Compare commits

...

15 Commits

@ -31,54 +31,68 @@
#include "los_bitmap.h"
#include "los_printf.h"
#include "los_toolchain.h"
#include "los_toolchain.h"//GCC 编译器的内置函数
/**
bit
bit
10
1
*/
#define OS_BITMAP_MASK 0x1FU
#define OS_BITMAP_WORD_MASK ~0UL
/* find first zero bit starting from LSB */
STATIC INLINE UINT16 Ffz(UINTPTR x)
{
return __builtin_ffsl(~x) - 1;
{//__builtin_ffsl: 返回右起第一个1的位置函数来自 glibc
return __builtin_ffsl(~x) - 1;//从LSB开始查找第一个零位 LSB(最低有效位) 对应 最高有效位(MSB)
}
///对状态字的某一标志位进行置1操作
VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos)
{
if (bitmap == NULL) {
return;
}
*bitmap |= 1U << (pos & OS_BITMAP_MASK);
*bitmap |= 1U << (pos & OS_BITMAP_MASK);//在对应位上置1
}
///对状态字的某一标志位进行清0操作
VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos)
{
if (bitmap == NULL) {
return;
}
*bitmap &= ~(1U << (pos & OS_BITMAP_MASK));
*bitmap &= ~(1U << (pos & OS_BITMAP_MASK));//在对应位上置0
}
/**
1 : 00110110 5
CLZ 0
  1.使1
  2.
*/
UINT16 LOS_HighBitGet(UINT32 bitmap)
{
if (bitmap == 0) {
return LOS_INVALID_BIT_INDEX;
}
return (OS_BITMAP_MASK - CLZ(bitmap));
return (OS_BITMAP_MASK - CLZ(bitmap));//CLZ = count leading zeros 用于计算整数的前导零
}
/// 获取参数位图中最低位为1的索引位 例如: 00110110 返回 1
UINT16 LOS_LowBitGet(UINT32 bitmap)
{
if (bitmap == 0) {
return LOS_INVALID_BIT_INDEX;
}
return CTZ(bitmap);
return CTZ(bitmap);// CTZ = count trailing zeros 用于计算给定整数的尾随零
}
/// 从start位置开始设置numsSet个bit位 置1
VOID LOS_BitmapSetNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsSet)
{
UINTPTR *p = bitmap + BITMAP_WORD(start);
@ -98,7 +112,7 @@ VOID LOS_BitmapSetNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsSet)
*p |= maskToSet;
}
}
///从start位置开始 清除numsSet个bit位置0 ,对状态字的连续标志位进行清0操作
VOID LOS_BitmapClrNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsClear)
{
UINTPTR *p = bitmap + BITMAP_WORD(start);
@ -118,7 +132,7 @@ VOID LOS_BitmapClrNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsClear)
*p &= ~maskToClear;
}
}
///从numBits位置开始找到第一个0位
INT32 LOS_BitmapFfz(UINTPTR *bitmap, UINT32 numBits)
{
INT32 bit, i;

@ -1,4 +1,9 @@
/*
/*并发Concurrent:多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程,
线
Parallel线CPU线
CPU线
CPU线
LITE_OS_SEC_BSS LITE_OS_SEC_DATA_INIT
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
@ -56,23 +61,23 @@
#include "los_vm_syscall.h"
LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL;
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess;
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList;
LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL;///< 进程池数组
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess;///< 空闲状态下的进程链表
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList;///< 需要回收的进程列表
LITE_OS_SEC_BSS UINT32 g_userInitProcess = OS_INVALID_VALUE;
LITE_OS_SEC_BSS UINT32 g_kernelInitProcess = OS_INVALID_VALUE;
LITE_OS_SEC_BSS UINT32 g_kernelIdleProcess = OS_INVALID_VALUE;
LITE_OS_SEC_BSS UINT32 g_processMaxNum;
LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL;
LITE_OS_SEC_BSS UINT32 g_processMaxNum;///< 进程最大数量,默认64个
LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL;///< 全局进程组,负责管理所有进程组
//将进程插入到空闲的链表中//
STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB)
{
UINT32 pid = processCB->processID;
(VOID)memset_s(processCB, sizeof(LosProcessCB), 0, sizeof(LosProcessCB));
processCB->processID = pid;
processCB->processStatus = OS_PROCESS_FLAG_UNUSED;
processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
LOS_ListTailInsert(&g_freeProcess, &processCB->pendList);
UINT32 pid = processCB->processID;//获取进程ID
(VOID)memset_s(processCB, sizeof(LosProcessCB), 0, sizeof(LosProcessCB));//进程描述符数据清0
processCB->processID = pid;//进程ID
processCB->processStatus = OS_PROCESS_FLAG_UNUSED;//设置为进程未使用
processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;//timeID初始化值
LOS_ListTailInsert(&g_freeProcess, &processCB->pendList);//进程节点挂入g_freeProcess以分配给后续进程使用
}
STATIC ProcessGroup *OsCreateProcessGroup(UINT32 pid)
@ -97,25 +102,25 @@ STATIC ProcessGroup *OsCreateProcessGroup(UINT32 pid)
return group;
}
/* 退出进程组,参数是进程地址和进程组地址的地址 */
STATIC VOID OsExitProcessGroup(LosProcessCB *processCB, ProcessGroup **group)
{
LosProcessCB *groupProcessCB = OS_PCB_FROM_PID(processCB->group->groupID);
LOS_ListDelete(&processCB->subordinateGroupList);
LOS_ListDelete(&processCB->subordinateGroupList);//从进程组进程链表上摘出去
if (LOS_ListEmpty(&processCB->group->processList) && LOS_ListEmpty(&processCB->group->exitProcessList)) {
LOS_ListDelete(&processCB->group->groupList);
groupProcessCB->processStatus &= ~OS_PROCESS_FLAG_GROUP_LEADER;
*group = processCB->group;
if (OsProcessIsUnused(groupProcessCB) && !(groupProcessCB->processStatus & OS_PROCESS_FLAG_EXIT)) {
LOS_ListDelete(&groupProcessCB->pendList);
OsInsertPCBToFreeList(groupProcessCB);
LOS_ListDelete(&groupProcessCB->pendList);//进程从全局进程链表上摘除
OsInsertPCBToFreeList(groupProcessCB);//释放进程的资源,回到freelist再利用
}
}
processCB->group = NULL;
}
/*通过指定组ID找到进程组 */
STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid)
{
ProcessGroup *group = NULL;
@ -132,7 +137,7 @@ STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid)
PRINT_INFO("%s is find group : %u failed!\n", __FUNCTION__, gid);
return NULL;
}
/*给指定进程组发送信号 */
STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *group, siginfo_t *info, INT32 permission)
{
INT32 ret, success, err;
@ -152,7 +157,7 @@ STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *group, siginfo_t *i
/* At least one success. */
return success ? LOS_OK : ret;
}
//创建进程组//
LITE_OS_SEC_TEXT INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission)
{
INT32 ret, success, err;
@ -232,7 +237,7 @@ STATIC LosProcessCB *OsFindExitChildProcess(const LosProcessCB *processCB, INT32
PRINT_INFO("%s is find the exit child : %d failed in parent : %u\n", __FUNCTION__, childPid, processCB->processID);
return NULL;
}
/* 唤醒等待wakePID结束的任务 */
VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID)
{
taskCB->waitID = wakePID;
@ -241,7 +246,7 @@ VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID)
LOS_MpSchedule(OS_MP_CPU_ALL);
#endif
}
/* 唤醒等待参数进程结束的任务 */
STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *processCB, LOS_DL_LIST **anyList)
{
LOS_DL_LIST *list = head;
@ -249,7 +254,7 @@ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *pr
UINT32 pid = 0;
BOOL find = FALSE;
while (list->pstNext != head) {
while (list->pstNext != head) {//遍历等待链表 processCB->waitList
taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
if ((taskCB->waitFlag == OS_PROCESS_WAIT_PRO) && (taskCB->waitID == processCB->processID)) {
if (pid == 0) {
@ -259,7 +264,7 @@ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *pr
pid = OS_INVALID_VALUE;
}
OsWaitWakeTask(taskCB, pid);
OsWaitWakeTask(taskCB, pid);//唤醒这个任务,此时会切到 LOS_Wait runTask->waitFlag = 0;处运行
continue;
}
@ -272,7 +277,7 @@ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *pr
return find;
}
/* 检查父进程的等待任务并唤醒父进程去处理等待任务 */
STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosProcessCB *processCB)
{
LOS_DL_LIST *head = &parentCB->waitList;
@ -281,29 +286,29 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro
BOOL findSpecified = FALSE;
if (LOS_ListEmpty(&parentCB->waitList)) {
return;
return;//检查是否有正在等待子进程退出的任务,若没有则退出
}
findSpecified = OsWaitWakeSpecifiedProcess(head, processCB, &list);
findSpecified = OsWaitWakeSpecifiedProcess(head, processCB, &list);//找到指定的任务
if (findSpecified == TRUE) {
/* No thread is waiting for any child process to finish */
if (LOS_ListEmpty(&parentCB->waitList)) {
if (LOS_ListEmpty(&parentCB->waitList)) {//没有线程正在等待任何子进程结束
return;
} else if (!LOS_ListEmpty(&parentCB->childrenList)) {
/* Other child processes exist, and other threads that are waiting
* for the child to finish continue to wait
*/
*///存在其他子进程,正在等待它们的子进程结束而将继续等待
return;
}
}
/* Waiting threads are waiting for a specified child process to finish */
if (list == NULL) {
if (list == NULL) {//等待线程正在等待指定的子进程结束
return;
}
/* No child processes exist and all waiting threads are awakened */
if (findSpecified == TRUE) {
if (findSpecified == TRUE) {//所有等待的任务都唤醒
while (list->pstNext != head) {
taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
OsWaitWakeTask(taskCB, OS_INVALID_VALUE);
@ -311,7 +316,7 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro
return;
}
while (list->pstNext != head) {
while (list->pstNext != head) {//处理 OS_PROCESS_WAIT_GID 标签
taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
if (taskCB->waitFlag == OS_PROCESS_WAIT_GID) {
if (taskCB->waitID != processCB->group->groupID) {
@ -334,7 +339,7 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro
return;
}
/* 回收指定进程的资源 */
LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
{
if (!(processCB->processStatus & (OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_RUNNING))) {
@ -351,8 +356,8 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
#ifdef LOSCFG_SECURITY_CAPABILITY
if (processCB->user != NULL) {
(VOID)LOS_MemFree(m_aucSysMem1, processCB->user);
processCB->user = NULL;
(VOID)LOS_MemFree(m_aucSysMem1, processCB->user);//删除用户
processCB->user = NULL;//重置指针为空
}
#endif
@ -376,23 +381,23 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
LITE_OS_SEC_TEXT STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **group)
{
OsExitProcessGroup(childCB, group);
LOS_ListDelete(&childCB->siblingList);
OsExitProcessGroup(childCB, group);//退出进程组
LOS_ListDelete(&childCB->siblingList);//从父亲大人的子孙链表上摘除
if (childCB->processStatus & OS_PROCESS_STATUS_ZOMBIES) {
childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES;
childCB->processStatus |= OS_PROCESS_FLAG_UNUSED;
childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES;//去掉僵死标签
childCB->processStatus |= OS_PROCESS_FLAG_UNUSED;//贴上没使用标签,进程由进程池分配,进程退出后重新回到空闲进程池
}
LOS_ListDelete(&childCB->pendList);
LOS_ListDelete(&childCB->pendList);//将自己从阻塞链表上摘除
if (childCB->processStatus & OS_PROCESS_FLAG_EXIT) {
LOS_ListHeadInsert(&g_processRecycleList, &childCB->pendList);
LOS_ListHeadInsert(&g_processRecycleList, &childCB->pendList);//从头部插入注意g_processRecyleList挂的是pendList节点,所以要通过OS_PCB_FROM_PENDLIST找.
} else if (childCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) {
LOS_ListTailInsert(&g_processRecycleList, &childCB->pendList);
LOS_ListTailInsert(&g_processRecycleList, &childCB->pendList);//从尾部插入
} else {
OsInsertPCBToFreeList(childCB);
OsInsertPCBToFreeList(childCB);//直接插到freeList中去可用于重新分配了。
}
}
/*! 当一个进程自然退出的时候,它的孩子进程由两位老祖宗收养 */
STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
{
UINT32 parentID;
@ -401,20 +406,20 @@ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
LOS_DL_LIST *nextList = NULL;
LOS_DL_LIST *childHead = NULL;
if (!LOS_ListEmpty(&processCB->childrenList)) {
childHead = processCB->childrenList.pstNext;
LOS_ListDelete(&(processCB->childrenList));
if (OsProcessIsUserMode(processCB)) {
if (!LOS_ListEmpty(&processCB->childrenList)) {//如果存在孩子进程
childHead = processCB->childrenList.pstNext;//获取孩子链表
LOS_ListDelete(&(processCB->childrenList));//清空自己的孩子链表
if (OsProcessIsUserMode(processCB)) {//是用户态进程
parentID = g_userInitProcess;
} else {
parentID = g_kernelInitProcess;
}
for (nextList = childHead; ;) {
childCB = OS_PCB_FROM_SIBLIST(nextList);
for (nextList = childHead; ;) {//遍历孩子链表
childCB = OS_PCB_FROM_SIBLIST(nextList);//找到孩子的真身//找到孩子的真身
childCB->parentProcessID = parentID;
nextList = nextList->pstNext;
if (nextList == childHead) {
nextList = nextList->pstNext;//找下一个孩子进程
if (nextList == childHead) {//所以孩子都完成操作
break;
}
}
@ -425,22 +430,23 @@ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
return;
}
/*! 回收指定进程的已经退出的孩子进程所占资源 */
STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB)
{
LosProcessCB *childCB = NULL;
ProcessGroup *group = NULL;
while (!LOS_ListEmpty(&((LosProcessCB *)processCB)->exitChildList)) {
childCB = LOS_DL_LIST_ENTRY(processCB->exitChildList.pstNext, LosProcessCB, siblingList);
OsRecycleZombiesProcess(childCB, &group);
while (!LOS_ListEmpty(&((LosProcessCB *)processCB)->exitChildList)) {//遍历直到没有了退出的孩子进程
childCB = LOS_DL_LIST_ENTRY(processCB->exitChildList.pstNext, LosProcessCB, siblingList);//获取孩子进程
OsRecycleZombiesProcess(childCB, &group);//其中会将childCB从exitChildList链表上摘出去
(VOID)LOS_MemFree(m_aucSysMem1, group);
}
}
STATIC VOID OsProcessNaturalExit(LosTaskCB *runTask, UINT32 status)
{
LosProcessCB *processCB = OS_PCB_FROM_PID(runTask->processID);
LosProcessCB *processCB = OS_PCB_FROM_PID(runTask->processID);//释放孩子进程的资源
LosProcessCB *parentCB = NULL;
LOS_ASSERT(processCB->processStatus & OS_PROCESS_STATUS_RUNNING);
@ -475,26 +481,26 @@ STATIC VOID OsProcessNaturalExit(LosTaskCB *runTask, UINT32 status)
LOS_Panic("pid : %u is the root process exit!\n", processCB->processID);
return;
}
/*! 进程模块初始化,被编译放在代码段 .init 中*/
STATIC UINT32 OsProcessInit(VOID)
{
UINT32 index;
UINT32 size;
g_processMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT;
g_processMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT;//默认支持64个进程
size = g_processMaxNum * sizeof(LosProcessCB);
g_processCBArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size);
g_processCBArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size);// 进程池,占用内核堆,内存池分配
if (g_processCBArray == NULL) {
return LOS_NOK;
}
(VOID)memset_s(g_processCBArray, size, 0, size);
(VOID)memset_s(g_processCBArray, size, 0, size);//安全方式重置清0
LOS_ListInit(&g_freeProcess);
LOS_ListInit(&g_processRecycleList);
LOS_ListInit(&g_freeProcess);//进程空闲链表初始化创建一个进程时从g_freeProcess中申请一个进程描述符使用
LOS_ListInit(&g_processRecycleList);//进程回收链表初始化,回收完成后进入g_freeProcess等待再次被申请使用
for (index = 0; index < g_processMaxNum; index++) {
g_processCBArray[index].processID = index;
for (index = 0; index < g_processMaxNum; index++) {//进程池循环创建
g_processCBArray[index].processID = index;//进程ID[0-g_processMaxNum-1]赋值
g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED;
LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList);
}
@ -510,16 +516,16 @@ STATIC UINT32 OsProcessInit(VOID)
return LOS_OK;
}
/*! 进程回收再利用过程*/
LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
{
UINT32 intSave;
LosProcessCB *processCB = NULL;
SCHEDULER_LOCK(intSave);
while (!LOS_ListEmpty(&g_processRecycleList)) {
while (!LOS_ListEmpty(&g_processRecycleList)) {//循环任务回收链表,直到为空
processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_processRecycleList));
if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) {
if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) {//进程没有退出标签
break;
}
SCHEDULER_UNLOCK(intSave);
@ -530,32 +536,32 @@ LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT;
#ifdef LOSCFG_KERNEL_VM
LosVmSpace *space = NULL;
if (OsProcessIsUserMode(processCB)) {
space = processCB->vmSpace;
if (OsProcessIsUserMode(processCB)) {//进程是否是用户态进程
space = processCB->vmSpace;//只有用户态的进程才需要释放虚拟内存空间
}
processCB->vmSpace = NULL;
#endif
/* OS_PROCESS_FLAG_GROUP_LEADER: The lead process group cannot be recycled without destroying the PCB.
* !OS_PROCESS_FLAG_UNUSED: Parent process does not reclaim child process resources.
*/
LOS_ListDelete(&processCB->pendList);
LOS_ListDelete(&processCB->pendList);//将进程从进程链表上摘除
if ((processCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) ||
(processCB->processStatus & OS_PROCESS_STATUS_ZOMBIES)) {
LOS_ListTailInsert(&g_processRecycleList, &processCB->pendList);
LOS_ListTailInsert(&g_processRecycleList, &processCB->pendList);//将进程挂到进程回收链表上,
} else {
/* Clear the bottom 4 bits of process status */
OsInsertPCBToFreeList(processCB);
OsInsertPCBToFreeList(processCB);//进程回到可分配池中,再分配利用
}
SCHEDULER_UNLOCK(intSave);
#ifdef LOSCFG_KERNEL_VM
(VOID)LOS_VmSpaceFree(space);
(VOID)LOS_VmSpaceFree(space);//释放用户态进程的虚拟内存空间,因为内核只有一个虚拟空间,因此不需要释放虚拟空间.
#endif
SCHEDULER_LOCK(intSave);
}
SCHEDULER_UNLOCK(intSave);
}
/*! 删除PCB块 其实是 PCB块回归进程池,先进入回收链表*/
STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
{
UINT32 intSave;
@ -565,11 +571,11 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
return;
}
OsProcessResourcesToFree(processCB);
OsProcessResourcesToFree(processCB);//释放进程所占用的资源
SCHEDULER_LOCK(intSave);
if (processCB->parentProcessID != OS_INVALID_VALUE) {
LOS_ListDelete(&processCB->siblingList);
LOS_ListDelete(&processCB->siblingList);//将进程从兄弟链表中摘除
processCB->parentProcessID = OS_INVALID_VALUE;
}
@ -577,8 +583,8 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
OsExitProcessGroup(processCB, &group);
}
processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;
processCB->processStatus |= OS_PROCESS_FLAG_EXIT;
processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;//设置进程状态为非初始化
processCB->processStatus |= OS_PROCESS_FLAG_EXIT;//设置进程状态为退出
LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList);
SCHEDULER_UNLOCK(intSave);
@ -586,7 +592,7 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
OsWriteResourceEvent(OS_RESOURCE_EVENT_FREE);
return;
}
/*! 设置进程的名字*/
UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name)
{
errno_t errRet;
@ -618,29 +624,28 @@ UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name)
}
return LOS_OK;
}
/*! 初始化PCB(进程控制块)*/
STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, const CHAR *name)
{
processCB->processMode = mode;
processCB->processStatus = OS_PROCESS_STATUS_INIT;
processCB->parentProcessID = OS_INVALID_VALUE;
processCB->threadGroupID = OS_INVALID_VALUE;
processCB->priority = priority;
processCB->umask = OS_PROCESS_DEFAULT_UMASK;
processCB->processMode = mode; //用户态进程还是内核态进程
processCB->processStatus = OS_PROCESS_STATUS_INIT; //进程初始状态
processCB->parentProcess = NULL;
processCB->threadGroup = NULL;
processCB->umask = OS_PROCESS_DEFAULT_UMASK; //掩码
processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
LOS_ListInit(&processCB->threadSiblingList);
LOS_ListInit(&processCB->childrenList);
LOS_ListInit(&processCB->exitChildList);
LOS_ListInit(&(processCB->waitList));
LOS_ListInit(&processCB->threadSiblingList);//初始化孩子任务/线程链表上面挂的都是由此fork的孩子线程 见于 OsTaskCBInit LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList));
LOS_ListInit(&processCB->childrenList); //初始化孩子进程链表上面挂的都是由此fork的孩子进程 见于 OsCopyParent LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);
LOS_ListInit(&processCB->exitChildList); //初始化记录退出孩子进程链表上面挂的是哪些exit 见于 OsProcessNaturalExit LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList);
LOS_ListInit(&(processCB->waitList)); //初始化等待任务链表 上面挂的是处于等待的 见于 OsWaitInsertWaitLIstInOrder LOS_ListHeadInsert(&processCB->waitList, &runTask->pendList);
#ifdef LOSCFG_KERNEL_VM
if (OsProcessIsUserMode(processCB)) {
processCB->vmSpace = OsCreateUserVmSpace();
if (OsProcessIsUserMode(processCB)) {//如果是用户态进程
processCB->vmSpace = OsCreateUserVmSpace();//创建用户空间
if (processCB->vmSpace == NULL) {
processCB->processStatus = OS_PROCESS_FLAG_UNUSED;
return LOS_ENOMEM;
}
}//在鸿蒙内核态进程只有kprocess 和 kidle 两个
} else {
processCB->vmSpace = LOS_GetKVmSpace();
}
@ -653,7 +658,7 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, c
}
#endif
#ifdef LOSCFG_SECURITY_CAPABILITY
OsInitCapability(processCB);
OsInitCapability(processCB);//初始化进程安全相关功能
#endif
if (OsSetProcessName(processCB, name) != LOS_OK) {
@ -662,10 +667,10 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, c
return LOS_OK;
}
//创建用户
#ifdef LOSCFG_SECURITY_CAPABILITY
STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)
{
STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)//参数size 表示组数量
{ //(size - 1) * sizeof(UINT32) 用于 user->groups[..],这种设计节约了内存,不造成不需要的浪费
User *user = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + (size - 1) * sizeof(UINT32));
if (user == NULL) {
return NULL;
@ -675,11 +680,11 @@ STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)
user->effUserID = userID;
user->gid = gid;
user->effGid = gid;
user->groupNumber = size;
user->groups[0] = gid;
user->groupNumber = size;//用户组数量
user->groups[0] = gid; //用户组列表,一个用户可以属于多个用户组
return user;
}
/*! 检查参数群组ID是否在当前用户所属群组中*/
LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid)
{
UINT32 intSave;
@ -687,8 +692,8 @@ LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid)
User *user = NULL;
SCHEDULER_LOCK(intSave);
user = OsCurrUserGet();
for (count = 0; count < user->groupNumber; count++) {
user = OsCurrUserGet();//当前进程所属用户
for (count = 0; count < user->groupNumber; count++) {//循环对比
if (user->groups[count] == gid) {
SCHEDULER_UNLOCK(intSave);
return TRUE;
@ -699,7 +704,7 @@ LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid)
return FALSE;
}
#endif
/*! 获取当前进程的用户ID*/
LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID)
{
#ifdef LOSCFG_SECURITY_CAPABILITY
@ -714,7 +719,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID)
return 0;
#endif
}
/*! 获取当前进程的用户组ID*/
LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID)
{
#ifdef LOSCFG_SECURITY_CAPABILITY
@ -730,7 +735,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID)
return 0;
#endif
}
/*! 进程创建初始化*/
STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name, UINT16 priority)
{
ProcessGroup *group = NULL;
@ -777,7 +782,7 @@ EXIT:
OsDeInitPCB(processCB);
return ret;
}
/*! 创建2,0号进程,即内核态进程的老祖宗*/
LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID)
{
UINT32 ret = OsProcessInit();
@ -791,13 +796,13 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID)
return ret;
}
kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT;
kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT;//去掉初始化标签
g_processGroup = kerInitProcess->group;
LOS_ListInit(&g_processGroup->groupList);
OsCurrProcessSet(kerInitProcess);
LosProcessCB *idleProcess = OS_PCB_FROM_PID(g_kernelIdleProcess);
ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, OS_TASK_PRIORITY_LOWEST, "KIdle");
ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, OS_TASK_PRIORITY_LOWEST, "KIdle");//创建内核态0号进程
if (ret != LOS_OK) {
return ret;
}
@ -820,7 +825,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID)
return LOS_OK;
}
/// 进程调度参数检查
STATIC INLINE INT32 OsProcessSchedlerParamCheck(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
{
if (OS_PID_CHECK_INVALID(pid)) {

@ -40,7 +40,7 @@
#ifdef LOSCFG_KERNEL_SMP
STATIC struct SmpOps *g_smpOps = NULL;
/// 多核中次级CPU核初始化,每个核都会调用一次
STATIC VOID OsSmpSecondaryInit(VOID *arg)
{
UNUSED(arg);
@ -60,7 +60,7 @@ STATIC VOID OsSmpSecondaryInit(VOID *arg)
OsSchedStart();
}
/// 设置多核操作接口, 通过外部注册
VOID LOS_SmpOpsSet(struct SmpOps *ops)
{
g_smpOps = ops;

@ -1,4 +1,67 @@
/*
/*!
* @file los_swtmr.c
* @brief
* @details
* @attention @verbatim
TickTick
Tick
使
TickHuawei LiteOS
TickTick
TickTick
Tick
OS_SWTMR_STATUS_UNUSED使
OS_SWTMR_STATUS_TICKING
LOS_SwtmrStart
OS_SWTMR_STATUS_CREATED
使
make menuconfig
LOS_SwtmrCreate
LOS_SwtmrStart
TickLOS_SwtmrTimeGet
LOS_SwtmrStop
LOS_SwtmrDelete
使
使
使0
使使
使
Tick
@endverbatim
CSDN
*//*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
@ -54,9 +117,9 @@ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);
LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID)
{
SwtmrHandlerItemPtr swtmrHandlePtr = NULL;
SwtmrHandlerItem swtmrHandle;
UINT32 ret, swtmrHandlerQueue;
SwtmrHandlerItemPtr swtmrHandlePtr = NULL;///< 初始化软时钟自旋锁,只有SMP情况才需要,只要是自旋锁都是用于CPU多核的同步
SwtmrHandlerItem swtmrHandle;///< 持有软时钟自旋锁
UINT32 ret, swtmrHandlerQueue;///< 释放软时钟自旋锁
swtmrHandlerQueue = OsPercpuGet()->swtmrHandlerQueue;
for (;;) {
@ -71,23 +134,24 @@ LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID)
}
}
}
///创建软时钟任务,每个cpu core都可以拥有自己的软时钟任务
LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID)
{
UINT32 ret, swtmrTaskID;
TSK_INIT_PARAM_S swtmrTask;
UINT32 cpuid = ArchCurrCpuid();
(VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsSwtmrTask;
swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
swtmrTask.pcName = "Swt_Task";
(VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//清0
swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsSwtmrTask;//入口函数
swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16K默认内核任务栈
swtmrTask.pcName = "Swt_Task";//任务名称
swtmrTask.usTaskPrio = 0;
swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;
#ifdef LOSCFG_KERNEL_SMP
swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);
swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);//交给当前CPU执行这个任务
#endif
ret = LOS_TaskCreate(&swtmrTaskID, &swtmrTask);
ret = LOS_TaskCreate(&swtmrTaskID, &swtmrTask);//创建任务并申请调度
if (ret == LOS_OK) {
g_percpu[cpuid].swtmrTaskID = swtmrTaskID;
OS_TCB_FROM_TID(swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;
@ -95,7 +159,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID)
return ret;
}
///回收指定进程的软时钟
LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID)
{
for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {
@ -104,7 +168,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID)
}
}
}
///软时钟初始化 ,注意函数在多CPU情况下会执行多次
LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
{
UINT32 size;
@ -121,16 +185,15 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
goto ERROR;
}
(VOID)memset_s(swtmr, size, 0, size);
g_swtmrCBArray = swtmr;
LOS_ListInit(&g_swtmrFreeList);
(VOID)memset_s(swtmr, size, 0, size);//清0
g_swtmrCBArray = swtmr;//软时钟
LOS_ListInit(&g_swtmrFreeList);//初始化空闲链表
for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
swtmr->usTimerID = index;
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);
swtmr->usTimerID = index;//按顺序赋值
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//通过sortLinkNode将节点挂到空闲链表
}
swtmrHandlePoolSize = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);
//想要用静态内存池管理,就必须要使用LOS_MEMBOX_SIZE来计算申请的内存大小,因为需要点前缀内存承载头部信息.
swtmrHandlePoolSize = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//规划一片内存区域作为软时钟处理函数的静态内存池。
g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, swtmrHandlePoolSize); /* system resident resource */
if (g_swtmrHandlerPool == NULL) {
ret = LOS_ERRNO_SWTMR_NO_MEMORY;
@ -314,7 +377,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr)
{
return OsSortLinkGetTargetExpireTime(&swtmr->stSortList);
}
///创建定时器设置定时器的定时时长、定时器模式、回调函数并返回定时器ID
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
UINT8 mode,
SWTMR_PROC_FUNC handler,
@ -354,19 +417,19 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
SWTMR_UNLOCK(intSave);
swtmr->uwOwnerPid = OsCurrProcessGet()->processID;
swtmr->pfnHandler = handler;
swtmr->ucMode = mode;
swtmr->pfnHandler = handler;//时间到了的回调函数
swtmr->ucMode = mode; //定时器模式
swtmr->uwOverrun = 0;
swtmr->uwInterval = interval;
swtmr->uwExpiry = interval;
swtmr->uwArg = arg;
swtmr->ucState = OS_SWTMR_STATUS_CREATED;
swtmr->uwInterval = interval; //周期性超时间隔
swtmr->uwExpiry = interval; //一次性超时间隔
swtmr->uwArg = arg; //回调函数的参数
swtmr->ucState = OS_SWTMR_STATUS_CREATED; //已创建状态
SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME);
*swtmrID = swtmr->usTimerID;
OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr);
return LOS_OK;
}
///接口函数 启动定时器 参数定时任务ID
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -379,24 +442,24 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
}
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID;
swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) {
if (swtmr->usTimerID != swtmrID) {//ID必须一样
SWTMR_UNLOCK(intSave);
return LOS_ERRNO_SWTMR_ID_INVALID;
}
switch (swtmr->ucState) {
switch (swtmr->ucState) {//判断定时器状态
case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED;
break;
/*
/*如果定时器的状态为启动中,应先停止定时器再重新启动
* If the status of swtmr is timing, it should stop the swtmr first,
* then start the swtmr again.
*/
case OS_SWTMR_STATUS_TICKING:
OsSwtmrStop(swtmr);
case OS_SWTMR_STATUS_TICKING://正在计数的定时器
OsSwtmrStop(swtmr);//先停止定时器,注意这里没有break;,在OsSwtmrStop中状态将会回到了OS_SWTMR_STATUS_CREATED 接下来就是执行启动了
/* fall-through */
case OS_SWTMR_STATUS_CREATED:
swtmr->startTime = OsGetCurrSchedTimeCycle();
@ -411,7 +474,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr);
return ret;
}
///接口函数 停止定时器 参数定时任务ID
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -424,7 +487,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
}
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID;
swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) {
@ -432,15 +495,15 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
return LOS_ERRNO_SWTMR_ID_INVALID;
}
switch (swtmr->ucState) {
switch (swtmr->ucState) {//判断定时器状态
case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED;
ret = LOS_ERRNO_SWTMR_NOT_CREATED;//返回没有创建
break;
case OS_SWTMR_STATUS_CREATED:
ret = LOS_ERRNO_SWTMR_NOT_STARTED;
ret = LOS_ERRNO_SWTMR_NOT_STARTED;//返回没有开始
break;
case OS_SWTMR_STATUS_TICKING:
OsSwtmrStop(swtmr);
case OS_SWTMR_STATUS_TICKING:/
SwtmrStop(swtmr);//执行正在停止定时器操作
break;
default:
ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
@ -451,7 +514,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr);
return ret;
}
///接口函数 获得软件定时器剩余Tick数 通过 *tick 带走
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -492,7 +555,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
SWTMR_UNLOCK(intSave);
return ret;
}
///接口函数 删除定时器
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -517,7 +580,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED;
break;
case OS_SWTMR_STATUS_TICKING:
case OS_SWTMR_STATUS_TICKING://正在计数就先停止再删除,这里没有break;
OsSwtmrStop(swtmr);
/* fall-through */
case OS_SWTMR_STATUS_CREATED:

