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

1.注解系统调用是如何发生的 2.完善对消息队列的注解

搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
上级 169574a2
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -570,7 +570,7 @@ STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal)
#endif
}
/******************************************
等待任务的同步信号,
等待任务的同步信号,
A --发送syncSignal-- > B
B --回一个syncSignal-- > A
如此A就知道B此时还在
......@@ -587,7 +587,7 @@ LITE_OS_SEC_TEXT UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
* triggered right at the timeout has reached, we set the timeout as double
* of the gc peroid.
*/
if (LOS_SemPend(taskCB->syncSignal, OS_MP_GC_PERIOD * 2) != LOS_OK) {//发送同步信号
if (LOS_SemPend(taskCB->syncSignal, OS_MP_GC_PERIOD * 2) != LOS_OK) {//发送同步信号
ret = LOS_ERRNO_TSK_MP_SYNC_FAILED;
}
......@@ -1364,7 +1364,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio)
* taskStatus --- task status
* timeOut --- Expiry time
* Return : LOS_OK on success or LOS_NOK on failure
*///任务等待,将当前任务挂到参数 list上
*/ //任务等待,将当前任务挂到参数 list上
UINT32 OsTaskWait(LOS_DL_LIST *list, UINT32 timeout, BOOL needSched)
{
LosTaskCB *runTask = NULL;
......@@ -1381,7 +1381,7 @@ UINT32 OsTaskWait(LOS_DL_LIST *list, UINT32 timeout, BOOL needSched)
}
if (needSched == TRUE) {//是否需要调度
OsSchedResched();//申请调度,里面直接切换了任务上下文,此次任务不再往下执行了.
OsSchedResched();//申请调度,里面直接切换了任务上下文,至此任务不再往下执行了.
if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) {//这条语句是被调度再次选中时执行的,和上面的语句可能隔了很长时间,所以很可能已经超时了
runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT;//如果任务有timeout的标签,那么就去掉那个标签
return LOS_ERRNO_TSK_TIMEOUT;
......
/*
* 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_QUEUE_PRI_H
#define _LOS_QUEUE_PRI_H
#include "los_queue.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
typedef enum {
OS_QUEUE_READ = 0, //读队列
OS_QUEUE_WRITE = 1, //写队列
OS_QUEUE_N_RW = 2
} QueueReadWrite;
typedef enum {
OS_QUEUE_HEAD = 0, //队列头部标识
OS_QUEUE_TAIL = 1 //队列尾部标识
} QueueHeadTail;
#define OS_QUEUE_OPERATE_TYPE(ReadOrWrite, HeadOrTail) (((UINT32)(HeadOrTail) << 1) | (ReadOrWrite))
#define OS_QUEUE_READ_WRITE_GET(type) ((type) & 0x01U)
#define OS_QUEUE_READ_HEAD (OS_QUEUE_READ | (OS_QUEUE_HEAD << 1))
#define OS_QUEUE_READ_TAIL (OS_QUEUE_READ | (OS_QUEUE_TAIL << 1))
#define OS_QUEUE_WRITE_HEAD (OS_QUEUE_WRITE | (OS_QUEUE_HEAD << 1))
#define OS_QUEUE_WRITE_TAIL (OS_QUEUE_WRITE | (OS_QUEUE_TAIL << 1))
#define OS_QUEUE_OPERATE_GET(type) ((type) & 0x03U)
#define OS_QUEUE_IS_READ(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_READ)
#define OS_QUEUE_IS_WRITE(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_WRITE)
/**
* @ingroup los_queue
* Queue information block structure
*/
typedef struct {
UINT8 *queueHandle; /**< Pointer to a queue handle */ //指向队列句柄的指针
UINT16 queueState; /**< Queue state */ //队列状态
UINT16 queueLen; /**< Queue length */ //队列长度
UINT16 queueSize; /**< Node size */ //队列大小
UINT32 queueID; /**< queueID */ //队列ID
UINT16 queueHead; /**< Node head */ //队列头部节点
UINT16 queueTail; /**< Node tail */ //队列尾部节点
UINT16 readWriteableCnt[OS_QUEUE_N_RW]; /**< Count of readable or writable resources, 0:readable, 1:writable */
LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */
LOS_DL_LIST memList; /**< Pointer to the memory linked list */ //@note_why 这里尚未搞明白是啥意思 ,是共享内存吗?
} LosQueueCB;//读写队列分离
/* queue state */
/**
* @ingroup los_queue
* Message queue state: not in use.
*/
#define OS_QUEUE_UNUSED 0
/**
* @ingroup los_queue
* Message queue state: used.
*/
#define OS_QUEUE_INUSED 1
/**
* @ingroup los_queue
* Not in use.
*/
#define OS_QUEUE_WAIT_FOR_POOL 1
/**
* @ingroup los_queue
* Normal message queue.
*/
#define OS_QUEUE_NORMAL 0
/**
* @ingroup los_queue
* Queue information control block
*/
extern LosQueueCB *g_allQueue;
/**
* @ingroup los_queue
* COUNT | INDEX split bit
*/
#define QUEUE_SPLIT_BIT 16
/**
* @ingroup los_queue
* Set the queue id
*/
#define SET_QUEUE_ID(count, queueID) (((count) << QUEUE_SPLIT_BIT) | (queueID))
/**
* @ingroup los_queue
* get the queue index
*/
#define GET_QUEUE_INDEX(queueID) ((queueID) & ((1U << QUEUE_SPLIT_BIT) - 1))
/**
* @ingroup los_queue
* get the queue count
*/
#define GET_QUEUE_COUNT(queueID) ((queueID) >> QUEUE_SPLIT_BIT)
/**
* @ingroup los_queue
* Obtain a handle of the queue that has a specified ID.
*
*/
#define GET_QUEUE_HANDLE(queueID) (((LosQueueCB *)g_allQueue) + GET_QUEUE_INDEX(queueID))
/**
* @ingroup los_queue
* Obtain the head node in a queue doubly linked list.
*/
#define GET_QUEUE_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosQueueCB, readWriteList[OS_QUEUE_WRITE])
/**
* @ingroup los_queue
* @brief Alloc a stationary memory for a mail.
*
* @par Description:
* This API is used to alloc a stationary memory for a mail according to queueID.
* @attention
* <ul>
* <li>Do not alloc memory in unblocking modes such as interrupt.</li>
* <li>This API cannot be called before the Huawei LiteOS is initialized.</li>
* <li>The argument timeout is a relative time.</li>
* </ul>
*
* @param queueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT].
* @param mailPool [IN] The memory poll that stores the mail.
* @param timeout [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER].
*
* @retval #NULL The memory allocation is failed.
* @retval #pMem The address of alloc memory.
* @par Dependency:
* <ul><li>los_queue_pri.h: the header file that contains the API declaration.</li></ul>
* @see OsQueueMailFree
*/
extern VOID *OsQueueMailAlloc(UINT32 queueID, VOID *mailPool, UINT32 timeout);
/**
* @ingroup los_queue
* @brief Free a stationary memory of a mail.
*
* @par Description:
* This API is used to free a stationary memory for a mail according to queueID.
* @attention
* <ul>
* <li>This API cannot be called before the Huawei LiteOS is initialized.</li>
* </ul>
*
* @param queueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT].
* @param mailPool [IN] The mail memory poll address.
* @param mailMem [IN] The mail memory block address.
*
* @retval #LOS_OK 0x00000000: The memory free successfully.
* @retval #OS_ERRNO_QUEUE_MAIL_HANDLE_INVALID 0x02000619: The handle of the queue passed-in when the memory
* for the queue is being freed is invalid.
* @retval #OS_ERRNO_QUEUE_MAIL_PTR_INVALID 0x0200061a: The pointer to the memory to be freed is null.
* @retval #OS_ERRNO_QUEUE_MAIL_FREE_ERROR 0x0200061b: The memory for the queue fails to be freed.
* @par Dependency:
* <ul><li>los_queue_pri.h: the header file that contains the API declaration.</li></ul>
* @see OsQueueMailAlloc
*/
extern UINT32 OsQueueMailFree(UINT32 queueID, VOID *mailPool, VOID *mailMem);
extern UINT32 OsQueueInit(VOID);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_QUEUE_PRI_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_QUEUE_PRI_H
#define _LOS_QUEUE_PRI_H
#include "los_queue.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
typedef enum {
OS_QUEUE_READ = 0, //读队列
OS_QUEUE_WRITE = 1, //写队列
OS_QUEUE_N_RW = 2
} QueueReadWrite;
typedef enum {
OS_QUEUE_HEAD = 0, //队列头部标识
OS_QUEUE_TAIL = 1 //队列尾部标识
} QueueHeadTail;
#define OS_QUEUE_OPERATE_TYPE(ReadOrWrite, HeadOrTail) (((UINT32)(HeadOrTail) << 1) | (ReadOrWrite))
#define OS_QUEUE_READ_WRITE_GET(type) ((type) & 0x01U)
#define OS_QUEUE_READ_HEAD (OS_QUEUE_READ | (OS_QUEUE_HEAD << 1))
#define OS_QUEUE_READ_TAIL (OS_QUEUE_READ | (OS_QUEUE_TAIL << 1))
#define OS_QUEUE_WRITE_HEAD (OS_QUEUE_WRITE | (OS_QUEUE_HEAD << 1))
#define OS_QUEUE_WRITE_TAIL (OS_QUEUE_WRITE | (OS_QUEUE_TAIL << 1))
#define OS_QUEUE_OPERATE_GET(type) ((type) & 0x03U)
#define OS_QUEUE_IS_READ(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_READ)
#define OS_QUEUE_IS_WRITE(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_WRITE)
/**
* @ingroup los_queue
* Queue information block structure
*/
typedef struct {
UINT8 *queueHandle; /**< Pointer to a queue handle */ //指向队列句柄的指针
UINT16 queueState; /**< Queue state */ //队列状态
UINT16 queueLen; /**< Queue length */ //队列中消息总数的上限值,由创建时确定,不再改变
UINT16 queueSize; /**< Node size */ //消息节点大小,由创建时确定,不再改变,即定义了每个消息长度的上限.
UINT32 queueID; /**< queueID */ //队列ID
UINT16 queueHead; /**< Node head */ //消息头节点位置(数组下标)
UINT16 queueTail; /**< Node tail */ //消息尾节点位置(数组下标)
UINT16 readWriteableCnt[OS_QUEUE_N_RW]; /**< Count of readable or writable resources, 0:readable, 1:writable */
//队列中可写或可读消息数,0表示可读,1表示可写
LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */
//挂的都是等待读/写消息的任务链表,0表示读消息的链表,1表示写消息的任务链表
LOS_DL_LIST memList; /**< Pointer to the memory linked list */ //@note_why 这里尚未搞明白是啥意思 ,是共享内存吗?
} LosQueueCB;//读写队列分离
/* queue state */
/**
* @ingroup los_queue
* Message queue state: not in use.
*/
#define OS_QUEUE_UNUSED 0 //队列没有使用
/**
* @ingroup los_queue
* Message queue state: used.
*/
#define OS_QUEUE_INUSED 1 //队列被使用
/**
* @ingroup los_queue
* Not in use.
*/
#define OS_QUEUE_WAIT_FOR_POOL 1
/**
* @ingroup los_queue
* Normal message queue.
*/
#define OS_QUEUE_NORMAL 0
/**
* @ingroup los_queue
* Queue information control block
*/
extern LosQueueCB *g_allQueue;
/**
* @ingroup los_queue
* COUNT | INDEX split bit
*/
#define QUEUE_SPLIT_BIT 16
/**
* @ingroup los_queue
* Set the queue id
*/
#define SET_QUEUE_ID(count, queueID) (((count) << QUEUE_SPLIT_BIT) | (queueID))
/**
* @ingroup los_queue
* get the queue index
*/
#define GET_QUEUE_INDEX(queueID) ((queueID) & ((1U << QUEUE_SPLIT_BIT) - 1))
/**
* @ingroup los_queue
* get the queue count
*/
#define GET_QUEUE_COUNT(queueID) ((queueID) >> QUEUE_SPLIT_BIT)
/**
* @ingroup los_queue
* Obtain a handle of the queue that has a specified ID.
*
*/
#define GET_QUEUE_HANDLE(queueID) (((LosQueueCB *)g_allQueue) + GET_QUEUE_INDEX(queueID))
/**
* @ingroup los_queue
* Obtain the head node in a queue doubly linked list.
*/
#define GET_QUEUE_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosQueueCB, readWriteList[OS_QUEUE_WRITE])
/**
* @ingroup los_queue
* @brief Alloc a stationary memory for a mail.
*
* @par Description:
* This API is used to alloc a stationary memory for a mail according to queueID.
* @attention
* <ul>
* <li>Do not alloc memory in unblocking modes such as interrupt.</li>
* <li>This API cannot be called before the Huawei LiteOS is initialized.</li>
* <li>The argument timeout is a relative time.</li>
* </ul>
*
* @param queueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT].
* @param mailPool [IN] The memory poll that stores the mail.
* @param timeout [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER].
*
* @retval #NULL The memory allocation is failed.
* @retval #pMem The address of alloc memory.
* @par Dependency:
* <ul><li>los_queue_pri.h: the header file that contains the API declaration.</li></ul>
* @see OsQueueMailFree
*/
extern VOID *OsQueueMailAlloc(UINT32 queueID, VOID *mailPool, UINT32 timeout);
/**
* @ingroup los_queue
* @brief Free a stationary memory of a mail.
*
* @par Description:
* This API is used to free a stationary memory for a mail according to queueID.
* @attention
* <ul>
* <li>This API cannot be called before the Huawei LiteOS is initialized.</li>
* </ul>
*
* @param queueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT].
* @param mailPool [IN] The mail memory poll address.
* @param mailMem [IN] The mail memory block address.
*
* @retval #LOS_OK 0x00000000: The memory free successfully.
* @retval #OS_ERRNO_QUEUE_MAIL_HANDLE_INVALID 0x02000619: The handle of the queue passed-in when the memory
* for the queue is being freed is invalid.
* @retval #OS_ERRNO_QUEUE_MAIL_PTR_INVALID 0x0200061a: The pointer to the memory to be freed is null.
* @retval #OS_ERRNO_QUEUE_MAIL_FREE_ERROR 0x0200061b: The memory for the queue fails to be freed.
* @par Dependency:
* <ul><li>los_queue_pri.h: the header file that contains the API declaration.</li></ul>
* @see OsQueueMailAlloc
*/
extern UINT32 OsQueueMailFree(UINT32 queueID, VOID *mailPool, VOID *mailMem);
extern UINT32 OsQueueInit(VOID);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_QUEUE_PRI_H */
......@@ -45,7 +45,11 @@ extern "C" {
#endif /* __cplusplus */
/********************************************
https://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html
信号本质:用于进程之间的异步通信
信号是Linux系统中用于进程间互相通信或者操作的一种机制,信号可以在任何时候发给某一进程,而无需知道该进程的状态。
如果该进程当前并未处于执行状态,则该信号就由内核保存起来,直到该进程被调度执行并传递给它为止。
如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。
软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。在软件层次上是对中断机制的一种模拟,
在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是进程间通信机制中唯一
的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。
......@@ -181,7 +185,7 @@ struct sigpendq {
};
typedef struct sigpendq sigpendq_t;
struct sq_queue_s {
struct sq_queue_s {//信号队列
sq_entry_t *head;
sq_entry_t *tail;
};
......@@ -204,19 +208,19 @@ typedef struct {//任务中断上下文
typedef struct {//信号切换上下文
TASK_IRQ_CONTEXT
unsigned int R7;
unsigned int count;
unsigned int R7; //存放系统调用的ID
unsigned int count; //信号上下文的数量
} sig_switch_context;
typedef struct {//信号控制块(描述符)
sigset_t sigFlag;
sigset_t sigPendFlag;
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信号
sigset_t sigwaitmask; /* Waiting for pending signals */ //任务在等待某某信号的掩码
siginfo_t sigunbinfo; /* Signal info when task unblocked */ //任务解除阻止时的信号信息
sig_switch_context context; //信号切换上下文,用于保存切换现场
sig_switch_context context; //信号切换上下文, 用于保存切换现场, 比如发生系统调用时的返回,涉及同一个任务的两个栈进行切换
} sig_cb;
#define SIGEV_THREAD_ID 4
......
此差异已折叠。
......@@ -86,11 +86,11 @@ int OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info)
masked = (bool)OsSigIsMember(&sigcb->sigprocmask, info->si_signo);//@note_thinking 这里还有 masked= -1的情况要处理!!!
if (masked) {//集合中已有该信号
/* If signal is in wait list and mask list, need unblock it */ //如果信号在等待列表和掩码列表中,需要解除阻止
if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, info->si_signo)) {//等待
OsTaskWake(stcb);
OsSigEmptySet(&sigcb->sigwaitmask);
if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, info->si_signo)) {//waitList上挂的都是task,sigwaitmask表示是否在等si_signo
OsTaskWake(stcb);//唤醒任务,从阻塞状态变成就绪态
OsSigEmptySet(&sigcb->sigwaitmask);//将sigwaitmask清空,都已经变成就绪状态了,当然就没有要等待的信号了.
} else {
OsSigAddSet(&sigcb->sigPendFlag, info->si_signo);
OsSigAddSet(&sigcb->sigPendFlag, info->si_signo);//
}
} else {//
/* unmasked signal actions */
......@@ -409,7 +409,7 @@ EXIT:
SCHEDULER_UNLOCK(intSave);
return ret;
}
//添加信号到指定信号集
int OsSigAddSet(sigset_t *set, int signo)
{
/* Verify the signal */
......@@ -419,11 +419,11 @@ int OsSigAddSet(sigset_t *set, int signo)
/* In musl, sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */
signo -= 1;
/* Add the signal to the set */
*set |= SIGNO2SET((unsigned int)signo);
*set |= SIGNO2SET((unsigned int)signo);//填充信号集
return LOS_OK;
}
}
//
//获取当前进程的阻塞信号集
int OsSigPending(sigset_t *set)
{
LosTaskCB *tcb = NULL;
......@@ -435,7 +435,7 @@ int OsSigPending(sigset_t *set)
SCHEDULER_LOCK(intSave);
tcb = OsCurrTaskGet();
*set = tcb->sig.sigPendFlag;
*set = tcb->sig.sigPendFlag;//因何而被阻塞
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
......@@ -484,7 +484,7 @@ int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout)
}
return ret;
}
//
//让当前任务等待的信号
int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout)
{
int ret;
......@@ -492,12 +492,12 @@ int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout)
SCHEDULER_LOCK(intSave);
ret = OsSigTimedWaitNoLock(set, info, timeout);
ret = OsSigTimedWaitNoLock(set, info, timeout);//以不加锁的方式等待
SCHEDULER_UNLOCK(intSave);
return ret;
}
//让当前任务暂停的信号
int OsPause(void)
{
LosTaskCB *spcb = NULL;
......@@ -507,7 +507,7 @@ int OsPause(void)
oldSigprocmask = spcb->sig.sigprocmask;
return OsSigSuspend(&oldSigprocmask);
}
//暂停信号
//让当前任务暂停的信号
int OsSigSuspend(const sigset_t *set)
{
unsigned int intSave;
......@@ -568,7 +568,9 @@ int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact)
return LOS_OK;
}
//保存信号现场
/**********************************************
产生系统调用时,也就是软中断时,保存用户栈寄存器现场信息
**********************************************/
void OsSaveSignalContext(unsigned int *sp)
{
UINTPTR sigHandler;
......@@ -581,26 +583,26 @@ void OsSaveSignalContext(unsigned int *sp)
OS_RETURN_IF_VOID(sp == NULL);
cpsr = OS_SYSCALL_GET_CPSR(sp);
OS_RETURN_IF_VOID(((cpsr & CPSR_MASK_MODE) != CPSR_USER_MODE));
OS_RETURN_IF_VOID(((cpsr & CPSR_MASK_MODE) != CPSR_USER_MODE));//必须在用户模式下保存
SCHEDULER_LOCK(intSave);
task = OsCurrTaskGet();
process = OsCurrProcessGet();
sigcb = &task->sig;
sigcb = &task->sig;//获取任务的信号控制块
if ((sigcb->context.count == 0) && ((sigcb->sigFlag != 0) || (process->sigShare != 0))) {
if ((sigcb->context.count == 0) && ((sigcb->sigFlag != 0) || (process->sigShare != 0))) {//未保存上下文且关注了信号
sigHandler = OsGetSigHandler();
if (sigHandler == 0) {
if (sigHandler == 0) {//信号没有注册
sigcb->sigFlag = 0;
process->sigShare = 0;
SCHEDULER_UNLOCK(intSave);
PRINT_ERR("The signal processing function for the current process pid =%d is NULL!\n", task->processID);
return;
}
/* One pthread do the share signal */
sigcb->sigFlag |= process->sigShare;
/* One pthread do the share signal */
sigcb->sigFlag |= process->sigShare;//记录由一个线程执行可进程的共享信号,这些恢复上下文时就找到对应的任务
unsigned int signo = (unsigned int)FindFirstSetedBit(sigcb->sigFlag) + 1;
OsProcessExitCodeSignalSet(process, signo);
sigcb->context.CPSR = cpsr;
sigcb->context.CPSR = cpsr; //保存当前各寄存器的信息
sigcb->context.PC = sp[REG_PC];
sigcb->context.USP = sp[REG_SP];
sigcb->context.ULR = sp[REG_LR];
......@@ -610,17 +612,18 @@ void OsSaveSignalContext(unsigned int *sp)
sigcb->context.R3 = sp[REG_R3];
sigcb->context.R7 = sp[REG_R7];
sigcb->context.R12 = sp[REG_R12];
sp[REG_PC] = sigHandler;
sp[REG_R0] = signo;
sp[REG_R1] = (unsigned int)(UINTPTR)(sigcb->sigunbinfo.si_value.sival_ptr);
sp[REG_PC] = sigHandler;//下一个要执行的函数,信号注册函数
sp[REG_R0] = signo; //信号注册函数参数
sp[REG_R1] = (unsigned int)(UINTPTR)(sigcb->sigunbinfo.si_value.sival_ptr); //@note_why 这里看明白,是干啥子用的?
/* sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */
sigcb->sigFlag ^= 1ULL << (signo - 1);
sigcb->context.count++;
sigcb->context.count++; //代表已保存
}
SCHEDULER_UNLOCK(intSave);
}
//保存信号中断现场
//发生硬中断时,需保存用户态的用户栈现场,多了一个参数 R7寄存器
//汇编调用 见于 los_dispatch.S | 254行: BL OsSaveSignalContextIrq
void OsSaveSignalContextIrq(unsigned int *sp, unsigned int r7)
{
UINTPTR sigHandler;
......@@ -633,7 +636,7 @@ void OsSaveSignalContextIrq(unsigned int *sp, unsigned int r7)
OS_RETURN_IF_VOID(sp == NULL);
cpsr = context->CPSR;
OS_RETURN_IF_VOID(((cpsr & CPSR_MASK_MODE) != CPSR_USER_MODE));
OS_RETURN_IF_VOID(((cpsr & CPSR_MASK_MODE) != CPSR_USER_MODE));//必须在用户模式下保存用户栈信息
SCHEDULER_LOCK(intSave);
task = OsCurrTaskGet();
......@@ -651,7 +654,7 @@ void OsSaveSignalContextIrq(unsigned int *sp, unsigned int r7)
sigcb->sigFlag |= process->sigShare;
unsigned int signo = (unsigned int)FindFirstSetedBit(sigcb->sigFlag) + 1;
OsProcessExitCodeSignalSet(process, signo);
(VOID)memcpy_s(&sigcb->context.R0, sizeof(TaskIrqDataSize), &context->R0, sizeof(TaskIrqDataSize));
(VOID)memcpy_s(&sigcb->context.R0, sizeof(TaskIrqDataSize), &context->R0, sizeof(TaskIrqDataSize));//note_why 为何此处和OsSaveSignalContext的处理不一致?
sigcb->context.R7 = r7;
context->PC = sigHandler;
context->R0 = signo;
......@@ -662,7 +665,13 @@ void OsSaveSignalContextIrq(unsigned int *sp, unsigned int r7)
}
SCHEDULER_UNLOCK(intSave);
}
//恢复信号上下文
/****************************************************
恢复信号上下文,由系统调用之__NR_sigreturn产生,这是一个内部产生的系统调用.
为什么要恢复呢?
因为系统调用的执行由任务内核态完成,使用的栈也是内核栈,CPU相关寄存器记录的都是内核栈的内容,
而系统调用完成后,需返回任务的用户栈执行,这时需将CPU各寄存器回到用户态现场
所以函数的功能就变成了还原寄存器的值
****************************************************/
void OsRestorSignalContext(unsigned int *sp)
{
LosTaskCB *task = NULL; /* Do not adjust this statement */
......@@ -672,28 +681,28 @@ void OsRestorSignalContext(unsigned int *sp)
SCHEDULER_LOCK(intSave);
task = OsCurrTaskGet();
sigcb = &task->sig;
sigcb = &task->sig;//获取当前任务信号控制块
if (sigcb->context.count != 1) {
if (sigcb->context.count != 1) {//必须之前保存过,才能被恢复
SCHEDULER_UNLOCK(intSave);
PRINT_ERR("sig error count : %d\n", sigcb->context.count);
return;
}
process = OsCurrProcessGet();
sp[REG_PC] = sigcb->context.PC;
OS_SYSCALL_SET_CPSR(sp, sigcb->context.CPSR);
sp[REG_SP] = sigcb->context.USP;
sp[REG_LR] = sigcb->context.ULR;
process = OsCurrProcessGet();//获取当前进程
sp[REG_PC] = sigcb->context.PC;//指令寄存器
OS_SYSCALL_SET_CPSR(sp, sigcb->context.CPSR);//重置程序状态寄存器
sp[REG_SP] = sigcb->context.USP;//堆栈指针, USP指的是 用户态的堆栈,即将回到用户栈继续运行
sp[REG_LR] = sigcb->context.ULR;//连接寄存器
sp[REG_R0] = sigcb->context.R0;
sp[REG_R1] = sigcb->context.R1;
sp[REG_R2] = sigcb->context.R2;
sp[REG_R3] = sigcb->context.R3;
sp[REG_R7] = sigcb->context.R7;
sp[REG_R12] = sigcb->context.R12;
sigcb->context.count--;
process->sigShare = 0;
OsProcessExitCodeSignalClear(process);
sigcb->context.count--; //信号上下文的数量回到减少
process->sigShare = 0; //回到用户态,信号共享清0
OsProcessExitCodeSignalClear(process);//清空进程退出码
SCHEDULER_UNLOCK(intSave);
}
......
/*
* 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.
*/
/**
* @defgroup los_sys System time
* @ingroup kernel
*/
#ifndef _LOS_SYS_H
#define _LOS_SYS_H
#include "los_base.h"
#include "los_hwi.h"
#include "los_hw.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_sys
* System time basic function error code: Null pointer.
*
* Value: 0x02000010
*
* Solution: Check whether the input parameter is null.
*/
#define LOS_ERRNO_SYS_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x10)
/**
* @ingroup los_sys
* System time basic function error code: Invalid system clock configuration.
*
* Value: 0x02000011
*
* Solution: Configure a valid system clock in los_config.h.
*/
#define LOS_ERRNO_SYS_CLOCK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x11)
/**
* @ingroup los_sys
* System time basic function error code: This error code is not in use temporarily.
*
* Value: 0x02000012
*
* Solution: None.
*/
#define LOS_ERRNO_SYS_MAXNUMOFCORES_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x12)
/**
* @ingroup los_sys
* System time error code: This error code is not in use temporarily.
*
* Value: 0x02000013
*
* Solution: None.
*/
#define LOS_ERRNO_SYS_PERIERRCOREID_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x13)
/**
* @ingroup los_sys
* System time error code: This error code is not in use temporarily.
*
* Value: 0x02000014
*
* Solution: None.
*/
#define LOS_ERRNO_SYS_HOOK_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x14)
/**
* @ingroup los_typedef
* system time structure.
*/
typedef struct tagSysTime {
UINT16 uwYear; /**< value 1970 ~ 2038 or 1970 ~ 2100 */
UINT8 ucMonth; /**< value 1 - 12 */
UINT8 ucDay; /**< value 1 - 31 */
UINT8 ucHour; /**< value 0 - 23 */
UINT8 ucMinute; /**< value 0 - 59 */
UINT8 ucSecond; /**< value 0 - 59 */
UINT8 ucWeek; /**< value 0 - 6 */
} SYS_TIME_S;
/**
* @ingroup los_sys
* @brief Obtain the number of Ticks.
*
* @par Description:
* This API is used to obtain the number of Ticks.
* @attention
* <ul>
* <li>None</li>
* </ul>
*
* @param None
*
* @retval UINT64 The number of Ticks.
* @par Dependency:
* <ul><li>los_sys.h: the header file that contains the API declaration.</li></ul>
* @see None
*/
extern UINT64 LOS_TickCountGet(VOID);
/**
* @ingroup los_sys
* @brief Obtain the number of cycles in one second.
*
* @par Description:
* This API is used to obtain the number of cycles in one second.
* @attention
* <ul>
* <li>None</li>
* </ul>
*
* @param None
*
* @retval UINT32 Number of cycles obtained in one second.
* @par Dependency:
* <ul><li>los_sys.h: the header file that contains the API declaration.</li></ul>
* @see None
*/
extern UINT32 LOS_CyclePerTickGet(VOID);
/**
* @ingroup los_sys
* @brief Convert Ticks to milliseconds.
*
* @par Description:
* This API is used to convert Ticks to milliseconds.
* @attention
* <ul>
* <li>The number of milliseconds obtained through the conversion is 32-bit.</li>
* </ul>
*
* @param tick [IN] Number of Ticks. The value range is (0,OS_SYS_CLOCK).
*
* @retval UINT32 Number of milliseconds obtained through the conversion. Ticks are successfully converted to
* milliseconds.
* @par Dependency:
* <ul><li>los_sys.h: the header file that contains the API declaration.</li></ul>
* @see LOS_MS2Tick
*/
extern UINT32 LOS_Tick2MS(UINT32 tick);
/**
* @ingroup los_sys
* @brief Convert milliseconds to Ticks.
*
* @par Description:
* This API is used to convert milliseconds to Ticks.
* @attention
* <ul>
* <li>If the parameter passed in is equal to 0xFFFFFFFF, the retval is 0xFFFFFFFF. Pay attention to the value to be
* converted because data possibly overflows.</li>
* </ul>
*
* @param millisec [IN] Number of milliseconds.
*
* @retval UINT32 Number of Ticks obtained through the conversion.
* @par Dependency:
* <ul><li>los_sys.h: the header file that contains the API declaration.</li></ul>
* @see LOS_Tick2MS
*/
extern UINT32 LOS_MS2Tick(UINT32 millisec);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_SYS_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.
*/
/**
* @defgroup los_sys System time
* @ingroup kernel
*/
#ifndef _LOS_SYS_H
#define _LOS_SYS_H
#include "los_base.h"
#include "los_hwi.h"
#include "los_hw.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//定义所有的系统调用的ID ..\third_party\musl\kernel\obj\include\bits\syscall.h
/**
* @ingroup los_sys
* System time basic function error code: Null pointer.
*
* Value: 0x02000010
*
* Solution: Check whether the input parameter is null.
*/
#define LOS_ERRNO_SYS_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x10)
/**
* @ingroup los_sys
* System time basic function error code: Invalid system clock configuration.
*
* Value: 0x02000011
*
* Solution: Configure a valid system clock in los_config.h.
*/
#define LOS_ERRNO_SYS_CLOCK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x11)
/**
* @ingroup los_sys
* System time basic function error code: This error code is not in use temporarily.
*
* Value: 0x02000012
*
* Solution: None.
*/
#define LOS_ERRNO_SYS_MAXNUMOFCORES_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x12)
/**
* @ingroup los_sys
* System time error code: This error code is not in use temporarily.
*
* Value: 0x02000013
*
* Solution: None.
*/
#define LOS_ERRNO_SYS_PERIERRCOREID_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x13)
/**
* @ingroup los_sys
* System time error code: This error code is not in use temporarily.
*
* Value: 0x02000014
*
* Solution: None.
*/
#define LOS_ERRNO_SYS_HOOK_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x14)
/**
* @ingroup los_typedef
* system time structure.
*/
typedef struct tagSysTime {
UINT16 uwYear; /**< value 1970 ~ 2038 or 1970 ~ 2100 */
UINT8 ucMonth; /**< value 1 - 12 */
UINT8 ucDay; /**< value 1 - 31 */
UINT8 ucHour; /**< value 0 - 23 */
UINT8 ucMinute; /**< value 0 - 59 */
UINT8 ucSecond; /**< value 0 - 59 */
UINT8 ucWeek; /**< value 0 - 6 */
} SYS_TIME_S;
/**
* @ingroup los_sys
* @brief Obtain the number of Ticks.
*
* @par Description:
* This API is used to obtain the number of Ticks.
* @attention
* <ul>
* <li>None</li>
* </ul>
*
* @param None
*
* @retval UINT64 The number of Ticks.
* @par Dependency:
* <ul><li>los_sys.h: the header file that contains the API declaration.</li></ul>
* @see None
*/
extern UINT64 LOS_TickCountGet(VOID);
/**
* @ingroup los_sys
* @brief Obtain the number of cycles in one second.
*
* @par Description:
* This API is used to obtain the number of cycles in one second.
* @attention
* <ul>
* <li>None</li>
* </ul>
*
* @param None
*
* @retval UINT32 Number of cycles obtained in one second.
* @par Dependency:
* <ul><li>los_sys.h: the header file that contains the API declaration.</li></ul>
* @see None
*/
extern UINT32 LOS_CyclePerTickGet(VOID);
/**
* @ingroup los_sys
* @brief Convert Ticks to milliseconds.
*
* @par Description:
* This API is used to convert Ticks to milliseconds.
* @attention
* <ul>
* <li>The number of milliseconds obtained through the conversion is 32-bit.</li>
* </ul>
*
* @param tick [IN] Number of Ticks. The value range is (0,OS_SYS_CLOCK).
*
* @retval UINT32 Number of milliseconds obtained through the conversion. Ticks are successfully converted to
* milliseconds.
* @par Dependency:
* <ul><li>los_sys.h: the header file that contains the API declaration.</li></ul>
* @see LOS_MS2Tick
*/
extern UINT32 LOS_Tick2MS(UINT32 tick);
/**
* @ingroup los_sys
* @brief Convert milliseconds to Ticks.
*
* @par Description:
* This API is used to convert milliseconds to Ticks.
* @attention
* <ul>
* <li>If the parameter passed in is equal to 0xFFFFFFFF, the retval is 0xFFFFFFFF. Pay attention to the value to be
* converted because data possibly overflows.</li>
* </ul>
*
* @param millisec [IN] Number of milliseconds.
*
* @retval UINT32 Number of Ticks obtained through the conversion.
* @par Dependency:
* <ul><li>los_sys.h: the header file that contains the API declaration.</li></ul>
* @see LOS_Tick2MS
*/
extern UINT32 LOS_MS2Tick(UINT32 millisec);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_SYS_H */
......@@ -37,7 +37,26 @@
#include "user_copy.h"
#include "los_signal.h"
#include "los_strncpy_from_user.h"
//创建和打开一个posix消息队列
/********************************************************
本文说明:系统调用|IPC
IPC(Inter-Process Communication,进程间通信)
每个进程各自有不同的用户地址空间,进程之间地址保护,相互隔离,任何一个进程的信息在另一个进程中都看不到,
所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,
进程B再从内核缓冲区把数据读走,
IPC实现方式之消息队列:
消息队列特点总结:
(1)消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识.
(2)消息队列允许一个或多个进程向它写入与读取消息.
(3)管道和消息队列的通信数据都是先进先出的原则。
(4)消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比FIFO更有优势。
(5)消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
(6)目前主要有两种类型的消息队列:POSIX消息队列以及System V消息队列,System V消息队列是随内核持续的,
只有在内核重起或者人工删除时,该消息队列才会被删除。
鸿蒙liteos 支持POSIX消息队列并加入了一种自研的消息队列 liteipc,此处重点讲 posix消息队列
********************************************************/
//打开一个消息队列,封装了posix接口
mqd_t SysMqOpen(const char *mqName, int openFlag, mode_t mode, struct mq_attr *attr)
{
mqd_t ret;
......@@ -48,7 +67,7 @@ mqd_t SysMqOpen(const char *mqName, int openFlag, mode_t mode, struct mq_attr *a
if (retValue < 0) {
return retValue;
}
ret = mq_open(kMqName, openFlag, mode, attr);
ret = mq_open(kMqName, openFlag, mode, attr);//posix
if (ret == -1) {
return (mqd_t)-get_errno();
}
......@@ -251,7 +270,7 @@ int SysSigTimedWait(const sigset_t_l *setl, siginfo_t *info, const struct timesp
}
return (ret == 0 ? infoIntr.si_signo : ret);
}
//IPC系统调用之暂停任务
int SysPause(void)
{
return OsPause();
......
此差异已折叠。
此差异已折叠。
git add -A
git commit -m '如何跨CPU删除任务?注解一个任务是如何自杀和被他杀的.
git commit -m '1.注解系统调用是如何发生的 2.完善对消息队列的注解
搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册