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

内存,进程,task模块注释基本完成. 本次提交涉及 LOS_TaskYield PendList IRQ ,FIQ等知识点

鸿蒙内核源码分析系列 https://blog.csdn.net/kuangyufei https://my.oschina.net/u/3751245
上级 8b973228
......@@ -282,11 +282,11 @@ extern HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM];
* @par Dependency:
* <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
* @see LOS_IntRestore
*/
*///在所有中断被禁用之前获得的CPSR值
STATIC INLINE UINT32 LOS_IntLock(VOID)
{
{//此API用于禁用CPSR中的所有IRQ和FIQ中断。
return ArchIntLock();
}
}//IRQ(Interrupt Request):指中断模式。FIQ(Fast Interrupt Request):指快速中断模式。
/**
* @ingroup los_hwi
......@@ -307,9 +307,9 @@ STATIC INLINE UINT32 LOS_IntLock(VOID)
* @par Dependency:
* <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
* @see LOS_IntLock
*/
*///启用所有中断后获得的CPSR值
STATIC INLINE UINT32 LOS_IntUnLock(VOID)
{
{//此API用于启用CPSR中的所有IRQ和FIQ中断。
return ArchIntUnlock();
}
......@@ -333,9 +333,9 @@ STATIC INLINE UINT32 LOS_IntUnLock(VOID)
* @par Dependency:
* <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
* @see LOS_IntLock
*/
*///在所有中断被禁用之前获得的CPSR值
STATIC INLINE VOID LOS_IntRestore(UINT32 intSave)
{
{//只有在禁用所有中断之后才能调用此API,并且输入参数值应为LOS_IntLock返回的值。
ArchIntRestore(intSave);
}
......
......@@ -319,7 +319,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID)
UINT32 size;
g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT;//任务池中最多默认128个,可谓铁打的任务池流水的线程
size = (g_taskMaxNum + 1) * sizeof(LosTaskCB);//家谱的
size = (g_taskMaxNum + 1) * sizeof(LosTaskCB);//计算需分配内存总大小
/*
* This memory is resident memory and is used to save the system resources
* of task control block and will not be freed.
......@@ -1351,26 +1351,26 @@ 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
*/
*///任务等待
UINT32 OsTaskWait(LOS_DL_LIST *list, UINT32 timeout, BOOL needSched)
{
LosTaskCB *runTask = NULL;
LOS_DL_LIST *pendObj = NULL;
runTask = OsCurrTaskGet();
OS_TASK_SCHED_QUEUE_DEQUEUE(runTask, OS_PROCESS_STATUS_PEND);
runTask = OsCurrTaskGet();//获取当前任务
OS_TASK_SCHED_QUEUE_DEQUEUE(runTask, OS_PROCESS_STATUS_PEND);//将任务从就绪队列摘除,并变成阻塞状态
pendObj = &runTask->pendList;
runTask->taskStatus |= OS_TASK_STATUS_PEND;
LOS_ListTailInsert(list, pendObj);
if (timeout != LOS_WAIT_FOREVER) {
runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME;
OsAdd2TimerList(runTask, timeout);
runTask->taskStatus |= OS_TASK_STATUS_PEND;//给任务贴上阻塞任务标签
LOS_ListTailInsert(list, pendObj);//将阻塞任务挂到list上,,这步很关键,很重要!
if (timeout != LOS_WAIT_FOREVER) {//非永远等待的时候
runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME;//阻塞任务再贴上一段时间内阻塞
OsAdd2TimerList(runTask, timeout);//把任务加到定时器链表中
}
if (needSched == TRUE) {
OsSchedResched();
if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) {
runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT;
if (needSched == TRUE) {//是否需要调度
OsSchedResched();//申请调度,里面直接切换了任务上下文,此次任务不再往下执行了.
if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) {//这条语句是被调度再次选中时执行的,和上面的语句可能隔了很长时间,所以很可能已经超时了
runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT;//如果任务有timeout的标签,那么就去掉那个标签
return LOS_ERRNO_TSK_TIMEOUT;
}
}
......@@ -1381,21 +1381,21 @@ UINT32 OsTaskWait(LOS_DL_LIST *list, UINT32 timeout, BOOL needSched)
* Description : delete the task from pendlist and also add to the priqueue
* Input : resumedTask --- resumed task
* taskStatus --- task status
*/
VOID OsTaskWake(LosTaskCB *resumedTask)
*///任务被唤醒
VOID OsTaskWake(LosTaskCB *resumedTask)//这个函数是被别的task唤醒的,当前任务可不是resumedTask,一定要明白这点.
{
LOS_ListDelete(&resumedTask->pendList);
resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND;
LOS_ListDelete(&resumedTask->pendList);//将自己从阻塞链表中摘除
resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND;//任务不再阻塞
if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) {
OsTimerListDelete(resumedTask);
resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME;
}
if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPEND)) {
OS_TASK_SCHED_QUEUE_ENQUEUE(resumedTask, OS_PROCESS_STATUS_PEND);
if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) {//有阻塞时间标签的时候
OsTimerListDelete(resumedTask);//从CPU的taskSortLink中摘除自己
resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME;//撕掉阻塞时间标签
}
if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPEND)) {//任务不是挂起状态时
OS_TASK_SCHED_QUEUE_ENQUEUE(resumedTask, OS_PROCESS_STATUS_PEND);//将任务加入调度队列,OS_PROCESS_STATUS_PEND表示加入就绪队列前的状态
}//OS_TASK_SCHED_QUEUE_ENQUEUE 之后 resumedTask就变成了ready状态,等待被调度选中
}
//任务大公无私,主动让出CPU. 读懂这个函数 你就彻底搞懂了 yield
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
{
UINT32 tskCount;
......@@ -1411,7 +1411,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
return LOS_ERRNO_TSK_YIELD_IN_LOCK;
}
runTask = OsCurrTaskGet();
runTask = OsCurrTaskGet();//获取当前任务
if (OS_TID_CHECK_INVALID(runTask->taskID)) {
return LOS_ERRNO_TSK_ID_INVALID;
}
......@@ -1419,28 +1419,28 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
SCHEDULER_LOCK(intSave);
/* reset timeslice of yeilded task */
runTask->timeSlice = 0;
runProcess = OS_PCB_FROM_PID(runTask->processID);
tskCount = OS_TASK_PRI_QUEUE_SIZE(runProcess, runTask);
runTask->timeSlice = 0;//重置时间片
runProcess = OS_PCB_FROM_PID(runTask->processID);//获取当前进程
tskCount = OS_TASK_PRI_QUEUE_SIZE(runProcess, runTask);//获取进程中和当前任务一样的task数
if (tskCount > 0) {
OS_TASK_PRI_QUEUE_ENQUEUE(runProcess, runTask);
runTask->taskStatus |= OS_TASK_STATUS_READY;
OS_TASK_PRI_QUEUE_ENQUEUE(runProcess, runTask);//先出队列,再入就绪队列, 这句话总意思就是是把自己排到最后,给同级兄弟让位置,所以叫 yield
runTask->taskStatus |= OS_TASK_STATUS_READY;//任务状态变成就绪
} else {
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
OsSchedResched();
OsSchedResched();//申请调度
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
//任务锁
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID)
{
UINT32 intSave;
UINT32 *losTaskLock = NULL;
intSave = LOS_IntLock();
losTaskLock = &OsPercpuGet()->taskLockCnt;
losTaskLock = &OsPercpuGet()->taskLockCnt;//task lock 的计数器
(*losTaskLock)++;
LOS_IntRestore(intSave);
}
......@@ -1468,7 +1468,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
LOS_IntRestore(intSave);
}
//获取任务信息,给shell使用的
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo)
{
UINT32 intSave;
......
......@@ -309,7 +309,7 @@ typedef struct {
VOID *taskEvent; /**< Task-held event */
UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 */
CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name */
LOS_DL_LIST pendList; /**< Task pend node */
LOS_DL_LIST pendList; /**< Task pend node *///如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时
LOS_DL_LIST threadList; /**< thread list */
SortLinkList sortList; /**< Task sortlink node */
UINT32 eventMask; /**< Event mask */
......
......@@ -218,7 +218,7 @@ STATIC VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *
return;
}
queueNode = &(queueCB->queueHandle[(queuePosion * (queueCB->queueSize))]);//拿到队列节点
queueNode = &(queueCB->queueHandle[(queuePosion * (queueCB->queueSize))]);//执行回调函数
if (OS_QUEUE_IS_READ(operateType)) {//读操作处理,读队列分两步走
if (memcpy_s(&msgDataSize, sizeof(UINT32), queueNode + queueCB->queueSize - sizeof(UINT32),
......@@ -286,9 +286,9 @@ UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT
goto QUEUE_END;
}
ret = OsTaskWait(&queueCB->readWriteList[readWrite], timeout, TRUE);//任务等待
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
ret = LOS_ERRNO_QUEUE_TIMEOUT;
ret = OsTaskWait(&queueCB->readWriteList[readWrite], timeout, TRUE);//任务等待,这里很重要啊,说明下把当前任务从就绪列表摘除,
if (ret == LOS_ERRNO_TSK_TIMEOUT) {//并挂在readWriteList[readWrite]上,如此一来readWriteList[readWrite]上挂的都是task
ret = LOS_ERRNO_QUEUE_TIMEOUT;//通过OS_TCB_FROM_PENDLIST就能找到task实体
goto QUEUE_END;
}
} else {
......@@ -298,7 +298,7 @@ UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT
OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize);//发起读或写队列操作
if (!LOS_ListEmpty(&queueCB->readWriteList[!readWrite])) {//另外的operateType中还有其他消息时,如果 operateType=read,这时去查write队列,读写交互操作
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite]));//拿到拥有这个队列节点的任务
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite]));//拿到拥有这个队列节点的任务 ?????
OsTaskWake(resumedTask);//唤醒任务去处理队列的值
SCHEDULER_UNLOCK(intSave);
LOS_MpSchedule(OS_MP_CPU_ALL);//让所有CPU参与调度
......@@ -321,15 +321,15 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueID,
UINT32 ret;
UINT32 operateType;
ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeout);
ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeout);//参数检查
if (ret != LOS_OK) {
return ret;
}
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD);
return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeout);
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD);//意思是从头开始读
return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeout);//执行读操作
}
//接口函数 从队列头开始写
LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID,
VOID *bufferAddr,
UINT32 bufferSize,
......@@ -338,15 +338,15 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID,
UINT32 ret;
UINT32 operateType;
ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);
ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);//参数检查
if (ret != LOS_OK) {
return ret;
}
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD);
return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD);//从头开始写
return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);//执行写操作
}
//接口函数 从队列尾部开始写
LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID,
VOID *bufferAddr,
UINT32 bufferSize,
......@@ -355,13 +355,13 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID,
UINT32 ret;
UINT32 operateType;
ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);
ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);//参数检查
if (ret != LOS_OK) {
return ret;
}
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL);
return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL);//从尾部开始写
return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);//执行写操作
}
//读一个队列数据
LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout)
......@@ -445,7 +445,7 @@ QUEUE_END:
SCHEDULER_UNLOCK(intSave);
return ret;
}
//获取队列信息,用一个queueInfo 把 LosQueueCB数据接走
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo)
{
UINT32 intSave;
......@@ -457,14 +457,14 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *que
return LOS_ERRNO_QUEUE_PTR_NULL;
}
if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {//1024
return LOS_ERRNO_QUEUE_INVALID;
}
(VOID)memset_s((VOID *)queueInfo, sizeof(QUEUE_INFO_S), 0, sizeof(QUEUE_INFO_S));
(VOID)memset_s((VOID *)queueInfo, sizeof(QUEUE_INFO_S), 0, sizeof(QUEUE_INFO_S));//接人之前先清0
SCHEDULER_LOCK(intSave);
queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);//通过队列ID获取 QCB
if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {
ret = LOS_ERRNO_QUEUE_NOT_CREATE;
goto QUEUE_END;
......@@ -475,18 +475,18 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *que
queueInfo->usQueueSize = queueCB->queueSize;
queueInfo->usQueueHead = queueCB->queueHead;
queueInfo->usQueueTail = queueCB->queueTail;
queueInfo->usReadableCnt = queueCB->readWriteableCnt[OS_QUEUE_READ];
queueInfo->usWritableCnt = queueCB->readWriteableCnt[OS_QUEUE_WRITE];
queueInfo->usReadableCnt = queueCB->readWriteableCnt[OS_QUEUE_READ];//可读数
queueInfo->usWritableCnt = queueCB->readWriteableCnt[OS_QUEUE_WRITE];//可写数
LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_READ], LosTaskCB, pendList) {
queueInfo->uwWaitReadTask |= 1ULL << tskCB->taskID;
}
LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_READ], LosTaskCB, pendList) {//循环的目的是找出哪些task需要读
queueInfo->uwWaitReadTask |= 1ULL << tskCB->taskID;//记录等待读的任务号, uwWaitReadTask 每一位代表一个任务编号
}//0b..011011011 代表 0,1,3,4,6,7 号任务有数据等待读.
LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_WRITE], LosTaskCB, pendList) {
LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_WRITE], LosTaskCB, pendList) {//循环的目的是找出哪些task需要写
queueInfo->uwWaitWriteTask |= 1ULL << tskCB->taskID;
}
LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->memList, LosTaskCB, pendList) {
LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->memList, LosTaskCB, pendList) {//同上
queueInfo->uwWaitMemTask |= 1ULL << tskCB->taskID;
}
......
......@@ -57,7 +57,7 @@ LITE_OS_SEC_BSS LosSemCB *g_allSem = NULL;
* Description : Initialize the semaphore doubly linked list
* Return : LOS_OK on success, or error code on failure
*/
LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)
LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)//信号量初始化
{
LosSemCB *semNode = NULL;
UINT32 index;
......
......@@ -143,7 +143,7 @@ UINT32 OsPriQueueProcessSize(LOS_DL_LIST *priQueueList, UINT32 priority)
return itemCnt;
}
//获取队列的数量
UINT32 OsPriQueueSize(LOS_DL_LIST *priQueueList, UINT32 priority)
{
UINT32 itemCnt = 0;
......@@ -156,14 +156,14 @@ UINT32 OsPriQueueSize(LOS_DL_LIST *priQueueList, UINT32 priority)
LOS_ASSERT(OsIntLocked());
LOS_ASSERT(LOS_SpinHeld(&g_taskSpin));
LOS_DL_LIST_FOR_EACH(curNode, &priQueueList[priority]) {
LOS_DL_LIST_FOR_EACH(curNode, &priQueueList[priority]) {//循环查找这优先级的数量
#if (LOSCFG_KERNEL_SMP == YES)
task = OS_TCB_FROM_PENDLIST(curNode);
if (!(task->cpuAffiMask & (1U << cpuID))) {
task = OS_TCB_FROM_PENDLIST(curNode);//找到task
if (!(task->cpuAffiMask & (1U << cpuID))) {//属不属于当前CPU
continue;
}
#endif
++itemCnt;
++itemCnt;//计数器
}
return itemCnt;
......
git add -A
git commit -m '内存,进程,task模块注释基本完成. 正在更新: 进程间IPC通讯消息队列模块代码注释...
git commit -m '内存,进程,task模块注释基本完成. 本次提交涉及 LOS_TaskYield PendList IRQ ,FIQ等知识点
鸿蒙内核源码分析系列 https://blog.csdn.net/kuangyufei https://my.oschina.net/u/3751245'
git push origin
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册