@ -29,44 +29,76 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
LOS_TickCountGet()OsGetCurrSchedTimeCycle()
LOS_CyclePerTickGet()
LOS_MS2Tick()
LOS_Tick2MS()
OsNS2Tick()1
*/
#include "los_sys_pri.h"
#include "los_sched_pri.h"
// 定义最大值
#define OS_MAX_VALUE 0xFFFFFFFFUL
// 获取当前的系统节拍数
LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID)
{
// 调用内部函数获取当前调度时间周期并除以每个节拍的周期数,得到节拍数
return OsGetCurrSchedTimeCycle() / OS_CYCLE_PER_TICK;
}
// 获取每个节拍的周期数
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CyclePerTickGet(VOID)
{
// 返回系统时钟频率除以每秒节拍数,得到每个节拍的周期数
return g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND;
}
// 将毫秒转换为节拍数
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec)
{
// 如果毫秒数等于最大值,直接返回最大值
if (millisec == OS_MAX_VALUE) {
return OS_MAX_VALUE;
}
// 将毫秒数乘以每秒节拍数,再除以每秒毫秒数,得到节拍数
return ((UINT64)millisec * LOSCFG_BASE_CORE_TICK_PER_SECOND) / OS_SYS_MS_PER_SECOND;
}
// 将节拍数转换为毫秒
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_Tick2MS(UINT32 tick)
{
// 将节拍数乘以每秒毫秒数,再除以每秒节拍数,得到毫秒数
return ((UINT64)tick * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND;
}
// 将纳秒转换为节拍数
LITE_OS_SEC_TEXT_MINOR UINT32 OsNS2Tick(UINT64 nanoseconds)
{
// 每个节拍的纳秒数
const UINT32 nsPerTick = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND;
// 将纳秒数加上每个节拍的纳秒数减1再除以每个节拍的纳秒数得到节拍数
UINT64 ticks = (nanoseconds + nsPerTick - 1) / nsPerTick;
// 如果节拍数超过最大值,将其设置为最大值
if (ticks > OS_MAX_VALUE) {
ticks = OS_MAX_VALUE;
}
// 将节拍数转换为32位整数并返回
return (UINT32)ticks;
}

File diff suppressed because it is too large Load Diff

@ -29,6 +29,22 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
g_sysClock
g_tickPerSecond
g_cycle2NsScale
g_tickSpin访
OsTickHandler()VDSOOsSchedTick()
*/
#include "los_tick_pri.h"
#include "los_swtmr_pri.h"
#include "los_sched_pri.h"
@ -36,17 +52,22 @@
#include "los_vdso.h"
#endif
// 系统时钟频率
LITE_OS_SEC_DATA_INIT UINT32 g_sysClock;
// 每秒节拍数
LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond;
// 循环周期到纳秒的缩放比例
LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale;
/* spinlock for task module */
// 任务模块的自旋锁
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin);
/*
* Description : Tick interruption handler
*/
// 节拍中断处理函数
LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
{
#ifdef LOSCFG_SCHED_TICK_DEBUG
@ -61,6 +82,10 @@ LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
HalClockIrqClear(); /* diff from every platform */
#endif
// 调度器的节拍处理函数
OsSchedTick();
}

