提交 169574a2 编写于 作者: 鸿蒙内核源码分析's avatar 鸿蒙内核源码分析

如何跨CPU删除任务?注解一个任务是如何自杀和被他杀的.

搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
上级 dc86cef2
......@@ -67,12 +67,12 @@ extern "C" {
//LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段
LITE_OS_SEC_BSS LosProcessCB *g_runProcess[LOSCFG_KERNEL_CORE_NUM];// CPU内核个数,超过一个就实现了并行
LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL; // 进程池数组
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess;// 空闲状态下的进程链表, .个人觉得应该取名为 g_freeProcessList
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess;// 空闲状态下的进程链表, .个人觉得应该取名为 g_freeProcessList @note_thinking
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecyleList;// 需要回收的进程列表
LITE_OS_SEC_BSS UINT32 g_userInitProcess = OS_INVALID_VALUE;// 用户态的初始init进程,用户态下其他进程由它 fork
LITE_OS_SEC_BSS UINT32 g_kernelInitProcess = OS_INVALID_VALUE;// 内核态初始Kprocess进程,内核态下其他进程由它 fork
LITE_OS_SEC_BSS UINT32 g_kernelIdleProcess = OS_INVALID_VALUE;// 内核态idle进程,由Kprocess fork
LITE_OS_SEC_BSS UINT32 g_processMaxNum;// 进程最大数量
LITE_OS_SEC_BSS UINT32 g_processMaxNum;// 进程最大数量,默认64个
LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL;// 全局进程组,负责管理所有进程组
//将task从该进程的就绪队列中摘除,如果需要进程也从进程就绪队列中摘除
LITE_OS_SEC_TEXT_INIT VOID OsTaskSchedQueueDequeue(LosTaskCB *taskCB, UINT16 status)
......@@ -2003,7 +2003,7 @@ LITE_OS_SEC_TEXT VOID OsSetSigHandler(UINTPTR addr)
{
OsCurrProcessGet()->sigHandler = addr;
}
//获取进程的中断处理函数
//获取进程的信号处理函数
LITE_OS_SEC_TEXT UINTPTR OsGetSigHandler(VOID)
{
return OsCurrProcessGet()->sigHandler;
......
......@@ -569,7 +569,12 @@ STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal)
(VOID)syncSignal;
#endif
}
//同步信号等待
/******************************************
等待任务的同步信号,
A --发送syncSignal-- > B
B --回一个syncSignal-- > A
如此A就知道B此时还在
*******************************************/
LITE_OS_SEC_TEXT UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
{
#if (LOSCFG_KERNEL_SMP_TASK_SYNC == YES)
......@@ -1086,38 +1091,46 @@ LITE_OS_SEC_TEXT VOID OsRunTaskToDelete(LosTaskCB *taskCB)
* 3. Do the deletion in hard-irq
* then LOS_TaskDelete will directly return with 'ret' value.
*/
/****************************************************************
检查是否需要对正在运行的任务执行删除操作,如果需要删除,则返回TRUE。
如果满足以下情况,则返回FALSE:
1.如果启用了SMP,则跨CPU执行删除
2.禁用抢占时执行删除
3.在硬irq中删除
然后LOS_TaskDelete将直接返回ret值
****************************************************************/
STATIC BOOL OsRunTaskToDeleteCheckOnRun(LosTaskCB *taskCB, UINT32 *ret)
{
/* init default out return value */
*ret = LOS_OK;
#if (LOSCFG_KERNEL_SMP == YES)
/* ASYNCHRONIZED. No need to do task lock checking */
if (taskCB->currCpu != ArchCurrCpuid()) {
/* ASYNCHRONIZED. No need to do task lock checking *///异步操作,不需要进行任务锁检查
if (taskCB->currCpu != ArchCurrCpuid()) {//任务运行在其他CPU,跨核心执行删除
/*
* the task is running on another cpu.
* mask the target task with "kill" signal, and trigger mp schedule
* which might not be essential but the deletion could more in time.
*/
taskCB->signal = SIGNAL_KILL;
LOS_MpSchedule(taskCB->currCpu);
*ret = OsTaskSyncWait(taskCB);
taskCB->signal = SIGNAL_KILL; //贴上干掉标记
LOS_MpSchedule(taskCB->currCpu);//通知任务所属CPU发生调度
*ret = OsTaskSyncWait(taskCB); //同步等待可怜的任务被干掉
return FALSE;
}
#endif
if (!OsPreemptableInSched()) {
if (!OsPreemptableInSched()) {//如果任务正在运行且调度程序已锁定,则无法删除它
/* If the task is running and scheduler is locked then you can not delete it */
*ret = LOS_ERRNO_TSK_DELETE_LOCKED;
return FALSE;
}
if (OS_INT_ACTIVE) {
if (OS_INT_ACTIVE) {//硬中断进行中...会屏蔽掉所有信号,当然包括kill了
/*
* delete running task in interrupt.
* mask "kill" signal and later deletion will be handled.
*/
taskCB->signal = SIGNAL_KILL;
taskCB->signal = SIGNAL_KILL;//硬中断后将处理删除。
return FALSE;
}
......@@ -1594,13 +1607,17 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
/*
* Description : Process pending signals tagged by others cores
*///处理由其他CPU核标记为挂起信号
*/
/******************************************************
由其他CPU核触发阻塞进程的信号
函数由汇编代码调用 ..\arch\arm\arm\src\los_dispatch.S
******************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskProcSignal(VOID)
{
Percpu *percpu = NULL;
LosTaskCB *runTask = NULL;
UINT32 intSave, ret;
//私有且不可中断,无需保护。这个任务在其他CPU核看到它时总是在运行,所以它在执行代码的同时也可以继续接收信号
//私有且不可中断,无需保护。这个任务在其他CPU核看到它时总是在运行,所以它在执行代码的同时也可以继续接收信号
/*
* private and uninterruptable, no protection needed.
* while this task is always running when others cores see it,
......@@ -1611,28 +1628,28 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskProcSignal(VOID)
goto EXIT;
}
if (runTask->signal & SIGNAL_KILL) {
if (runTask->signal & SIGNAL_KILL) {//意思是其他cpu发起了要干掉你的信号
/*
* clear the signal, and do the task deletion. if the signaled task has been
* scheduled out, then this deletion will wait until next run.
*///清除信号,删除任务。如果发出信号的任务已出调度就绪队列,则此删除将等待下次运行
*///如果发出信号的任务已出调度就绪队列,则此删除将等待下次运行
SCHEDULER_LOCK(intSave);
runTask->signal = SIGNAL_NONE;
ret = OsTaskDeleteUnsafe(runTask, OS_PRO_EXIT_OK, intSave);
runTask->signal = SIGNAL_NONE;//清除信号,
ret = OsTaskDeleteUnsafe(runTask, OS_PRO_EXIT_OK, intSave);//任务的自杀行动,这可是正在运行的任务.
if (ret) {
PRINT_ERR("Task proc signal delete task(%u) failed err:0x%x\n", runTask->taskID, ret);
}
} else if (runTask->signal & SIGNAL_SUSPEND) {
runTask->signal &= ~SIGNAL_SUSPEND;
} else if (runTask->signal & SIGNAL_SUSPEND) {//意思是其他cpu发起了要挂起你的信号
runTask->signal &= ~SIGNAL_SUSPEND;//
/* suspend killed task may fail, ignore the result */
(VOID)LOS_TaskSuspend(runTask->taskID);
#if (LOSCFG_KERNEL_SMP == YES)
} else if (runTask->signal & SIGNAL_AFFI) {
} else if (runTask->signal & SIGNAL_AFFI) {//意思是下次调度其他cpu要媾和你
runTask->signal &= ~SIGNAL_AFFI;
/* pri-queue has updated, notify the target cpu */
LOS_MpSchedule((UINT32)runTask->cpuAffiMask);
LOS_MpSchedule((UINT32)runTask->cpuAffiMask);//任务队列已更新,通知目标cpu
#endif
}
......
......@@ -106,7 +106,7 @@ typedef struct ProcessCB {
#if (LOSCFG_KERNEL_SMP == YES)
UINT32 timerCpu; /**< CPU core number of this task is delayed or pended *///统计各线程被延期或阻塞的时间
#endif
UINTPTR sigHandler; /**< signal handler */ //信号处理函数
UINTPTR sigHandler; /**< signal handler */ //信号处理函数,处理如 SIGSYS 等信号
sigset_t sigShare; /**< signal share bit */ //信号共享位
#if (LOSCFG_KERNEL_LITEIPC == YES)
ProcIpcInfo ipcInfo; /**< memory pool for lite ipc */ //用于进程间通讯的 内存文件系统,设备装载点为 /dev/litepc
......
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_SIGNAL_H
#define _LOS_SIGNAL_H
#include <stddef.h>
#include <limits.h>
#include <sys/types.h>
#include <signal.h>
#include "los_event.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define LOS_BIT_SET(val, bit) ((val) = (val) | (1ULL << (UINT32)(bit)))
#define LOS_BIT_CLR(val, bit) ((val) = (val) & ~(1ULL << (UINT32)(bit)))
#define LOS_IS_BIT_SET(val, bit) (bool)((((val) >> (UINT32)(bit)) & 1ULL))
#define OS_SYSCALL_SET_CPSR(regs, cpsr) (*((unsigned long *)((UINTPTR)(regs) - 4)) = (cpsr))
#define OS_SYSCALL_SET_SR(regs, cpsr) (*((unsigned long *)((UINTPTR)(regs))) = (cpsr))
#define OS_SYSCALL_GET_CPSR(regs) (*((unsigned long *)((UINTPTR)(regs) - 4)))
#define SIG_STOP_VISIT 1
#define OS_KERNEL_KILL_PERMISSION 0U //内核级 kill 权限
#define OS_USER_KILL_PERMISSION 3U //用户级 kill 权限
#define OS_RETURN_IF(expr, errcode) \
if ((expr)) { \
return errcode; \
}
#define OS_RETURN_IF_VOID(expr) \
if ((expr)) { \
return; \
}
#define OS_GOTO_EXIT_IF(expr, errcode) \
if (expr) { \
ret = errcode; \
goto EXIT; \
}
#define OS_GOTO_EXIT_IF_ONLY(expr) \
if (expr) { \
goto EXIT; \
}
#define OS_RETURN_VOID_IF_NULL(pPara) \
if (NULL == (pPara)) { \
return; \
}
#define OS_RETURN_IF_NULL(pPara) \
if (NULL == (pPara)) { \
return (-EINVAL); \
}
#define OS_GOTO_EXIT_IF_NULL(pPara) \
if (NULL == (pPara)) { \
ret = -EINVAL; \
goto EXIT; \
}
typedef void (*sa_sighandler_t)(int);
typedef void (*sa_siginfoaction_t)(int, siginfo_t *, void *);
#define SIGNO2SET(s) ((sigset_t)1ULL << (s))
#define NULL_SIGNAL_SET ((sigset_t)0ULL) //设置成没有信号
#define FULL_SIGNAL_SET ((sigset_t)~0ULL) //设置成满格信号
static inline int GOOD_SIGNO(unsigned int sig)
{
return (sig < _NSIG) ? 1 : 0;
}
/********************************************************************
Musl官网 http://musl.libc.org/
musl是构建在Linux系统调用API之上的C标准库的实现,包括在基本语言标准POSIX中定义的接口,
以及广泛认可的扩展。musl是轻量级的,快速的,简单的,自由的.
********************************************************************/
#define MAX_SIG_ARRAY_IN_MUSL 128
typedef struct {
unsigned long sig[MAX_SIG_ARRAY_IN_MUSL / sizeof(unsigned long)];
} sigset_t_l;
typedef struct sigaction sigaction_t;
struct sigactq {
struct sigactq *flink; /* Forward link */
sigaction_t act; /* Sigaction data */
uint8_t signo; /* Signal associated with action */
};
typedef struct sigactq sigactq_t;
struct sq_entry_s {
struct sq_entry_s *flink;
};
typedef struct sq_entry_s sq_entry_t;
struct sigpendq {
struct sigpendq *flink; /* Forward link */
siginfo_t info; /* Signal information */
uint8_t type; /* (Used to manage allocations) */
};
typedef struct sigpendq sigpendq_t;
struct sq_queue_s {
sq_entry_t *head;
sq_entry_t *tail;
};
typedef struct sq_queue_s sq_queue_t;
#define TASK_IRQ_CONTEXT \
unsigned int R0; \
unsigned int R1; \
unsigned int R2; \
unsigned int R3; \
unsigned int R12; \
unsigned int USP; \
unsigned int ULR; \
unsigned int CPSR; \
unsigned int PC;
typedef struct {
TASK_IRQ_CONTEXT
} TaskIrqDataSize;
typedef struct {
TASK_IRQ_CONTEXT
unsigned int R7;
unsigned int count;
} sig_switch_context;
typedef struct {//信号控制块(描述符)
sigset_t sigFlag;
sigset_t sigPendFlag;
sigset_t sigprocmask; /* Signals that are blocked */ //信号屏蔽
sq_queue_t sigactionq;
LOS_DL_LIST waitList; //等待链表
sigset_t sigwaitmask; /* Waiting for pending signals */ //等待挂起的信号
siginfo_t sigunbinfo; /* Signal info when task unblocked */ //任务解除阻止时的信号信息
sig_switch_context context;
} sig_cb;
#define SIGEV_THREAD_ID 4
int sys_sigqueue(pid_t, int, const union sigval);
int sys_sigpending(sigset_t *);
int sys_rt_sigtimedwait(const sigset_t *mask, siginfo_t *si, const struct timespec *ts, size_t sigsetsize);
int sys_sigsuspend(const sigset_t *);
int OsKillLock(pid_t pid, int sig);
int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact);
int OsSigprocMask(int how, const sigset_t_l *set, sigset_t_l *oldset);
int OsPthreadKill(UINT32 tid, int signo);
int OsSigEmptySet(sigset_t *);
int OsSigAddSet(sigset_t *, int);
int OsSigIsMember(const sigset_t *, int);
void OsSaveSignalContext(unsigned int *sp);
void OsRestorSignalContext(unsigned int *sp);
int OsKill(pid_t pid, int sig, int permission);
int OsDispatch(pid_t pid, siginfo_t *info, int permission);
int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout);
int OsPause(void);
int OsSigPending(sigset_t *set);
int OsSigSuspend(const sigset_t *set);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_SIGNAL_H */
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_SIGNAL_H
#define _LOS_SIGNAL_H
#include <stddef.h>
#include <limits.h>
#include <sys/types.h>
#include <signal.h>
#include "los_event.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/********************************************
https://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html
信号本质:用于进程之间的异步通信
软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。在软件层次上是对中断机制的一种模拟,
在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是进程间通信机制中唯一
的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。
进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程
发生了某个事件。信号机制除了基本通知功能外,还可以传递附加信息。
信号量定义如下: 见于..\third_party\musl\arch\aarch64\bits\signal.h
#define SIGHUP 1 //终端挂起或者控制进程终止
#define SIGINT 2 //键盘中断(如break键被按下)
#define SIGQUIT 3 //键盘的退出键被按下
#define SIGILL 4 //非法指令
#define SIGTRAP 5 //跟踪陷阱(trace trap),启动进程,跟踪代码的执行
#define SIGABRT 6 //由abort(3)发出的退出指令
#define SIGIOT SIGABRT
#define SIGBUS 7 //总线错误
#define SIGFPE 8 //浮点异常
#define SIGKILL 9 //常用的命令 kill 9 123
#define SIGUSR1 10 //用户自定义信号1
#define SIGSEGV 11 //无效的内存引用, 段违例(segmentation violation),进程试图去访问其虚地址空间以外的位置
#define SIGUSR2 12 //用户自定义信号2
#define SIGPIPE 13 //向某个非读管道中写入数据
#define SIGALRM 14 //由alarm(2)发出的信号,默认行为为进程终止
#define SIGTERM 15 //软件终止(software termination)
#define SIGSTKFLT 16
#define SIGCHLD 17 //子进程结束信号
#define SIGCONT 18 //进程继续(曾被停止的进程)
#define SIGSTOP 19 //终止进程
#define SIGTSTP 20 //控制终端(tty)上 按下停止键
#define SIGTTIN 21 //后台进程企图从控制终端读
#define SIGTTOU 22 //后台进程企图从控制终端写
#define SIGURG 23
#define SIGXCPU 24
#define SIGXFSZ 25
#define SIGVTALRM 26
#define SIGPROF 27
#define SIGWINCH 28
#define SIGIO 29
#define SIGPOLL 29
#define SIGPWR 30 //电源故障
#define SIGSYS 31 //系统调用中参数错,如系统调用号非法
#define SIGUNUSED SIGSYS
#define _NSIG 65 //信号范围,不超过_NSIG
********************************************/
#define LOS_BIT_SET(val, bit) ((val) = (val) | (1ULL << (UINT32)(bit))) //按位设置
#define LOS_BIT_CLR(val, bit) ((val) = (val) & ~(1ULL << (UINT32)(bit))) //按位清除
#define LOS_IS_BIT_SET(val, bit) (bool)((((val) >> (UINT32)(bit)) & 1ULL)) //位是否设置为1
#define OS_SYSCALL_SET_CPSR(regs, cpsr) (*((unsigned long *)((UINTPTR)(regs) - 4)) = (cpsr))
#define OS_SYSCALL_SET_SR(regs, cpsr) (*((unsigned long *)((UINTPTR)(regs))) = (cpsr))
#define OS_SYSCALL_GET_CPSR(regs) (*((unsigned long *)((UINTPTR)(regs) - 4)))
#define SIG_STOP_VISIT 1
#define OS_KERNEL_KILL_PERMISSION 0U //内核级 kill 权限
#define OS_USER_KILL_PERMISSION 3U //用户级 kill 权限
#define OS_RETURN_IF(expr, errcode) \
if ((expr)) { \
return errcode; \
}
#define OS_RETURN_IF_VOID(expr) \
if ((expr)) { \
return; \
}
#define OS_GOTO_EXIT_IF(expr, errcode) \
if (expr) { \
ret = errcode; \
goto EXIT; \
}
#define OS_GOTO_EXIT_IF_ONLY(expr) \
if (expr) { \
goto EXIT; \
}
#define OS_RETURN_VOID_IF_NULL(pPara) \
if (NULL == (pPara)) { \
return; \
}
#define OS_RETURN_IF_NULL(pPara) \
if (NULL == (pPara)) { \
return (-EINVAL); \
}
#define OS_GOTO_EXIT_IF_NULL(pPara) \
if (NULL == (pPara)) { \
ret = -EINVAL; \
goto EXIT; \
}
typedef void (*sa_sighandler_t)(int);
typedef void (*sa_siginfoaction_t)(int, siginfo_t *, void *);
#define SIGNO2SET(s) ((sigset_t)1ULL << (s))
#define NULL_SIGNAL_SET ((sigset_t)0ULL) //设置成没有信号
#define FULL_SIGNAL_SET ((sigset_t)~0ULL) //设置成满格信号
//信号量是否有效
static inline int GOOD_SIGNO(unsigned int sig)
{
return (sig < _NSIG) ? 1 : 0;//
}
/********************************************************************
Musl官网 http://musl.libc.org/
musl是构建在Linux系统调用API之上的C标准库的实现,包括在基本语言标准POSIX中定义的接口,
以及广泛认可的扩展。musl是轻量级的,快速的,简单的,自由的.
********************************************************************/
#define MAX_SIG_ARRAY_IN_MUSL 128
typedef struct {
unsigned long sig[MAX_SIG_ARRAY_IN_MUSL / sizeof(unsigned long)];
} sigset_t_l;
typedef struct sigaction sigaction_t;
struct sigactq {
struct sigactq *flink; /* Forward link */
sigaction_t act; /* Sigaction data */
uint8_t signo; /* Signal associated with action */
};
typedef struct sigactq sigactq_t;
struct sq_entry_s {
struct sq_entry_s *flink;
};
typedef struct sq_entry_s sq_entry_t;
struct sigpendq {
struct sigpendq *flink; /* Forward link */
siginfo_t info; /* Signal information */
uint8_t type; /* (Used to manage allocations) */
};
typedef struct sigpendq sigpendq_t;
struct sq_queue_s {
sq_entry_t *head;
sq_entry_t *tail;
};
typedef struct sq_queue_s sq_queue_t;
#define TASK_IRQ_CONTEXT \
unsigned int R0; \
unsigned int R1; \
unsigned int R2; \
unsigned int R3; \
unsigned int R12; \
unsigned int USP; \
unsigned int ULR; \
unsigned int CPSR; \
unsigned int PC;
typedef struct {//任务中断上下文
TASK_IRQ_CONTEXT
} TaskIrqDataSize;
typedef struct {//信号切换上下文
TASK_IRQ_CONTEXT
unsigned int R7;
unsigned int count;
} sig_switch_context;
typedef struct {//信号控制块(描述符)
sigset_t sigFlag;
sigset_t sigPendFlag;
sigset_t sigprocmask; /* Signals that are blocked */ //进程屏蔽了哪些信号
sq_queue_t sigactionq; //信号捕捉队列
LOS_DL_LIST waitList; //等待链表,上面挂的可是等待信号到来的任务, 请查找 OsTaskWait(&sigcb->waitList, timeout, TRUE) 理解
sigset_t sigwaitmask; /* Waiting for pending signals */ //等待挂起的信号,意思就是位信号来了都要处理,比如 SIGKILL,SIGSTOP信号
siginfo_t sigunbinfo; /* Signal info when task unblocked */ //任务解除阻止时的信号信息
sig_switch_context context; //信号切换上下文,用于保存切换现场
} sig_cb;
#define SIGEV_THREAD_ID 4
int sys_sigqueue(pid_t, int, const union sigval);
int sys_sigpending(sigset_t *);
int sys_rt_sigtimedwait(const sigset_t *mask, siginfo_t *si, const struct timespec *ts, size_t sigsetsize);
int sys_sigsuspend(const sigset_t *);
int OsKillLock(pid_t pid, int sig);
int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact);
int OsSigprocMask(int how, const sigset_t_l *set, sigset_t_l *oldset);
int OsPthreadKill(UINT32 tid, int signo);
int OsSigEmptySet(sigset_t *);
int OsSigAddSet(sigset_t *, int);
int OsSigIsMember(const sigset_t *, int);
void OsSaveSignalContext(unsigned int *sp);
void OsRestorSignalContext(unsigned int *sp);
int OsKill(pid_t pid, int sig, int permission);
int OsDispatch(pid_t pid, siginfo_t *info, int permission);
int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout);
int OsPause(void);
int OsSigPending(sigset_t *set);
int OsSigSuspend(const sigset_t *set);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_SIGNAL_H */
......@@ -55,10 +55,10 @@ extern "C" {
*
* Task siginal types.
*/
#define SIGNAL_NONE 0U
#define SIGNAL_KILL (1U << 0)
#define SIGNAL_SUSPEND (1U << 1)
#define SIGNAL_AFFI (1U << 2)
#define SIGNAL_NONE 0U //无信号
#define SIGNAL_KILL (1U << 0) //干掉
#define SIGNAL_SUSPEND (1U << 1) //挂起
#define SIGNAL_AFFI (1U << 2) //CPU 亲和力,一个任务被切换后被同一个CPU再次执行,则亲和力高
/* scheduler lock */
extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
......@@ -317,8 +317,8 @@ typedef struct {
UINT32 priBitMap; /**< BitMap for recording the change of task priority, //任务在执行过程中优先级会经常变化,这个变量用来记录所有曾经变化
the priority can not be greater than 31 */ //过的优先级,例如 ..01001011 曾经有过 0,1,3,6 优先级
INT32 errorNo; /**< Error Num */
UINT32 signal; /**< Task signal */ //任务信号 注意这个信号和 下面的sig是完全不一样的两个东东。
sig_cb sig; //信号控制块,和上面的signal是两个东西,独立使用。鸿蒙这样放在一块会误导开发者!
UINT32 signal; /**< Task signal */ //任务信号类型,(SIGNAL_NONE,SIGNAL_KILL,SIGNAL_SUSPEND,SIGNAL_AFFI)
sig_cb sig; //信号控制块,这里用于进程间通讯的信号,类似于 linux singal模块
#if (LOSCFG_KERNEL_SMP == YES)
UINT16 currCpu; /**< CPU core number of this task is running on */ //正在运行此任务的CPU内核号
UINT16 lastCpu; /**< CPU core number of this task is running on last time */ //上次运行此任务的CPU内核号
......@@ -356,7 +356,7 @@ typedef struct {
LosTaskCB *newTask;
} LosTask;
struct ProcessSignalInfo {//进程信号信息
struct ProcessSignalInfo {//进程信号描述符
siginfo_t *sigInfo; /**< Signal to be dispatched */ //要发送的信号 例如 9 代表 kill process信号
LosTaskCB *defaultTcb; /**< Default TCB */ //默认task,指的是信号的发送方
LosTaskCB *unblockedTcb; /**< The signal unblock on this TCB*/ //解除阻塞这个task的信号
......@@ -364,7 +364,7 @@ struct ProcessSignalInfo {//进程信号信息
LosTaskCB *receivedTcb; /**< This TCB received the signal */ //指定task接收信号
};
typedef int (*ForEachTaskCB)(LosTaskCB *tcb, void *arg);//函数指针
typedef int (*ForEachTaskCB)(LosTaskCB *tcb, void *arg);//每个任务的回调函数,可用于进程被kill 9 时,通知所有任务善后处理
/**
* @ingroup los_task
......
此差异已折叠。
此差异已折叠。
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "stdio.h"
#include "stdlib.h"
#include "los_signal.h"
#include "los_printf.h"
#include "los_task_pri.h"
#include "los_process_pri.h"
#include "log.h"
#ifdef LOSCFG_SHELL
#include "shcmd.h"
#include "shell.h"
#endif
LITE_OS_SEC_TEXT_MINOR VOID OsPrintKillUsage(VOID)
{
PRINTK("\nkill: usage: kill [sigspec] [pid]\n");
}
// shell kill 命令用于发送特定信号给指定进程。kill [signo | -signo] [pid]
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdKill(INT32 argc, const CHAR **argv)
{
#define ARG_NUM 2
INT32 sigNo = 0;
INT32 pidNo = 0;
INT32 ret;
CHAR *endPtr = NULL;
if (argc == ARG_NUM) {
sigNo = strtoul(argv[0], &endPtr, 0);
if (*endPtr != 0) {
PRINTK("\nsigNo can't access %s.\n", argv[0]);
goto ERROR;
}
endPtr = NULL;
pidNo = strtoul(argv[1], &endPtr, 0);
if (*endPtr != 0) {
PRINTK("\npidNo can't access %s.\n", argv[1]);
goto ERROR;
}
ret = OsKill(pidNo, abs(sigNo), OS_USER_KILL_PERMISSION);// OS_USER_KILL_PERMISSION 干掉用户进程
HILOG_INFO(LOG_CORE, "Send signal(%d) to pidNo = %d!\n", abs(sigNo), pidNo);
if (ret == -1) {
HILOG_ERROR(LOG_CORE, "Kill fail ret = %d! Operation not permitted\n", ret);
goto ERROR;
}
if (ret < 0) {
PRINTK("\n Kill fail ret = %d! process not exist or sigNo is invalid\n", ret);
goto ERROR;
}
} else {
PRINTK("\nPara number errno!\n");
goto ERROR;
}
return 0;
ERROR:
OsPrintKillUsage();//失败时 打印 kill 的用法
return 0;
}
#ifdef LOSCFG_SHELL
SHELLCMD_ENTRY(kill_shellcmd, CMD_TYPE_EX, "kill", 2, (CmdCallBackFunc)OsShellCmdKill);//采用shell命令静态注册方式
#endif
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "stdio.h"
#include "stdlib.h"
#include "los_signal.h"
#include "los_printf.h"
#include "los_task_pri.h"
#include "los_process_pri.h"
#include "log.h"
#ifdef LOSCFG_SHELL
#include "shcmd.h"
#include "shell.h"
#endif
LITE_OS_SEC_TEXT_MINOR VOID OsPrintKillUsage(VOID)
{
PRINTK("\nkill: usage: kill [sigspec] [pid]\n");
}
/*********************************************
命令功能
命令用于发送特定信号给指定进程。
命令格式
kill [signo | -signo] [pid]
参数 参数说明 取值范围
signo 信号ID [1,30]
pid 进程ID [1,MAX_INT]
须知: signo有效范围为[0,64],建议取值范围为[1,30],其余为保留内容。
使用指南
必须指定发送的信号编号及进程号。
进程编号取值范围根据系统配置变化,例如系统最大支持pid为256,则取值范围缩小为[1-256]。
*********************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdKill(INT32 argc, const CHAR **argv)
{
#define ARG_NUM 2
INT32 sigNo = 0;
INT32 pidNo = 0;
INT32 ret;
CHAR *endPtr = NULL;
if (argc == ARG_NUM) {
sigNo = strtoul(argv[0], &endPtr, 0);
if (*endPtr != 0) {
PRINTK("\nsigNo can't access %s.\n", argv[0]);
goto ERROR;
}
endPtr = NULL;
pidNo = strtoul(argv[1], &endPtr, 0);
if (*endPtr != 0) {
PRINTK("\npidNo can't access %s.\n", argv[1]);
goto ERROR;
}
ret = OsKill(pidNo, abs(sigNo), OS_USER_KILL_PERMISSION);// OS_USER_KILL_PERMISSION 干掉用户进程
HILOG_INFO(LOG_CORE, "Send signal(%d) to pidNo = %d!\n", abs(sigNo), pidNo);
if (ret == -1) {
HILOG_ERROR(LOG_CORE, "Kill fail ret = %d! Operation not permitted\n", ret);
goto ERROR;
}
if (ret < 0) {
PRINTK("\n Kill fail ret = %d! process not exist or sigNo is invalid\n", ret);
goto ERROR;
}
} else {
PRINTK("\nPara number errno!\n");
goto ERROR;
}
return 0;
ERROR:
OsPrintKillUsage();//失败时 打印 kill 的用法
return 0;
}
#ifdef LOSCFG_SHELL
SHELLCMD_ENTRY(kill_shellcmd, CMD_TYPE_EX, "kill", 2, (CmdCallBackFunc)OsShellCmdKill);//采用shell命令静态注册方式
#endif
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CAPABILITY_TYPE_H
#define CAPABILITY_TYPE_H
// posix capabilities //posix 接口能力范围
#define CAP_CHOWN 0 //修改拥有者
#define CAP_DAC_EXECUTE 1 //
#define CAP_DAC_WRITE 2
#define CAP_DAC_READ_SEARCH 3
#define CAP_FOWNER 4
#define CAP_KILL 5 //kill
#define CAP_SETGID 6 //设置用户组ID
#define CAP_SETUID 7 //设置用户ID
// socket capabilities //网络能力
#define CAP_NET_BIND_SERVICE 8 //绑定端口
#define CAP_NET_BROADCAST 9 //网络广播
#define CAP_NET_ADMIN 10 //网络管理
#define CAP_NET_RAW 11 //网络读写访问
// fs capabilities //文件系统能力
#define CAP_FS_MOUNT 12 //挂载
#define CAP_FS_FORMAT 13 //格式化
// process capabilities //进程调度能力,
#define CAP_SCHED_SETPRIORITY 14 //设置调度优先级
// time capabilities //时间能力
#define CAP_SET_TIMEOFDAY 15 //重置系统时间
#define CAP_CLOCK_SETTIME 16 //设置时钟
// process capabilities //进程能力
#define CAP_CAPSET 17 //设置进程能力的能力
// reboot capability //重新启动功能
#define CAP_REBOOT 18 //重启系统
// self deined privileged syscalls //自定义特权系统调用
#define CAP_SHELL_EXEC 19 //自定义 shell 命令
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CAPABILITY_TYPE_H
#define CAPABILITY_TYPE_H
// posix capabilities //posix 接口能力范围
#define CAP_CHOWN 0 //修改拥有者
#define CAP_DAC_EXECUTE 1 //
#define CAP_DAC_WRITE 2
#define CAP_DAC_READ_SEARCH 3
#define CAP_FOWNER 4
#define CAP_KILL 5 //杀死(进程,线程 ==)能力
#define CAP_SETGID 6 //设置用户组ID
#define CAP_SETUID 7 //设置用户ID
// socket capabilities //网络能力
#define CAP_NET_BIND_SERVICE 8 //绑定端口
#define CAP_NET_BROADCAST 9 //网络广播
#define CAP_NET_ADMIN 10 //网络管理
#define CAP_NET_RAW 11 //网络读写访问
// fs capabilities //文件系统能力
#define CAP_FS_MOUNT 12 //挂载
#define CAP_FS_FORMAT 13 //格式化
// process capabilities //进程调度能力,
#define CAP_SCHED_SETPRIORITY 14 //设置调度优先级
// time capabilities //时间能力
#define CAP_SET_TIMEOFDAY 15 //重置系统时间
#define CAP_CLOCK_SETTIME 16 //设置时钟
// process capabilities //进程能力
#define CAP_CAPSET 17 //设置进程能力的能力
// reboot capability //重新启动功能
#define CAP_REBOOT 18 //重启系统
// self deined privileged syscalls //自定义特权系统调用
#define CAP_SHELL_EXEC 19 //自定义 shell 命令
#endif
\ No newline at end of file
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mqueue.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "time_posix.h"
#include "user_copy.h"
#include "los_signal.h"
#include "los_strncpy_from_user.h"
//创建和打开一个posix消息队列
mqd_t SysMqOpen(const char *mqName, int openFlag, mode_t mode, struct mq_attr *attr)
{
mqd_t ret;
int retValue;
char kMqName[PATH_MAX + 1] = { 0 };
retValue = LOS_StrncpyFromUser(kMqName, mqName, PATH_MAX);
if (retValue < 0) {
return retValue;
}
ret = mq_open(kMqName, openFlag, mode, attr);
if (ret == -1) {
return (mqd_t)-get_errno();
}
return ret;
}
//关闭一个消息队列
int SysMqClose(mqd_t personal)
{
int ret;
ret = mq_close(personal);
if (ret < 0) {
return -get_errno();
}
return ret;
}
int SysMqGetSetAttr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old)
{
int ret;
struct mq_attr knew, kold;
if (new != NULL) {
ret = LOS_ArchCopyFromUser(&knew, new, sizeof(struct mq_attr));
if (ret != 0) {
return -EFAULT;
}
}
ret = mq_getsetattr(mqd, new ? &knew : NULL, old ? &kold : NULL);
if (ret < 0) {
return -get_errno();
}
if (old != NULL) {
ret = LOS_ArchCopyToUser(old, &kold, sizeof(struct mq_attr));
if (ret != 0) {
return -EFAULT;
}
}
return ret;
}
int SysMqUnlink(const char *mqName)
{
int ret;
int retValue;
char kMqName[PATH_MAX + 1] = { 0 };
retValue = LOS_StrncpyFromUser(kMqName, mqName, PATH_MAX);
if (retValue < 0) {
return retValue;
}
ret = mq_unlink(kMqName);
if (ret < 0) {
return -get_errno();
}
return ret;
}
int SysMqTimedSend(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio,
const struct timespec *absTimeout)
{
int ret;
struct timespec timeout;
char *msgIntr = NULL;
if (absTimeout != NULL) {
ret = LOS_ArchCopyFromUser(&timeout, absTimeout, sizeof(struct timespec));
if (ret != 0) {
return -EFAULT;
}
}
if (msgLen == 0) {
return -EINVAL;
}
msgIntr = (char *)malloc(msgLen);
if (msgIntr == NULL) {
return -ENOMEM;
}
ret = LOS_ArchCopyFromUser(msgIntr, msg, msgLen);
if (ret != 0) {
free(msgIntr);
return -EFAULT;
}
ret = mq_timedsend(personal, msgIntr, msgLen, msgPrio, absTimeout ? &timeout : NULL);
free(msgIntr);
if (ret < 0) {
return -get_errno();
}
return ret;
}
ssize_t SysMqTimedReceive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio,
const struct timespec *absTimeout)
{
int ret, receiveLen;
struct timespec timeout;
char *msgIntr = NULL;
unsigned int kMsgPrio;
if (absTimeout != NULL) {
ret = LOS_ArchCopyFromUser(&timeout, absTimeout, sizeof(struct timespec));
if (ret != 0) {
return -EFAULT;
}
}
if (msgLen == 0) {
return -EINVAL;
}
msgIntr = (char *)malloc(msgLen);
if (msgIntr == NULL) {
return -ENOMEM;
}
receiveLen = mq_timedreceive(personal, msgIntr, msgLen, &kMsgPrio, absTimeout ? &timeout : NULL);
if (receiveLen < 0) {
free(msgIntr);
return -get_errno();
}
if (msgPrio != NULL) {
ret = LOS_ArchCopyToUser(msgPrio, &kMsgPrio, sizeof(unsigned int));
if (ret != 0) {
free(msgIntr);
return -EFAULT;
}
}
ret = LOS_ArchCopyToUser(msg, msgIntr, receiveLen);
free(msgIntr);
if (ret != 0) {
return -EFAULT;
}
return receiveLen;
}
int SysSigAction(int sig, const sigaction_t *restrict sa, sigaction_t *restrict old, size_t sigsetsize)
{
return OsSigAction(sig, sa, old);
}
int SysSigprocMask(int how, const sigset_t_l *restrict setl, sigset_t_l *restrict oldl, size_t sigsetsize)
{
/* Let nxsig_procmask do all of the work */
return OsSigprocMask(how, setl, oldl);
}
int SysKill(pid_t pid, int sig)
{
return OsKillLock(pid, sig);
}
int SysPthreadKill(pid_t pid, int sig)
{
return OsPthreadKill(pid, sig);
}
int SysSigTimedWait(const sigset_t_l *setl, siginfo_t *info, const struct timespec *timeout, size_t sigsetsize)
{
sigset_t set;
unsigned int tick;
int retVal, ret;
siginfo_t infoIntr;
struct timespec timeoutIntr;
retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
if (retVal != 0) {
return -EFAULT;
}
if (timeout == NULL) {
tick = LOS_WAIT_FOREVER;
} else {
retVal = LOS_ArchCopyFromUser(&timeoutIntr, timeout, sizeof(struct timespec));
if (retVal != 0) {
return -EFAULT;
}
if (!ValidTimeSpec(&timeoutIntr)) {
return -EINVAL;
}
tick = OsTimeSpec2Tick(&timeoutIntr);
}
ret = OsSigTimedWait(&set, &infoIntr, tick);
if (ret < 0) {
return ret;
}
if (info != NULL) {
retVal = LOS_ArchCopyToUser(info, &infoIntr, sizeof(siginfo_t));
if (retVal != 0) {
return -EFAULT;
}
}
return (ret == 0 ? infoIntr.si_signo : ret);
}
int SysPause(void)
{
return OsPause();
}
int SysSigPending(sigset_t_l *setl)
{
sigset_t set;
int ret;
ret = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
if (ret != 0) {
return -EFAULT;
}
ret = OsSigPending(&set);
if (ret != LOS_OK) {
return ret;
}
ret = LOS_ArchCopyToUser(&(setl->sig[0]), &set, sizeof(sigset_t));
if (ret != LOS_OK) {
return -EFAULT;
}
return ret;
}
int SysSigSuspend(sigset_t_l *setl)
{
sigset_t set;
int retVal;
retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
if (retVal != 0) {
return -EFAULT;
}
return OsSigSuspend(&set);
}
int SysMkFifo(const char *pathName, mode_t mode)
{
int retValue;
char kPathName[PATH_MAX + 1] = { 0 };
retValue = LOS_StrncpyFromUser(kPathName, pathName, PATH_MAX);
if (retValue < 0) {
return retValue;
}
return mkfifo(kPathName, mode);
}
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mqueue.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "time_posix.h"
#include "user_copy.h"
#include "los_signal.h"
#include "los_strncpy_from_user.h"
//创建和打开一个posix消息队列
mqd_t SysMqOpen(const char *mqName, int openFlag, mode_t mode, struct mq_attr *attr)
{
mqd_t ret;
int retValue;
char kMqName[PATH_MAX + 1] = { 0 };
retValue = LOS_StrncpyFromUser(kMqName, mqName, PATH_MAX);
if (retValue < 0) {
return retValue;
}
ret = mq_open(kMqName, openFlag, mode, attr);
if (ret == -1) {
return (mqd_t)-get_errno();
}
return ret;
}
//关闭一个消息队列
int SysMqClose(mqd_t personal)
{
int ret;
ret = mq_close(personal);
if (ret < 0) {
return -get_errno();
}
return ret;
}
int SysMqGetSetAttr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old)
{
int ret;
struct mq_attr knew, kold;
if (new != NULL) {
ret = LOS_ArchCopyFromUser(&knew, new, sizeof(struct mq_attr));
if (ret != 0) {
return -EFAULT;
}
}
ret = mq_getsetattr(mqd, new ? &knew : NULL, old ? &kold : NULL);
if (ret < 0) {
return -get_errno();
}
if (old != NULL) {
ret = LOS_ArchCopyToUser(old, &kold, sizeof(struct mq_attr));
if (ret != 0) {
return -EFAULT;
}
}
return ret;
}
int SysMqUnlink(const char *mqName)
{
int ret;
int retValue;
char kMqName[PATH_MAX + 1] = { 0 };
retValue = LOS_StrncpyFromUser(kMqName, mqName, PATH_MAX);
if (retValue < 0) {
return retValue;
}
ret = mq_unlink(kMqName);
if (ret < 0) {
return -get_errno();
}
return ret;
}
int SysMqTimedSend(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio,
const struct timespec *absTimeout)
{
int ret;
struct timespec timeout;
char *msgIntr = NULL;
if (absTimeout != NULL) {
ret = LOS_ArchCopyFromUser(&timeout, absTimeout, sizeof(struct timespec));
if (ret != 0) {
return -EFAULT;
}
}
if (msgLen == 0) {
return -EINVAL;
}
msgIntr = (char *)malloc(msgLen);
if (msgIntr == NULL) {
return -ENOMEM;
}
ret = LOS_ArchCopyFromUser(msgIntr, msg, msgLen);
if (ret != 0) {
free(msgIntr);
return -EFAULT;
}
ret = mq_timedsend(personal, msgIntr, msgLen, msgPrio, absTimeout ? &timeout : NULL);
free(msgIntr);
if (ret < 0) {
return -get_errno();
}
return ret;
}
ssize_t SysMqTimedReceive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio,
const struct timespec *absTimeout)
{
int ret, receiveLen;
struct timespec timeout;
char *msgIntr = NULL;
unsigned int kMsgPrio;
if (absTimeout != NULL) {
ret = LOS_ArchCopyFromUser(&timeout, absTimeout, sizeof(struct timespec));
if (ret != 0) {
return -EFAULT;
}
}
if (msgLen == 0) {
return -EINVAL;
}
msgIntr = (char *)malloc(msgLen);
if (msgIntr == NULL) {
return -ENOMEM;
}
receiveLen = mq_timedreceive(personal, msgIntr, msgLen, &kMsgPrio, absTimeout ? &timeout : NULL);
if (receiveLen < 0) {
free(msgIntr);
return -get_errno();
}
if (msgPrio != NULL) {
ret = LOS_ArchCopyToUser(msgPrio, &kMsgPrio, sizeof(unsigned int));
if (ret != 0) {
free(msgIntr);
return -EFAULT;
}
}
ret = LOS_ArchCopyToUser(msg, msgIntr, receiveLen);
free(msgIntr);
if (ret != 0) {
return -EFAULT;
}
return receiveLen;
}
//系统调用之捕捉信号,鸿蒙内核只捕捉了SIGSYS 信号
int SysSigAction(int sig, const sigaction_t *restrict sa, sigaction_t *restrict old, size_t sigsetsize)
{
return OsSigAction(sig, sa, old);
}
/*****************************************************
系统调用之进程信号屏蔽,
什么意思?简单说就是 一个信号来了进程要不要处理,阻塞就是不处理,注意不能阻塞SIGKILL和SIGSTOP信号,必须要处理.
how
SIG_BLOCK 加入信号到进程屏蔽。set包含了希望阻塞的附加信号
SIG_UNBLOCK 从进程屏蔽里将信号删除。set包含了希望解除阻塞的信号
SIG_SETMASK 将set的值设定为新的进程屏蔽
*****************************************************/
int SysSigprocMask(int how, const sigset_t_l *restrict setl, sigset_t_l *restrict oldl, size_t sigsetsize)
{
/* Let nxsig_procmask do all of the work */
return OsSigprocMask(how, setl, oldl);
}
//系统调用之干掉进程
int SysKill(pid_t pid, int sig)
{
return OsKillLock(pid, sig);
}
//系统调用之干掉线程
int SysPthreadKill(pid_t pid, int sig)
{
return OsPthreadKill(pid, sig);
}
int SysSigTimedWait(const sigset_t_l *setl, siginfo_t *info, const struct timespec *timeout, size_t sigsetsize)
{
sigset_t set;
unsigned int tick;
int retVal, ret;
siginfo_t infoIntr;
struct timespec timeoutIntr;
retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
if (retVal != 0) {
return -EFAULT;
}
if (timeout == NULL) {
tick = LOS_WAIT_FOREVER;
} else {
retVal = LOS_ArchCopyFromUser(&timeoutIntr, timeout, sizeof(struct timespec));
if (retVal != 0) {
return -EFAULT;
}
if (!ValidTimeSpec(&timeoutIntr)) {
return -EINVAL;
}
tick = OsTimeSpec2Tick(&timeoutIntr);
}
ret = OsSigTimedWait(&set, &infoIntr, tick);
if (ret < 0) {
return ret;
}
if (info != NULL) {
retVal = LOS_ArchCopyToUser(info, &infoIntr, sizeof(siginfo_t));
if (retVal != 0) {
return -EFAULT;
}
}
return (ret == 0 ? infoIntr.si_signo : ret);
}
int SysPause(void)
{
return OsPause();
}
int SysSigPending(sigset_t_l *setl)
{
sigset_t set;
int ret;
ret = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
if (ret != 0) {
return -EFAULT;
}
ret = OsSigPending(&set);
if (ret != LOS_OK) {
return ret;
}
ret = LOS_ArchCopyToUser(&(setl->sig[0]), &set, sizeof(sigset_t));
if (ret != LOS_OK) {
return -EFAULT;
}
return ret;
}
int SysSigSuspend(sigset_t_l *setl)
{
sigset_t set;
int retVal;
retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
if (retVal != 0) {
return -EFAULT;
}
return OsSigSuspend(&set);
}
int SysMkFifo(const char *pathName, mode_t mode)
{
int retValue;
char kPathName[PATH_MAX + 1] = { 0 };
retValue = LOS_StrncpyFromUser(kPathName, pathName, PATH_MAX);
if (retValue < 0) {
return retValue;
}
return mkfifo(kPathName, mode);
}
git add -A
git commit -m '完善对进程/任务注解
git commit -m '如何跨CPU删除任务?注解一个任务是如何自杀和被他杀的.
搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册