鸿蒙内核源码分析(事件控制篇) | 任务间一对多和多对多的同步方案

    搜索 @note_pic 可查看绘制的全部字符图
    搜索 @note_why 是尚未看明白的地方,有看明白的,请Pull Request完善
    搜索 @note_thinking 是一些的思考和建议
    搜索 @note_#if0 是由第三方项目提供不在内核源码中定义的极为重要结构体,为方便理解而添加的。
    搜索 @note_good 是给源码点赞的地方
上级 decc273f
此差异已折叠。
...@@ -312,8 +312,8 @@ typedef struct { ...@@ -312,8 +312,8 @@ typedef struct {
LOS_DL_LIST pendList; /**< Task pend node */ //如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时 LOS_DL_LIST pendList; /**< Task pend node */ //如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时
LOS_DL_LIST threadList; /**< thread list */ //挂到所属进程的线程链表上 LOS_DL_LIST threadList; /**< thread list */ //挂到所属进程的线程链表上
SortLinkList sortList; /**< Task sortlink node */ //挂到cpu core 的任务执行链表上 SortLinkList sortList; /**< Task sortlink node */ //挂到cpu core 的任务执行链表上
UINT32 eventMask; /**< Event mask */ //事件屏蔽 UINT32 eventMask; /**< Event mask */ //对哪些事件进行屏蔽
UINT32 eventMode; /**< Event mode */ //事件模式 UINT32 eventMode; /**< Event mode */ //事件三种模式(LOS_WAITMODE_AND,LOS_WAITMODE_OR,LOS_WAITMODE_CLR)
UINT32 priBitMap; /**< BitMap for recording the change of task priority, //任务在执行过程中优先级会经常变化,这个变量用来记录所有曾经变化 UINT32 priBitMap; /**< BitMap for recording the change of task priority, //任务在执行过程中优先级会经常变化,这个变量用来记录所有曾经变化
the priority can not be greater than 31 */ //过的优先级,例如 ..01001011 曾经有过 0,1,3,6 优先级 the priority can not be greater than 31 */ //过的优先级,例如 ..01001011 曾经有过 0,1,3,6 优先级
INT32 errorNo; /**< Error Num */ INT32 errorNo; /**< Error Num */
......
...@@ -96,10 +96,10 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB) ...@@ -96,10 +96,10 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
return LOS_ERRNO_EVENT_PTR_NULL; return LOS_ERRNO_EVENT_PTR_NULL;
} }
intSave = LOS_IntLock(); intSave = LOS_IntLock();//锁中断
eventCB->uwEventID = 0; eventCB->uwEventID = 0;
LOS_ListInit(&eventCB->stEventList);//事件链表初始化 LOS_ListInit(&eventCB->stEventList);//事件链表初始化
LOS_IntRestore(intSave); LOS_IntRestore(intSave);//恢复中断
return LOS_OK; return LOS_OK;
} }
//事件参数检查 //事件参数检查
...@@ -124,7 +124,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMa ...@@ -124,7 +124,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMa
} }
return LOS_OK; return LOS_OK;
} }
////根据用户传入的事件值、事件掩码及校验模式,返回用户传入的事件是否符合预期 //根据用户传入的事件值、事件掩码及校验模式,返回用户传入的事件是否符合预期
LITE_OS_SEC_TEXT UINT32 OsEventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode) LITE_OS_SEC_TEXT UINT32 OsEventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode)
{ {
UINT32 ret = 0; UINT32 ret = 0;
...@@ -223,46 +223,46 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB, UINT32 eventMask ...@@ -223,46 +223,46 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB, UINT32 eventMask
//事件恢复操作 //事件恢复操作
LITE_OS_SEC_TEXT STATIC UINT8 OsEventResume(LosTaskCB *resumedTask, const PEVENT_CB_S eventCB, UINT32 events) LITE_OS_SEC_TEXT STATIC UINT8 OsEventResume(LosTaskCB *resumedTask, const PEVENT_CB_S eventCB, UINT32 events)
{ {
UINT8 exitFlag = 0; UINT8 exitFlag = 0;//是否唤醒
if (((resumedTask->eventMode & LOS_WAITMODE_OR) && ((resumedTask->eventMask & events) != 0)) || if (((resumedTask->eventMode & LOS_WAITMODE_OR) && ((resumedTask->eventMask & events) != 0)) ||
((resumedTask->eventMode & LOS_WAITMODE_AND) && ((resumedTask->eventMode & LOS_WAITMODE_AND) &&
((resumedTask->eventMask & eventCB->uwEventID) == resumedTask->eventMask))) { ((resumedTask->eventMask & eventCB->uwEventID) == resumedTask->eventMask))) {//逻辑与 和 逻辑或 的处理
exitFlag = 1; exitFlag = 1;
resumedTask->taskEvent = NULL; resumedTask->taskEvent = NULL;
OsTaskWake(resumedTask);//唤醒任务 OsTaskWake(resumedTask);//唤醒任务,加入就绪队列
} }
return exitFlag; return exitFlag;
} }
//以不安全的方式写事件
LITE_OS_SEC_TEXT VOID OsEventWriteUnsafe(PEVENT_CB_S eventCB, UINT32 events, BOOL once, UINT8 *exitFlag) LITE_OS_SEC_TEXT VOID OsEventWriteUnsafe(PEVENT_CB_S eventCB, UINT32 events, BOOL once, UINT8 *exitFlag)
{ {
LosTaskCB *resumedTask = NULL; LosTaskCB *resumedTask = NULL;
LosTaskCB *nextTask = NULL; LosTaskCB *nextTask = NULL;
BOOL schedFlag = FALSE; BOOL schedFlag = FALSE;
eventCB->uwEventID |= events; eventCB->uwEventID |= events;//对应位贴上标签
if (!LOS_ListEmpty(&eventCB->stEventList)) { if (!LOS_ListEmpty(&eventCB->stEventList)) {//等待事件链表判断,处理等待事件的任务
for (resumedTask = LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext, LosTaskCB, pendList); for (resumedTask = LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext, LosTaskCB, pendList);
&resumedTask->pendList != &eventCB->stEventList;) { &resumedTask->pendList != &eventCB->stEventList;) {//循环获取任务链表
nextTask = LOS_DL_LIST_ENTRY(resumedTask->pendList.pstNext, LosTaskCB, pendList); nextTask = LOS_DL_LIST_ENTRY(resumedTask->pendList.pstNext, LosTaskCB, pendList);//获取任务实体
if (OsEventResume(resumedTask, eventCB, events)) { if (OsEventResume(resumedTask, eventCB, events)) {//是否恢复任务
schedFlag = TRUE; schedFlag = TRUE;//任务已加至就绪队列,申请发生一次调度
} }
if (once == TRUE) { if (once == TRUE) {//是否只处理一次任务
break; break;//退出循环
} }
resumedTask = nextTask; resumedTask = nextTask;//检查链表中下一个任务
} }
} }
if ((exitFlag != NULL) && (schedFlag == TRUE)) { if ((exitFlag != NULL) && (schedFlag == TRUE)) {//是否让外面调度
*exitFlag = 1; *exitFlag = 1;
} }
} }
//写入事件
LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, BOOL once) LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, BOOL once)
{ {
UINT32 intSave; UINT32 intSave;
...@@ -276,13 +276,13 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, ...@@ -276,13 +276,13 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events,
return LOS_ERRNO_EVENT_SETBIT_INVALID; return LOS_ERRNO_EVENT_SETBIT_INVALID;
} }
SCHEDULER_LOCK(intSave); SCHEDULER_LOCK(intSave); //禁止调度
OsEventWriteUnsafe(eventCB, events, once, &exitFlag); OsEventWriteUnsafe(eventCB, events, once, &exitFlag);//写入事件
SCHEDULER_UNLOCK(intSave); SCHEDULER_UNLOCK(intSave); //允许调度
if (exitFlag == 1) { if (exitFlag == 1) { //需要发生调度
LOS_MpSchedule(OS_MP_CPU_ALL); LOS_MpSchedule(OS_MP_CPU_ALL);//通知所有CPU调度
LOS_Schedule(); LOS_Schedule();//执行调度
} }
return LOS_OK; return LOS_OK;
} }
......
git add -A git add -A
git commit -m '鸿蒙内核源码分析(信号量篇) | 信号量解决任务同步问题 git commit -m '鸿蒙内核源码分析(事件控制篇) | 任务间一对多和多对多的同步方案
搜索 @note_pic 可查看绘制的全部字符图 搜索 @note_pic 可查看绘制的全部字符图
搜索 @note_why 是尚未看明白的地方,有看明白的,请Pull Request完善 搜索 @note_why 是尚未看明白的地方,有看明白的,请Pull Request完善
搜索 @note_thinking 是一些的思考和建议 搜索 @note_thinking 是一些的思考和建议
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册