File diff suppressed because it is too large Load Diff

@ -118,7 +118,256 @@ STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID)
*idleCpuID = cpuID;
}
cpuID++;
cpuID++;/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 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 "los_sortlink_pri.h"
#include "los_memory.h"
#include "los_exc.h"
#include "los_percpu_pri.h"
#include "los_sched_pri.h"
#include "los_mp.h"
UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
{
LOS_ListInit(&sortLinkHeader->sortLink); // 初始化排序链表头
sortLinkHeader->nodeNum = 0; // 初始化节点数量为0
return LOS_OK;
}
STATIC INLINE VOID OsAddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
{
LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; // 获取排序链表头指针
if (LOS_ListEmpty(head)) { // 如果链表为空
LOS_ListHeadInsert(head, &sortList->sortLinkNode); // 将节点插入链表头
sortLinkHeader->nodeNum++; // 节点数量加1
return;
}
SortLinkList *listSorted = LOS_DL_LIST_ENTRY(head->pstNext, SortLinkList, sortLinkNode); // 获取链表中的第一个节点
if (listSorted->responseTime > sortList->responseTime) { // 如果插入节点的响应时间小于第一个节点的响应时间
LOS_ListAdd(head, &sortList->sortLinkNode); // 将节点插入链表头之前
sortLinkHeader->nodeNum++; // 节点数量加1
return;
} else if (listSorted->responseTime == sortList->responseTime) { // 如果插入节点的响应时间等于第一个节点的响应时间
LOS_ListAdd(head->pstNext, &sortList->sortLinkNode); // 将节点插入第一个节点之后
sortLinkHeader->nodeNum++; // 节点数量加1
return;
}
LOS_DL_LIST *prevNode = head->pstPrev; // 获取链表中的最后一个节点
do {
listSorted = LOS_DL_LIST_ENTRY(prevNode, SortLinkList, sortLinkNode); // 获取当前节点
if (listSorted->responseTime <= sortList->responseTime) { // 如果插入节点的响应时间小于等于当前节点的响应时间
LOS_ListAdd(prevNode, &sortList->sortLinkNode); // 将节点插入当前节点之前
sortLinkHeader->nodeNum++; // 节点数量加1
break;
}
prevNode = prevNode->pstPrev; // 继续向前遍历
} while (1);
}
/*OsSortLinkInit函数用于初始化排序链表头。在函数中它调用LOS_ListInit函数初始化排序链表头并将节点数量设置为0然后返回LOS_OK。
OsAddNode2SortLink
退*/
VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
{
LOS_ListDelete(&sortList->sortLinkNode); // 从排序链表中删除节点
SET_SORTLIST_VALUE(sortList, OS_SORT_LINK_INVALID_TIME); // 将节点的响应时间设置为无效值
sortLinkHeader->nodeNum--; // 节点数量减1
}
STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, UINT64 startTime)
{
LOS_DL_LIST *head = &sortHeader->sortLink; // 获取排序链表头指针
LOS_DL_LIST *list = head->pstNext; // 获取链表中的第一个节点
if (LOS_ListEmpty(head)) { // 如果链表为空
return OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; // 返回最大响应时间减去精度
}
SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode); // 获取第一个节点
if (listSorted->responseTime <= (startTime + OS_TICK_RESPONSE_PRECISION)) { // 如果第一个节点的响应时间小于等于(开始时间加上精度)
return startTime + OS_TICK_RESPONSE_PRECISION; // 返回开始时间加上精度
}
return listSorted->responseTime; // 返回第一个节点的响应时间
}
STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID)
{
Percpu *idleCpu = OsPercpuGetByID(0); // 获取CPU 0 的PerCPU结构体指针
*idleCpuID = 0; // 将空闲CPU的ID设置为0
/*OsDeleteNodeSortLink函数用于从排序链表中删除节点。在函数中它调用LOS_ListDelete函数删除节点并将节点的响应时间设置为无效值然后将节点数量减1。
OsGetSortLinkNextExpireTime
OsFindIdleCpuCPUOsPercpuGetByIDCPU 0 PerCPUCPUID0*/
#ifdef LOSCFG_KERNEL_SMP
UINT16 cpuID = 1; // 初始化CPU ID为1
UINT32 nodeNum = idleCpu->taskSortLink.nodeNum + idleCpu->swtmrSortLink.nodeNum; // 获取当前CPU的任务排序链表和软件定时器排序链表的节点数量之和
do {
Percpu *cpu = OsPercpuGetByID(cpuID); // 获取指定CPU的PerCPU结构体指针
UINT32 temp = cpu->taskSortLink.nodeNum + cpu->swtmrSortLink.nodeNum; // 获取指定CPU的任务排序链表和软件定时器排序链表的节点数量之和
if (nodeNum > temp) { // 如果当前CPU的节点数量之和大于指定CPU的节点数量之和
idleCpu = cpu; // 更新空闲CPU指针
*idleCpuID = cpuID; // 更新空闲CPU的ID
}
cpuID++; // 继续遍历下一个CPU
} while (cpuID < LOSCFG_KERNEL_CORE_NUM); // 遍历完所有的CPU
#endif
return idleCpu; // 返回空闲CPU的指针
}
VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, SortLinkType type)
{
UINT32 intSave;
Percpu *cpu = NULL;
SortLinkAttribute *sortLinkHeader = NULL;
SPIN_LOCK_S *spinLock = NULL;
UINT16 idleCpu;
if (OS_SCHEDULER_ACTIVE) { // 如果调度器处于活动状态
cpu = OsFindIdleCpu(&idleCpu); // 查找空闲的CPU
} else {
idleCpu = ArchCurrCpuid(); // 获取当前CPU的ID
cpu = OsPercpuGet(); // 获取当前CPU的PerCPU结构体指针
}
if (type == OS_SORT_LINK_TASK) {
sortLinkHeader = &cpu->taskSortLink; // 获取任务排序链表头指针
spinLock = &cpu->taskSortLinkSpin; // 获取任务排序链表自旋锁
} else if (type == OS_SORT_LINK_SWTMR) {
sortLinkHeader = &cpu->swtmrSortLink; // 获取软件定时器排序链表头指针
spinLock = &cpu->swtmrSortLinkSpin; // 获取软件定时器排序链表自旋锁
} else {
LOS_Panic("Sort link type error : %u\n", type); // 报错,排序链表类型错误
}
LOS_SpinLockSave(spinLock, &intSave); // 保存自旋锁状态并禁止中断
SET_SORTLIST_VALUE(node, startTime + (UINT64)waitTicks * OS_CYCLE_PER_TICK); // 设置节点的响应时间
OsAddNode2SortLink(sortLinkHeader, node); // 将节点插入排序链表中
#ifdef LOSCFG_KERNEL_SMP
node->cpuid = idleCpu; // 设置节点的CPU ID为空闲CPU的ID
if (idleCpu != ArchCurrCpuid()) { // 如果空闲CPU的ID不等于当前CPU的ID
LOS_MpSchedule(CPUID_TO_AFFI_MASK(idleCpu)); // 调度空闲CPU执行任务
}
#endif
LOS_SpinUnlockRestore(spinLock, intSave); // 恢复自旋锁状态并允许中断
}
VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type)
{
UINT32 intSave;
#ifdef LOSCFG_KERNEL_SMP
Percpu *cpu = OsPercpuGetByID(node->cpuid); // 获取节点所在CPU的PerCPU结构体指针
#else
Percpu *cpu = OsPercpuGetByID(0); // 获取CPU 0 的PerCPU结构体指针
#endif
/*OsAdd2SortLink函数用于将节点插入排序链表中。在函数中首先根据调度器的活动状态选择空闲的CPU。
OsFindIdleCpuCPUCPUID
OsPercpuGetCPUPerCPU
SMPCPU ID
CPUIDCPUIDCPU
OsDeleteSortLinkSMP
CPU IDCPUPerCPUCPU 0 PerCPU*/
SPIN_LOCK_S *spinLock = NULL;
SortLinkAttribute *sortLinkHeader = NULL;
if (type == OS_SORT_LINK_TASK) {
sortLinkHeader = &cpu->taskSortLink; // 获取任务排序链表头指针
spinLock = &cpu->taskSortLinkSpin; // 获取任务排序链表自旋锁
} else if (type == OS_SORT_LINK_SWTMR) {
sortLinkHeader = &cpu->swtmrSortLink; // 获取软件定时器排序链表头指针
spinLock = &cpu->swtmrSortLinkSpin; // 获取软件定时器排序链表自旋锁
} else {
LOS_Panic("Sort link type error : %u\n", type); // 报错,排序链表类型错误
}
LOS_SpinLockSave(spinLock, &intSave); // 保存自旋锁状态并禁止中断
if (node->responseTime != OS_SORT_LINK_INVALID_TIME) { // 如果节点的响应时间不为无效时间
OsDeleteNodeSortLink(sortLinkHeader, node); // 从排序链表中删除节点
}
LOS_SpinUnlockRestore(spinLock, intSave); // 恢复自旋锁状态并允许中断
}
UINT64 OsGetNextExpireTime(UINT64 startTime)
{
UINT32 intSave;
Percpu *cpu = OsPercpuGet(); // 获取当前CPU的PerCPU结构体指针
SortLinkAttribute *taskHeader = &cpu->taskSortLink; // 获取任务排序链表头指针
SortLinkAttribute *swtmrHeader = &cpu->swtmrSortLink; // 获取软件定时器排序链表头指针
LOS_SpinLockSave(&cpu->taskSortLinkSpin, &intSave); // 保存任务排序链表自旋锁状态并禁止中断
UINT64 taskExpirTime = OsGetSortLinkNextExpireTime(taskHeader, startTime); // 获取任务排序链表中下一个过期时间
LOS_SpinUnlockRestore(&cpu->taskSortLinkSpin, intSave); // 恢复任务排序链表自旋锁状态并允许中断
LOS_SpinLockSave(&cpu->swtmrSortLinkSpin, &intSave); // 保存软件定时器排序链表自旋锁状态并禁止中断
UINT64 swtmrExpirTime = OsGetSortLinkNextExpireTime(swtmrHeader, startTime); // 获取软件定时器排序链表中下一个过期时间
LOS_SpinUnlockRestore(&cpu->swtmrSortLinkSpin, intSave); // 恢复软件定时器排序链表自旋锁状态并允许中断
return (taskExpirTime < swtmrExpirTime) ? taskExpirTime : swtmrExpirTime; // 返回较小的过期时间
}
UINT32 OsSortLinkGetTargetExpireTime(const SortLinkList *targetSortList)
{
UINT64 currTimes = OsGetCurrSchedTimeCycle(); // 获取当前调度时间
if (currTimes >= targetSortList->responseTime) { // 如果当前时间大于等于目标排序链表节点的响应时间
return 0; // 返回0表示已经过期
}
return (UINT32)(targetSortList->responseTime - currTimes) / OS_CYCLE_PER_TICK; // 计算剩余的滴答数
}
UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader)
{
LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; // 获取排序链表头节点
if (LOS_ListEmpty(head)) { // 如果排序链表为空
return 0; // 返回0表示没有过期时间
}
SortLinkList *listSorted = LOS_DL_LIST_ENTRY(head->pstNext, SortLinkList, sortLinkNode); // 获取排序链表中的第一个节点
return OsSortLinkGetTargetExpireTime(listSorted); // 获取目标排序链表节点的过期时间
}
} while (cpuID < LOSCFG_KERNEL_CORE_NUM);
#endif

Binary file not shown.
Loading…
Cancel
Save