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

CPU的工作量是如何分配的, 读懂对 SortLinkList 的注解即可

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    博客输出站点(国内):http://weharmonyos.com
    博客输出站点(国外):https://weharmony.github.io
    注解文件系统:https://gitee.com/weharmony/third_party_NuttX
    注解协议栈:https://gitee.com/weharmony/third_party_lwip
    注解编译子系统:https://gitee.com/weharmony/build_lite
上级 aa36c1c9
...@@ -58,7 +58,7 @@ typedef enum { ...@@ -58,7 +58,7 @@ typedef enum {
* 这样做的好处是,在多处理器系统中,当处理器操作属于它的变量副本时,不需要考虑与其他处理器的竞争的问题, * 这样做的好处是,在多处理器系统中,当处理器操作属于它的变量副本时,不需要考虑与其他处理器的竞争的问题,
*/ */
typedef struct { typedef struct {
SortLinkAttribute taskSortLink; /*! task sort link | 挂等待和延时的任务 */ SortLinkAttribute taskSortLink; /*! task sort link | 挂等待和延时的任务,这些任务从任务就绪队列中来,等待最后CPU执行 */
SPIN_LOCK_S taskSortLinkSpin; ///< task sort link spin lock | 操作taskSortLink链表的自旋锁 SPIN_LOCK_S taskSortLinkSpin; ///< task sort link spin lock | 操作taskSortLink链表的自旋锁
SortLinkAttribute swtmrSortLink; ///< swtmr sort link | 挂还没到时间的定时器 SortLinkAttribute swtmrSortLink; ///< swtmr sort link | 挂还没到时间的定时器
SPIN_LOCK_S swtmrSortLinkSpin; ///< swtmr sort link spin lock |* 操作swtmrSortLink链表的自旋锁 SPIN_LOCK_S swtmrSortLinkSpin; ///< swtmr sort link spin lock |* 操作swtmrSortLink链表的自旋锁
...@@ -74,7 +74,7 @@ typedef struct { ...@@ -74,7 +74,7 @@ typedef struct {
#ifdef LOSCFG_KERNEL_SMP #ifdef LOSCFG_KERNEL_SMP
UINT32 excFlag; ///< cpu halt or exc flag | cpu 停止或 异常 标志 UINT32 excFlag; ///< cpu halt or exc flag | cpu 停止或 异常 标志
#ifdef LOSCFG_KERNEL_SMP_CALL #ifdef LOSCFG_KERNEL_SMP_CALL
LOS_DL_LIST funcLink; ///< mp function call link LOS_DL_LIST funcLink; ///< mp function call link | 回调函数
#endif #endif
#endif #endif
} Percpu; } Percpu;
......
...@@ -167,7 +167,7 @@ typedef struct ProcessCB { ...@@ -167,7 +167,7 @@ typedef struct ProcessCB {
* *
* The process is running. * The process is running.
*/ */
#define OS_PROCESS_STATUS_RUNNING 0x0040U ///< 进程运行状态 #define OS_PROCESS_STATUS_RUNNING 0x0040U ///< 进程状态: 运行中...
/** /**
* @ingroup los_process * @ingroup los_process
...@@ -175,7 +175,7 @@ typedef struct ProcessCB { ...@@ -175,7 +175,7 @@ typedef struct ProcessCB {
* *
* The process is pending * The process is pending
*/ */
#define OS_PROCESS_STATUS_PENDING 0x0080U #define OS_PROCESS_STATUS_PENDING 0x0080U ///< 进程状态: 挂起中... ,意思是进程还没开始,在等待其他条件成熟
/** /**
* @ingroup los_process * @ingroup los_process
...@@ -183,7 +183,7 @@ typedef struct ProcessCB { ...@@ -183,7 +183,7 @@ typedef struct ProcessCB {
* *
* The process is run out but the resources occupied by the process are not recovered. * The process is run out but the resources occupied by the process are not recovered.
*/ */
#define OS_PROCESS_STATUS_ZOMBIES 0x100U ///< 进程僵死状态 #define OS_PROCESS_STATUS_ZOMBIES 0x100U ///< 进程状态: 僵死
/** /**
* @ingroup los_process * @ingroup los_process
...@@ -239,9 +239,9 @@ typedef struct ProcessCB { ...@@ -239,9 +239,9 @@ typedef struct ProcessCB {
* Flag that indicates the process or process control block status. * Flag that indicates the process or process control block status.
* *
* The process is dying or already dying. * The process is dying or already dying.
*/ */ /// 进程不活跃状态定义: 身上贴有退出便签且状态为僵死的进程
#define OS_PROCESS_STATUS_INACTIVE (OS_PROCESS_FLAG_EXIT | OS_PROCESS_STATUS_ZOMBIES) #define OS_PROCESS_STATUS_INACTIVE (OS_PROCESS_FLAG_EXIT | OS_PROCESS_STATUS_ZOMBIES)
//进程不活跃状态定义: 身上贴有退出便签且状态为僵死的进程
/** /**
* @ingroup los_process * @ingroup los_process
* Used to check if the process control block is unused. * Used to check if the process control block is unused.
...@@ -254,44 +254,44 @@ STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB)//查下进 ...@@ -254,44 +254,44 @@ STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB)//查下进
/** /**
* @ingroup los_process * @ingroup los_process
* Used to check if the process is inactive. * Used to check if the process is inactive.
*/ */ /// 进程不活跃函数定义:身上贴有不使用且不活跃标签的进程
STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB)//查下进程是否不活跃? STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB)//查下进程是否不活跃?
{ {
return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_INACTIVE)) != 0); return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_INACTIVE)) != 0);
}//进程不活跃函数定义:身上贴有不使用且不活跃标签的进程 }
/** /**
* @ingroup los_process * @ingroup los_process
* Used to check if the process is dead. * Used to check if the process is dead.
*/ */ /// 进程死啦死啦的定义: 身上贴有不使用且状态为僵死的进程
STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB)//查下进程是否死啦死啦滴? STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB)//查下进程是否死啦死啦滴?
{ {
return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_ZOMBIES)) != 0); return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_ZOMBIES)) != 0);
}//进程死啦死啦的定义: 身上贴有不使用且状态为僵死的进程 }
/** /**
* @ingroup los_process * @ingroup los_process
* The highest priority of a kernel mode process. * The highest priority of a kernel mode process.
*/ */
#define OS_PROCESS_PRIORITY_HIGHEST 0 //进程最高优先级 #define OS_PROCESS_PRIORITY_HIGHEST 0 ///< 进程最高优先级
/** /**
* @ingroup los_process * @ingroup los_process
* The lowest priority of a kernel mode process * The lowest priority of a kernel mode process
*/ */
#define OS_PROCESS_PRIORITY_LOWEST 31 //进程最低优先级 #define OS_PROCESS_PRIORITY_LOWEST 31 ///< 进程最低优先级
/** /**
* @ingroup los_process * @ingroup los_process
* The highest priority of a user mode process. * The highest priority of a user mode process.
*/ */
#define OS_USER_PROCESS_PRIORITY_HIGHEST 10 //内核模式和用户模式的优先级分割线 10-31 用户级, 0-9内核级 #define OS_USER_PROCESS_PRIORITY_HIGHEST 10 ///< 内核模式和用户模式的优先级分割线 10-31 用户级, 0-9内核级
/** /**
* @ingroup los_process * @ingroup los_process
* The lowest priority of a user mode process * The lowest priority of a user mode process
*/ */
#define OS_USER_PROCESS_PRIORITY_LOWEST OS_PROCESS_PRIORITY_LOWEST //用户进程的最低优先级 #define OS_USER_PROCESS_PRIORITY_LOWEST OS_PROCESS_PRIORITY_LOWEST ///< 用户进程的最低优先级
/** /**
* @ingroup los_process * @ingroup los_process
...@@ -339,7 +339,7 @@ STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB) ...@@ -339,7 +339,7 @@ STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)
* | | exit code | core dump | signal | * | | exit code | core dump | signal |
*/ */
#define OS_PRO_EXIT_OK 0 ///< 进程正常退出 #define OS_PRO_EXIT_OK 0 ///< 进程正常退出
//置进程退出码第七位为1 /// 置进程退出码第七位为1
STATIC INLINE VOID OsProcessExitCodeCoreDumpSet(LosProcessCB *processCB) STATIC INLINE VOID OsProcessExitCodeCoreDumpSet(LosProcessCB *processCB)
{ {
processCB->exitCode |= 0x80U; // 0b10000000 processCB->exitCode |= 0x80U; // 0b10000000
......
...@@ -45,8 +45,8 @@ extern "C" { ...@@ -45,8 +45,8 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __cplusplus */ #endif /* __cplusplus */
#define OS_SCHED_MINI_PERIOD (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI) #define OS_SCHED_MINI_PERIOD (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI) ///< 1毫秒的时钟周期
#define OS_TICK_RESPONSE_PRECISION (UINT32)((OS_SCHED_MINI_PERIOD * 75) / 100) #define OS_TICK_RESPONSE_PRECISION (UINT32)((OS_SCHED_MINI_PERIOD * 75) / 100) ///< 不明白为啥是 * 75 就精确了??? @note_thinking
#define OS_SCHED_MAX_RESPONSE_TIME (UINT64)(((UINT64)-1) - 1U) #define OS_SCHED_MAX_RESPONSE_TIME (UINT64)(((UINT64)-1) - 1U)
extern UINT32 g_taskScheduled; extern UINT32 g_taskScheduled;
...@@ -62,17 +62,17 @@ STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID) ...@@ -62,17 +62,17 @@ STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID)
return 0; return 0;
} }
/// 更新中断使用时间
STATIC INLINE VOID OsSchedIrqUpdateUsedTime(VOID) STATIC INLINE VOID OsSchedIrqUpdateUsedTime(VOID)
{ {
LosTaskCB *runTask = OsCurrTaskGet(); LosTaskCB *runTask = OsCurrTaskGet();
runTask->irqUsedTime = OsGetCurrSchedTimeCycle() - runTask->irqStartTime; runTask->irqUsedTime = OsGetCurrSchedTimeCycle() - runTask->irqStartTime;//获取时间差
} }
/// 获取中断开始时间
STATIC INLINE VOID OsSchedIrqStartTime(VOID) STATIC INLINE VOID OsSchedIrqStartTime(VOID)
{ {
LosTaskCB *runTask = OsCurrTaskGet(); LosTaskCB *runTask = OsCurrTaskGet();
runTask->irqStartTime = OsGetCurrSchedTimeCycle(); runTask->irqStartTime = OsGetCurrSchedTimeCycle(); //获取当前时间
} }
/* /*
...@@ -87,12 +87,12 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID) ...@@ -87,12 +87,12 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID)
g_taskScheduled &= ~(1U << (cpuid)); \ g_taskScheduled &= ~(1U << (cpuid)); \
} while (0); } while (0);
#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))//用于判断当前cpu是否可调度 #define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))///< 用于判断当前cpu是否在调度中
typedef enum { typedef enum {
INT_NO_RESCH = 0x0, /* no needs to schedule */ INT_NO_RESCH = 0x0, /**< no needs to schedule | 不需要调度*/
INT_PEND_RESCH = 0x1, /* pending schedule flag */ INT_PEND_RESCH = 0x1, /**< pending schedule flag | 因不允许抢占或正在中断导致的不允许调度*/
INT_PEND_TICK = 0x2, /* pending tick */ INT_PEND_TICK = 0x2, /**< pending tick | 更新过期时间遇到正在中断导致的不允许调度*/
} SchedFlag; } SchedFlag;
/* Check if preemptable with counter flag */ /* Check if preemptable with counter flag */
...@@ -122,7 +122,7 @@ STATIC INLINE BOOL OsPreemptableInSched(VOID) ...@@ -122,7 +122,7 @@ STATIC INLINE BOOL OsPreemptableInSched(VOID)
#ifdef LOSCFG_KERNEL_SMP #ifdef LOSCFG_KERNEL_SMP
/* /*
* For smp systems, schedule must hold the task spinlock, and this counter * For smp systems, schedule must hold the task spinlock, and this counter
* will increase by 1 in that case. * will increase by 1 in that case. | 对于 smp ,调度必须持有任务自旋锁,在这种情况下,此计数器将增加 1。
*/ */
preemptable = (OsPercpuGet()->taskLockCnt == 1);//SMP时 taskLockCnt=1 才能执行调度任务 preemptable = (OsPercpuGet()->taskLockCnt == 1);//SMP时 taskLockCnt=1 才能执行调度任务
...@@ -130,18 +130,18 @@ STATIC INLINE BOOL OsPreemptableInSched(VOID) ...@@ -130,18 +130,18 @@ STATIC INLINE BOOL OsPreemptableInSched(VOID)
preemptable = (OsPercpuGet()->taskLockCnt == 0); preemptable = (OsPercpuGet()->taskLockCnt == 0);
#endif #endif
if (!preemptable) { if (!preemptable) {
/* Set schedule flag if preemption is disabled */ /* Set schedule flag if preemption is disabled | 如果禁用抢占,则设置调度标志*/
OsPercpuGet()->schedFlag |= INT_PEND_RESCH; OsPercpuGet()->schedFlag |= INT_PEND_RESCH;
} }
return preemptable; return preemptable;
} }
/// 申请CPU调度锁
STATIC INLINE VOID OsCpuSchedLock(Percpu *cpu) STATIC INLINE VOID OsCpuSchedLock(Percpu *cpu)
{ {
cpu->taskLockCnt++; cpu->taskLockCnt++;
} }
/// 释放CPU调度锁
STATIC INLINE VOID OsCpuSchedUnlock(Percpu *cpu, UINT32 intSave) STATIC INLINE VOID OsCpuSchedUnlock(Percpu *cpu, UINT32 intSave)
{ {
if (cpu->taskLockCnt > 0) { if (cpu->taskLockCnt > 0) {
......
...@@ -43,30 +43,30 @@ extern "C" { ...@@ -43,30 +43,30 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/*! \enum SortLinkType /*! \enum SortLinkType
* 因为任务和定时器都是吃CPU的,让CPU不停工作的主要就是这两宝贝. * @brief 因为任务和定时器都是吃CPU的,让CPU不停工作的主要就是这两宝贝.
*/ */
typedef enum { typedef enum {
OS_SORT_LINK_TASK = 1, ///< 任务排序 OS_SORT_LINK_TASK = 1, ///< 任务
OS_SORT_LINK_SWTMR = 2, ///< 定时器排序 OS_SORT_LINK_SWTMR = 2, ///< 定时器
} SortLinkType; } SortLinkType;
/*! \struct SortLinkList /*! \struct SortLinkList
* *
*/ */
typedef struct { typedef struct {
LOS_DL_LIST sortLinkNode; ///< 任务排序链表,注意上面挂的是一个个等待的任务 LOS_DL_LIST sortLinkNode; ///< 排序链表,注意上面挂的是一个个等待被执行的任务/软件定时器
UINT64 responseTime; ///< 响应时间 UINT64 responseTime; ///< 响应时间,注意是时间短的排在前面,见于 OsAddNode2SortLink 的实现
#ifdef LOSCFG_KERNEL_SMP #ifdef LOSCFG_KERNEL_SMP
UINT32 cpuid; ///< 需要哪个CPU处理 UINT32 cpuid; ///< 需要哪个CPU处理
#endif #endif
} SortLinkList; } SortLinkList;
/*! \struct SortLinkAttribute /*! \struct SortLinkAttribute
* * @brief 排序链表属性
*/ */
typedef struct { typedef struct {
LOS_DL_LIST sortLink; LOS_DL_LIST sortLink; ///< 排序链表,上面挂的任务/软件定时器
UINT32 nodeNum; UINT32 nodeNum; ///< 链表结点数量
} SortLinkAttribute; } SortLinkAttribute;
#define OS_SORT_LINK_INVALID_TIME ((UINT64)-1) #define OS_SORT_LINK_INVALID_TIME ((UINT64)-1)
......
...@@ -45,79 +45,78 @@ extern "C" { ...@@ -45,79 +45,78 @@ extern "C" {
* @ingroup los_sys * @ingroup los_sys
* Number of milliseconds in one second. * Number of milliseconds in one second.
*/ */
#define OS_SYS_MS_PER_SECOND 1000 //一秒多少毫秒 #define OS_SYS_MS_PER_SECOND 1000 ///< 一秒多少毫秒
/** /**
* @ingroup los_sys * @ingroup los_sys
* Number of microseconds in one second. * Number of microseconds in one second.
*/ */
#define OS_SYS_US_PER_SECOND 1000000 //一秒多少微秒 #define OS_SYS_US_PER_SECOND 1000000 ///< 一秒多少微秒
/** /**
* @ingroup los_sys * @ingroup los_sys
* Number of nanoseconds in one second. * Number of nanoseconds in one second.
*/ */
#define OS_SYS_NS_PER_SECOND 1000000000 //一秒多少纳秒 #define OS_SYS_NS_PER_SECOND 1000000000 ///< 一秒多少纳秒
/** /**
* @ingroup los_sys * @ingroup los_sys
* Number of microseconds in one milliseconds. * Number of microseconds in one milliseconds.
*/ */
#define OS_SYS_US_PER_MS 1000 //一毫秒都是微秒 #define OS_SYS_US_PER_MS 1000 ///< 一毫秒的微秒数
/** /**
* @ingroup los_sys * @ingroup los_sys
* Number of nanoseconds in one milliseconds. * Number of nanoseconds in one milliseconds.
*/ */
#define OS_SYS_NS_PER_MS 1000000 //一毫秒都是纳秒 #define OS_SYS_NS_PER_MS 1000000 ///< 一毫秒的纳秒数
/** /**
* @ingroup los_sys * @ingroup los_sys
* Number of nanoseconds in one microsecond. * Number of nanoseconds in one microsecond.
*/ */
#define OS_SYS_NS_PER_US 1000 //一微秒都是纳秒 #define OS_SYS_NS_PER_US 1000 ///< 一微秒的纳秒数
/** /**
* @ingroup los_sys * @ingroup los_sys
* Number of cycle in one tick. * Number of cycle in one tick.
*/ */
#define OS_CYCLE_PER_TICK (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND) #define OS_CYCLE_PER_TICK (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND) ///< 一个节拍的周期数
/** /**
* @ingroup los_sys * @ingroup los_sys
* Number of nanoseconds in one cycle. * Number of nanoseconds in one cycle.
*/ */
#define OS_NS_PER_CYCLE (OS_SYS_NS_PER_SECOND / OS_SYS_CLOCK) #define OS_NS_PER_CYCLE (OS_SYS_NS_PER_SECOND / OS_SYS_CLOCK) ///< 一周期的纳秒数
/** /**
* @ingroup los_sys * @ingroup los_sys
* Number of microseconds in one tick. * Number of microseconds in one tick.
*/ */
#define OS_US_PER_TICK (OS_SYS_US_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) #define OS_US_PER_TICK (OS_SYS_US_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) ///< 一个tick的微秒数
/** /**
* @ingroup los_sys * @ingroup los_sys
* Number of nanoseconds in one tick. * Number of nanoseconds in one tick.
*/ */
#define OS_NS_PER_TICK (OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) #define OS_NS_PER_TICK (OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) ///< 一个tick的纳秒数
/** /**
* @ingroup los_sys * @ingroup los_sys
* The maximum length of name. * The maximum length of name.
*/ */
#define OS_SYS_APPVER_NAME_MAX 64 //名字的最大长度 #define OS_SYS_APPVER_NAME_MAX 64 ///< 名字的最大长度
/** /**
* @ingroup los_sys * @ingroup los_sys
* The magic word. * The magic word.
*/ */
#define OS_SYS_MAGIC_WORD 0xAAAAAAAA //魔法数字,还记得栈顶的魔法数字是多少吗? 0xCCCCCCCC #define OS_SYS_MAGIC_WORD 0xAAAAAAAA ///< 魔法数字,还记得栈顶的魔法数字是多少吗? 0xCCCCCCCC
/** /**
* @ingroup los_sys * @ingroup los_sys
* The initialization value of stack space. * The initialization value of stack space.
*/ */
#define OS_SYS_EMPTY_STACK 0xCACACACA //栈的填充内容魔法数字 #define OS_SYS_EMPTY_STACK 0xCACACACA ///< 栈的填充内容魔法数字
/** /**
* @ingroup los_sys * @ingroup los_sys
......
...@@ -77,7 +77,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -77,7 +77,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* Null task ID * Null task ID
* *
*/ */
#define OS_TASK_ERRORID 0xFFFFFFFF #define OS_TASK_ERRORID 0xFFFFFFFF
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -93,7 +93,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -93,7 +93,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* Lowest task priority. * Lowest task priority.
*/ */
#define OS_TASK_PRIORITY_LOWEST 31 //任务最低优先级 #define OS_TASK_PRIORITY_LOWEST 31 ///< 任务最低优先级
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -101,7 +101,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -101,7 +101,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The task is init. * The task is init.
*/ */
#define OS_TASK_STATUS_INIT 0x0001U //初始化状态 #define OS_TASK_STATUS_INIT 0x0001U ///< 初始化状态
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -109,7 +109,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -109,7 +109,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The task is ready. * The task is ready.
*/ */
#define OS_TASK_STATUS_READY 0x0002U //就绪状态的任务都将插入就绪队列,注意就绪队列的本质是个双向链表 #define OS_TASK_STATUS_READY 0x0002U ///< 就绪状态的任务都将插入就绪队列,注意就绪队列的本质是个双向链表
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -117,7 +117,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -117,7 +117,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The task is running. * The task is running.
*/ */
#define OS_TASK_STATUS_RUNNING 0x0004U //运行状态 #define OS_TASK_STATUS_RUNNING 0x0004U ///< 任务状态: 运行中
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -125,7 +125,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -125,7 +125,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The task is suspended. * The task is suspended.
*/ */
#define OS_TASK_STATUS_SUSPENDED 0x0008U #define OS_TASK_STATUS_SUSPENDED 0x0008U ///< 任务状态: 暂停 ,意思是任务已经开始了, 不过现在要停了
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -133,7 +133,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -133,7 +133,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The task is blocked. * The task is blocked.
*/ */
#define OS_TASK_STATUS_PENDING 0x0010U #define OS_TASK_STATUS_PENDING 0x0010U ///< 任务状态: 挂起 ,意思是任务还没开始,在等待其他条件成熟
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -141,7 +141,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -141,7 +141,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The task is delayed. * The task is delayed.
*/ */
#define OS_TASK_STATUS_DELAY 0x0020U //延期状态 #define OS_TASK_STATUS_DELAY 0x0020U ///< 延期状态 ,见于 OsSchedDelay 延期调度
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -149,7 +149,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -149,7 +149,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The time for waiting for an event to occur expires. * The time for waiting for an event to occur expires.
*/ */
#define OS_TASK_STATUS_TIMEOUT 0x0040U //任务超时 #define OS_TASK_STATUS_TIMEOUT 0x0040U ///< 任务等待事件发生超时
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -157,10 +157,10 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -157,10 +157,10 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The task is pend for a period of time. * The task is pend for a period of time.
*/ */
#define OS_TASK_STATUS_PEND_TIME 0x0080U #define OS_TASK_STATUS_PEND_TIME 0x0080U ///< 任务状态: 挂起
#define OS_TASK_STATUS_BLOCKED (OS_TASK_STATUS_INIT | OS_TASK_STATUS_PENDING | \ #define OS_TASK_STATUS_BLOCKED (OS_TASK_STATUS_INIT | OS_TASK_STATUS_PENDING | \
OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME) OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME) ///< 任务状态: 屏蔽
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -168,7 +168,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -168,7 +168,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The task is exit. * The task is exit.
*/ */
#define OS_TASK_STATUS_EXIT 0x0100U #define OS_TASK_STATUS_EXIT 0x0100U ///< 任务状态:退出
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -176,7 +176,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -176,7 +176,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The task control block is unused. * The task control block is unused.
*/ */
#define OS_TASK_STATUS_UNUSED 0x0200U #define OS_TASK_STATUS_UNUSED 0x0200U ///< 任务状态:未使用
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -184,7 +184,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -184,7 +184,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The task is joinable. * The task is joinable.
*/ */
#define OS_TASK_FLAG_PTHREAD_JOIN 0x0400U //主task和子task连在一块不分离 #define OS_TASK_FLAG_PTHREAD_JOIN 0x0400U ///< 主task和子task连在一块不分离
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -192,15 +192,15 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -192,15 +192,15 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* The task is system-level task, like idle, swtmr and etc. * The task is system-level task, like idle, swtmr and etc.
*/ */
#define OS_TASK_FLAG_SYSTEM_TASK 0x1000U //系统任务 #define OS_TASK_FLAG_SYSTEM_TASK 0x1000U ///< 系统任务
/** /**
* @ingroup los_task * @ingroup los_task
* Flag that indicates the task property. * Flag that indicates the task property.
* *
* The task is no-delete system task, like resourceTask. //该任务是不可删除的系统任务,如资源回收任务 * The task is no-delete system task, like resourceTask.
*/ */
#define OS_TASK_FLAG_NO_DELETE 0x2000U #define OS_TASK_FLAG_NO_DELETE 0x2000U ///< 该任务是不可删除的系统任务,如资源回收任务
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -208,7 +208,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -208,7 +208,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* Kills the thread during process exit. * Kills the thread during process exit.
*/ */
#define OS_TASK_FLAG_EXIT_KILL 0x4000U //在进程退出期间一同被干掉的任务 #define OS_TASK_FLAG_EXIT_KILL 0x4000U ///< 在进程退出期间一同被干掉的任务
/** /**
* @ingroup los_task * @ingroup los_task
...@@ -216,26 +216,26 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -216,26 +216,26 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* *
* Specifies the process creation task. * Specifies the process creation task.
*/ */
#define OS_TASK_FLAG_SPECIFIES_PROCESS 0x0U //创建指定任务 例如: cat weharmony.net 实现 #define OS_TASK_FLAG_SPECIFIES_PROCESS 0x0U ///< 创建指定任务 例如: cat weharmony.net 实现
/** /**
* @ingroup los_task * @ingroup los_task
* Boundary on which the stack size is aligned. * Boundary on which the stack size is aligned.
* *
*/ */
#define OS_TASK_STACK_SIZE_ALIGN 16U //堆栈大小对齐的边界 #define OS_TASK_STACK_SIZE_ALIGN 16U ///< 堆栈大小对齐
/** /**
* @ingroup los_task * @ingroup los_task
* Boundary on which the stack address is aligned. * Boundary on which the stack address is aligned.
* *
*/ */
#define OS_TASK_STACK_ADDR_ALIGN 8U #define OS_TASK_STACK_ADDR_ALIGN 8U ///< 堆栈地址对齐
/** /**
* @ingroup los_task * @ingroup los_task
* Number of usable task priorities. * Number of usable task priorities. | 任务优先级数量
*/ //可用任务优先级的数量 */
#define OS_TSK_PRINUM (OS_TASK_PRIORITY_LOWEST - OS_TASK_PRIORITY_HIGHEST + 1) #define OS_TSK_PRINUM (OS_TASK_PRIORITY_LOWEST - OS_TASK_PRIORITY_HIGHEST + 1)
/** /**
...@@ -269,9 +269,9 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -269,9 +269,9 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* @par Dependency: * @par Dependency:
* <ul><li>los_task_pri.h: the header file that contains the API declaration.</li></ul> * <ul><li>los_task_pri.h: the header file that contains the API declaration.</li></ul>
* @see * @see
*/ */ ///通过pendList取出TCB,用于挂入链表节点时使用 pendList的情况
#define OS_TCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosTaskCB, pendList) #define OS_TCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosTaskCB, pendList)
//通过pendList取出TCB,用于挂入链表节点时使用 pendList的情况
/** /**
* @ingroup los_task * @ingroup los_task
* @brief Obtain the pointer to a task control block. * @brief Obtain the pointer to a task control block.
...@@ -286,19 +286,19 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 ...@@ -286,19 +286,19 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
* @par Dependency: * @par Dependency:
* <ul><li>los_task_pri.h: the header file that contains the API declaration.</li></ul> * <ul><li>los_task_pri.h: the header file that contains the API declaration.</li></ul>
* @see * @see
*/ */ ///通过任务ID找到任务实体
#define OS_TCB_FROM_TID(taskID) (((LosTaskCB *)g_taskCBArray) + (taskID)) #define OS_TCB_FROM_TID(taskID) (((LosTaskCB *)g_taskCBArray) + (taskID))
//通过Tid找到TCB
#ifndef LOSCFG_STACK_POINT_ALIGN_SIZE #ifndef LOSCFG_STACK_POINT_ALIGN_SIZE
#define LOSCFG_STACK_POINT_ALIGN_SIZE (sizeof(UINTPTR) * 2) #define LOSCFG_STACK_POINT_ALIGN_SIZE (sizeof(UINTPTR) * 2)
#endif #endif
#define OS_TASK_RESOURCE_STATIC_SIZE 0x1000 //4K #define OS_TASK_RESOURCE_STATIC_SIZE 0x1000 ///< 4K
#define OS_TASK_RESOURCE_FREE_PRIORITY 5 //回收资源任务的优先级 #define OS_TASK_RESOURCE_FREE_PRIORITY 5 ///< 回收资源任务的优先级
#define OS_RESOURCE_EVENT_MASK 0xFF //资源事件的掩码 #define OS_RESOURCE_EVENT_MASK 0xFF ///< 资源事件的掩码
#define OS_RESOURCE_EVENT_OOM 0x02 //内存溢出事件 #define OS_RESOURCE_EVENT_OOM 0x02 ///< 内存溢出事件
#define OS_RESOURCE_EVENT_FREE 0x04 //资源释放事件 #define OS_RESOURCE_EVENT_FREE 0x04 ///< 资源释放事件
#define OS_TCB_NAME_LEN 32 #define OS_TCB_NAME_LEN 32 ///< 任务名称长度上限
typedef struct { typedef struct {
VOID *stackPointer; /**< Task stack pointer | 内核栈指针位置(SP) */ VOID *stackPointer; /**< Task stack pointer | 内核栈指针位置(SP) */
...@@ -311,7 +311,7 @@ typedef struct { ...@@ -311,7 +311,7 @@ typedef struct {
UINT32 initTimeSlice; /**< Task init time slice | 任务初始的时间片 */ UINT32 initTimeSlice; /**< Task init time slice | 任务初始的时间片 */
INT32 timeSlice; /**< Task remaining time slice | 任务剩余时间片 */ INT32 timeSlice; /**< Task remaining time slice | 任务剩余时间片 */
UINT32 waitTimes; /**< Task delay time, tick number | 设置任务调度延期时间 */ UINT32 waitTimes; /**< Task delay time, tick number | 设置任务调度延期时间 */
SortLinkList sortList; /**< Task sortlink node | 任务排序链表节点 */ SortLinkList sortList; /**< Task sortlink node | 跟CPU捆绑的任务排序链表节点,上面挂的是就绪队列的下一个阶段,进入CPU要执行的任务队列 */
UINT32 stackSize; /**< Task stack size | 内核态栈大小,内存来自内核空间 */ UINT32 stackSize; /**< Task stack size | 内核态栈大小,内存来自内核空间 */
UINTPTR topOfStack; /**< Task stack top | 内核态栈顶 bottom = top + size */ UINTPTR topOfStack; /**< Task stack top | 内核态栈顶 bottom = top + size */
UINT32 taskID; /**< Task ID | 任务ID,任务池本质是一个大数组,ID就是数组的索引,默认 < 128 */ UINT32 taskID; /**< Task ID | 任务ID,任务池本质是一个大数组,ID就是数组的索引,默认 < 128 */
...@@ -365,13 +365,14 @@ typedef struct { ...@@ -365,13 +365,14 @@ typedef struct {
UINTPTR fp; ///< fp寄存器 UINTPTR fp; ///< fp寄存器
#endif #endif
} LosTaskCB; } LosTaskCB;
//LosTask结构体是给外部使用的 ///< LosTask结构体是给外部使用的
typedef struct { typedef struct {
LosTaskCB *runTask; LosTaskCB *runTask;
LosTaskCB *newTask; LosTaskCB *newTask;
} LosTask; } LosTask;
struct ProcessSignalInfo {//进程信号描述符 ///< 进程信号描述符
struct ProcessSignalInfo {
siginfo_t *sigInfo; /**< Signal to be dispatched | 要发送的信号*/ siginfo_t *sigInfo; /**< Signal to be dispatched | 要发送的信号*/
LosTaskCB *defaultTcb; /**< Default TCB | 默认task,默认接收信号的任务. */ LosTaskCB *defaultTcb; /**< Default TCB | 默认task,默认接收信号的任务. */
LosTaskCB *unblockedTcb; /**< The signal unblock on this TCB | 信号在此TCB上解除阻塞 */ LosTaskCB *unblockedTcb; /**< The signal unblock on this TCB | 信号在此TCB上解除阻塞 */
...@@ -405,27 +406,27 @@ typedef struct {//时间片结构体,任务轮询 ...@@ -405,27 +406,27 @@ typedef struct {//时间片结构体,任务轮询
UINT16 time; /**< Expiration time point | 过期时间点*/ UINT16 time; /**< Expiration time point | 过期时间点*/
UINT16 timeout; /**< Expiration duration | 有效期*/ UINT16 timeout; /**< Expiration duration | 有效期*/
} OsTaskRobin; } OsTaskRobin;
//获取当前CPU core运行的任务 /// 获取当前CPU core运行的任务
STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID) STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID)
{ {
return (LosTaskCB *)ArchCurrTaskGet(); return (LosTaskCB *)ArchCurrTaskGet();
} }
///告诉协处理器当前任务使用范围为内核空间 /// 告诉协处理器当前任务使用范围为内核空间
STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task) STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task)
{ {
ArchCurrTaskSet(task); ArchCurrTaskSet(task);
} }
///告诉协处理器当前任务使用范围为 用户空间 /// 告诉协处理器当前任务使用范围为 用户空间
STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread) STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread)
{ {
ArchCurrUserTaskSet(thread); ArchCurrUserTaskSet(thread);
} }
///通过任务ID获取任务实体,task由任务池分配,本质是个数组,彼此都挨在一块 /// 通过任务ID获取任务实体,task由任务池分配,本质是个数组,彼此都挨在一块
STATIC INLINE LosTaskCB *OsGetTaskCB(UINT32 taskID) STATIC INLINE LosTaskCB *OsGetTaskCB(UINT32 taskID)
{ {
return OS_TCB_FROM_TID(taskID); return OS_TCB_FROM_TID(taskID);
} }
///任务是否在使用 /// 任务是否在使用
STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB) STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB)
{ {
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//在freelist中的任务都是 OS_TASK_STATUS_UNUSED 状态 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//在freelist中的任务都是 OS_TASK_STATUS_UNUSED 状态
...@@ -434,7 +435,7 @@ STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB) ...@@ -434,7 +435,7 @@ STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB)
return FALSE; return FALSE;
} }
///任务是否在运行 /// 任务是否在运行
STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB) STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB)
{ {
if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//一个CPU core 只能有一个 OS_TASK_STATUS_RUNNING task if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//一个CPU core 只能有一个 OS_TASK_STATUS_RUNNING task
...@@ -443,7 +444,7 @@ STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB) ...@@ -443,7 +444,7 @@ STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB)
return FALSE; return FALSE;
} }
///任务是否不再活动 /// 任务是否不再活动
STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB) STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB)
{ {
if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) {//三个标签有一个代表不在活动 if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) {//三个标签有一个代表不在活动
...@@ -452,7 +453,7 @@ STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB) ...@@ -452,7 +453,7 @@ STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB)
return FALSE; return FALSE;
} }
/// 任务是否挂起
STATIC INLINE BOOL OsTaskIsPending(const LosTaskCB *taskCB) STATIC INLINE BOOL OsTaskIsPending(const LosTaskCB *taskCB)
{ {
if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) {
...@@ -461,7 +462,7 @@ STATIC INLINE BOOL OsTaskIsPending(const LosTaskCB *taskCB) ...@@ -461,7 +462,7 @@ STATIC INLINE BOOL OsTaskIsPending(const LosTaskCB *taskCB)
return FALSE; return FALSE;
} }
/// 任务是否被干掉
STATIC INLINE BOOL OsTaskIsKilled(const LosTaskCB *taskCB) STATIC INLINE BOOL OsTaskIsKilled(const LosTaskCB *taskCB)
{ {
if (taskCB->taskStatus & OS_TASK_FLAG_EXIT_KILL) { if (taskCB->taskStatus & OS_TASK_FLAG_EXIT_KILL) {
...@@ -489,7 +490,7 @@ STATIC INLINE BOOL OsTaskIsKilled(const LosTaskCB *taskCB) ...@@ -489,7 +490,7 @@ STATIC INLINE BOOL OsTaskIsKilled(const LosTaskCB *taskCB)
#define OS_TASK_WAIT_EVENT (OS_TASK_WAIT_FUTEX + 1) ///< 任务等待事件发生 #define OS_TASK_WAIT_EVENT (OS_TASK_WAIT_FUTEX + 1) ///< 任务等待事件发生
#define OS_TASK_WAIT_COMPLETE (OS_TASK_WAIT_EVENT + 1) ///< 任务等待完成 #define OS_TASK_WAIT_COMPLETE (OS_TASK_WAIT_EVENT + 1) ///< 任务等待完成
//设置事件阻塞掩码,即设置任务的等待事件. /// 设置事件阻塞掩码,即设置任务的等待事件.
STATIC INLINE VOID OsTaskWaitSetPendMask(UINT16 mask, UINTPTR lockID, UINT32 timeout) STATIC INLINE VOID OsTaskWaitSetPendMask(UINT16 mask, UINTPTR lockID, UINT32 timeout)
{ {
LosTaskCB *runTask = OsCurrTaskGet(); LosTaskCB *runTask = OsCurrTaskGet();
...@@ -498,7 +499,7 @@ STATIC INLINE VOID OsTaskWaitSetPendMask(UINT16 mask, UINTPTR lockID, UINT32 tim ...@@ -498,7 +499,7 @@ STATIC INLINE VOID OsTaskWaitSetPendMask(UINT16 mask, UINTPTR lockID, UINT32 tim
(VOID)timeout; (VOID)timeout;
} }
//清除事件阻塞掩码,即任务不再等待任何事件. /// 清除事件阻塞掩码,即任务不再等待任何事件.
STATIC INLINE VOID OsTaskWakeClearPendMask(LosTaskCB *resumeTask) STATIC INLINE VOID OsTaskWakeClearPendMask(LosTaskCB *resumeTask)
{ {
resumeTask->waitID = 0; resumeTask->waitID = 0;
......
...@@ -633,17 +633,17 @@ VOID OsSchedTaskEnQueue(LosTaskCB *taskCB) ...@@ -633,17 +633,17 @@ VOID OsSchedTaskEnQueue(LosTaskCB *taskCB)
#endif #endif
OsSchedEnTaskQueue(taskCB, processCB); OsSchedEnTaskQueue(taskCB, processCB);
} }
/// 任务退出
VOID OsSchedTaskExit(LosTaskCB *taskCB) VOID OsSchedTaskExit(LosTaskCB *taskCB)
{ {
LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);
if (taskCB->taskStatus & OS_TASK_STATUS_READY) { if (taskCB->taskStatus & OS_TASK_STATUS_READY) {//就绪状态
OsSchedTaskDeQueue(taskCB); OsSchedTaskDeQueue(taskCB);//从就绪队列中删除
processCB->processStatus &= ~OS_PROCESS_STATUS_PENDING; processCB->processStatus &= ~OS_PROCESS_STATUS_PENDING;//进程贴上非挂起标签
} else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { } else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { //挂起状态
LOS_ListDelete(&taskCB->pendList); LOS_ListDelete(&taskCB->pendList); //从任务挂起链表中摘除
taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING; taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING;////任务贴上非挂起标签
} }
if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) { if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) {
......
...@@ -35,96 +35,105 @@ ...@@ -35,96 +35,105 @@
#include "los_percpu_pri.h" #include "los_percpu_pri.h"
#include "los_sched_pri.h" #include "los_sched_pri.h"
#include "los_mp.h" #include "los_mp.h"
/// 排序链表初始化
UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
{ {
LOS_ListInit(&sortLinkHeader->sortLink); LOS_ListInit(&sortLinkHeader->sortLink);//初始化双向链表
sortLinkHeader->nodeNum = 0; sortLinkHeader->nodeNum = 0;//nodeNum背后的含义是记录需要CPU工作的数量
return LOS_OK; return LOS_OK;
} }
/*!
* @brief OsAddNode2SortLink 向链表中插入结点,并按时间顺序排列
*
* @param sortLinkHeader 被插入的链表
* @param sortList 要插入的结点
* @return
*
* @see
*/
STATIC INLINE VOID OsAddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) STATIC INLINE VOID OsAddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
{ {
LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; //获取双向链表
if (LOS_ListEmpty(head)) { if (LOS_ListEmpty(head)) { //空链表,直接插入
LOS_ListHeadInsert(head, &sortList->sortLinkNode); LOS_ListHeadInsert(head, &sortList->sortLinkNode);//插入结点
sortLinkHeader->nodeNum++; sortLinkHeader->nodeNum++;//CPU的工作量增加了
return; return;
} }
//链表不为空时,插入分三种情况, responseTime 大于,等于,小于的处理
SortLinkList *listSorted = LOS_DL_LIST_ENTRY(head->pstNext, SortLinkList, sortLinkNode); SortLinkList *listSorted = LOS_DL_LIST_ENTRY(head->pstNext, SortLinkList, sortLinkNode);
if (listSorted->responseTime > sortList->responseTime) { if (listSorted->responseTime > sortList->responseTime) {//如果要插入的节点 responseTime 最小
LOS_ListAdd(head, &sortList->sortLinkNode); LOS_ListAdd(head, &sortList->sortLinkNode);//能跑进来说明是最小的,直接插入到第一的位置
sortLinkHeader->nodeNum++; sortLinkHeader->nodeNum++;//CPU的工作量增加了
return; return;//直接返回了
} else if (listSorted->responseTime == sortList->responseTime) { } else if (listSorted->responseTime == sortList->responseTime) {//相等的情况
LOS_ListAdd(head->pstNext, &sortList->sortLinkNode); LOS_ListAdd(head->pstNext, &sortList->sortLinkNode);//插到第二的位置
sortLinkHeader->nodeNum++; sortLinkHeader->nodeNum++;
return; return;
} }
//处理大于链表中第一个responseTime的情况,需要遍历链表
LOS_DL_LIST *prevNode = head->pstPrev; LOS_DL_LIST *prevNode = head->pstPrev;//注意这里用的前一个结点,也就是说前一个结点中的responseTime 是最大的
do { do { // @note_good 这里写的有点妙,也是双向链表的魅力所在
listSorted = LOS_DL_LIST_ENTRY(prevNode, SortLinkList, sortLinkNode); listSorted = LOS_DL_LIST_ENTRY(prevNode, SortLinkList, sortLinkNode);//一个个遍历,先比大的再比小的
if (listSorted->responseTime <= sortList->responseTime) { if (listSorted->responseTime <= sortList->responseTime) {//如果时间比你小,就插到后面
LOS_ListAdd(prevNode, &sortList->sortLinkNode); LOS_ListAdd(prevNode, &sortList->sortLinkNode);
sortLinkHeader->nodeNum++; sortLinkHeader->nodeNum++;
break; break;
} }
prevNode = prevNode->pstPrev; prevNode = prevNode->pstPrev;//再拿上一个更小的responseTime进行比较
} while (1); } while (1);//死循环
} }
/// 从排序链表上摘除指定节点
VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
{ {
LOS_ListDelete(&sortList->sortLinkNode); LOS_ListDelete(&sortList->sortLinkNode);//摘除工作量
SET_SORTLIST_VALUE(sortList, OS_SORT_LINK_INVALID_TIME); SET_SORTLIST_VALUE(sortList, OS_SORT_LINK_INVALID_TIME);//重置响应时间
sortLinkHeader->nodeNum--; sortLinkHeader->nodeNum--;//cpu的工作量减少一份
} }
/// 获取下一个结点的过期时间
STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, UINT64 startTime) STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, UINT64 startTime)
{ {
LOS_DL_LIST *head = &sortHeader->sortLink; LOS_DL_LIST *head = &sortHeader->sortLink;
LOS_DL_LIST *list = head->pstNext; LOS_DL_LIST *list = head->pstNext;
if (LOS_ListEmpty(head)) { if (LOS_ListEmpty(head)) {//链表为空
return OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; return OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION;
} }
SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode); SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode);//获取结点实体
if (listSorted->responseTime <= (startTime + OS_TICK_RESPONSE_PRECISION)) { if (listSorted->responseTime <= (startTime + OS_TICK_RESPONSE_PRECISION)) { //没看明白 @note_thinking
return startTime + OS_TICK_RESPONSE_PRECISION; return startTime + OS_TICK_RESPONSE_PRECISION;
} }
return listSorted->responseTime; return listSorted->responseTime;
} }
/// 根据函数的具体实现,这个函数应该是找出最空闲的CPU, 函数的实现有待优化, @note_thinking
STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID) STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID)
{ {
Percpu *idleCpu = OsPercpuGetByID(0); Percpu *idleCpu = OsPercpuGetByID(0); //获取0号CPU,0号CPU也可称主核
*idleCpuID = 0; *idleCpuID = 0;
#ifdef LOSCFG_KERNEL_SMP #ifdef LOSCFG_KERNEL_SMP //多核情况下
UINT16 cpuID = 1; UINT16 cpuID = 1;
UINT32 nodeNum = idleCpu->taskSortLink.nodeNum + idleCpu->swtmrSortLink.nodeNum; UINT32 nodeNum = idleCpu->taskSortLink.nodeNum + idleCpu->swtmrSortLink.nodeNum; //获取还未跑完的工作数量
//cpu执行两种工作: 1.普通任务 2.软件定时器
do { do {
Percpu *cpu = OsPercpuGetByID(cpuID); Percpu *cpu = OsPercpuGetByID(cpuID); //一个个cpu遍历
UINT32 temp = cpu->taskSortLink.nodeNum + cpu->swtmrSortLink.nodeNum; UINT32 temp = cpu->taskSortLink.nodeNum + cpu->swtmrSortLink.nodeNum;//获取cpu的工作量
if (nodeNum > temp) { if (nodeNum > temp) {//对工作量比较
idleCpu = cpu; idleCpu = cpu;//取工作量最小的cpu实体
*idleCpuID = cpuID; *idleCpuID = cpuID;//获取cpu id
} }
cpuID++; cpuID++;//下一个cpu id
} while (cpuID < LOSCFG_KERNEL_CORE_NUM); } while (cpuID < LOSCFG_KERNEL_CORE_NUM);
#endif #endif
return idleCpu; return idleCpu;
} }
/// 向cpu的排序链表上添加指定节点
VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, SortLinkType type) VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, SortLinkType type)
{ {
UINT32 intSave; UINT32 intSave;
...@@ -133,51 +142,51 @@ VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, Sort ...@@ -133,51 +142,51 @@ VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, Sort
SPIN_LOCK_S *spinLock = NULL; SPIN_LOCK_S *spinLock = NULL;
UINT16 idleCpu; UINT16 idleCpu;
if (OS_SCHEDULER_ACTIVE) { if (OS_SCHEDULER_ACTIVE) {//当前CPU正在调度
cpu = OsFindIdleCpu(&idleCpu); cpu = OsFindIdleCpu(&idleCpu);//找一个最空闲的CPU
} else { } else {
idleCpu = ArchCurrCpuid(); idleCpu = ArchCurrCpuid();//使用当前cpu
cpu = OsPercpuGet(); cpu = OsPercpuGet();
} }
if (type == OS_SORT_LINK_TASK) { if (type == OS_SORT_LINK_TASK) {//任务类型
sortLinkHeader = &cpu->taskSortLink; sortLinkHeader = &cpu->taskSortLink; //获取任务链表
spinLock = &cpu->taskSortLinkSpin; spinLock = &cpu->taskSortLinkSpin;
} else if (type == OS_SORT_LINK_SWTMR) { } else if (type == OS_SORT_LINK_SWTMR) {//软件定时器类型
sortLinkHeader = &cpu->swtmrSortLink; sortLinkHeader = &cpu->swtmrSortLink;//获取软件定时器链表
spinLock = &cpu->swtmrSortLinkSpin; spinLock = &cpu->swtmrSortLinkSpin;
} else { } else {
LOS_Panic("Sort link type error : %u\n", type); LOS_Panic("Sort link type error : %u\n", type);
} }
LOS_SpinLockSave(spinLock, &intSave); LOS_SpinLockSave(spinLock, &intSave);
SET_SORTLIST_VALUE(node, startTime + (UINT64)waitTicks * OS_CYCLE_PER_TICK); SET_SORTLIST_VALUE(node, startTime + (UINT64)waitTicks * OS_CYCLE_PER_TICK);//设置节点响应时间
OsAddNode2SortLink(sortLinkHeader, node); OsAddNode2SortLink(sortLinkHeader, node);//插入节点
#ifdef LOSCFG_KERNEL_SMP #ifdef LOSCFG_KERNEL_SMP
node->cpuid = idleCpu; node->cpuid = idleCpu;
if (idleCpu != ArchCurrCpuid()) { if (idleCpu != ArchCurrCpuid()) { //如果插入的链表不是当前CPU的链表
LOS_MpSchedule(CPUID_TO_AFFI_MASK(idleCpu)); LOS_MpSchedule(CPUID_TO_AFFI_MASK(idleCpu));//核间中断,对该CPU发生一次调度申请
} }
#endif #endif
LOS_SpinUnlockRestore(spinLock, intSave); LOS_SpinUnlockRestore(spinLock, intSave);
} }
/// 从cpu的排序链表上摘除指定节点
VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type) VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type)
{ {
UINT32 intSave; UINT32 intSave;
#ifdef LOSCFG_KERNEL_SMP #ifdef LOSCFG_KERNEL_SMP
Percpu *cpu = OsPercpuGetByID(node->cpuid); Percpu *cpu = OsPercpuGetByID(node->cpuid);//获取CPU
#else #else
Percpu *cpu = OsPercpuGetByID(0); Percpu *cpu = OsPercpuGetByID(0);
#endif #endif
SPIN_LOCK_S *spinLock = NULL; SPIN_LOCK_S *spinLock = NULL;
SortLinkAttribute *sortLinkHeader = NULL; SortLinkAttribute *sortLinkHeader = NULL;
if (type == OS_SORT_LINK_TASK) { if (type == OS_SORT_LINK_TASK) {//当为任务时
sortLinkHeader = &cpu->taskSortLink; sortLinkHeader = &cpu->taskSortLink;//获取该CPU的任务链表
spinLock = &cpu->taskSortLinkSpin; spinLock = &cpu->taskSortLinkSpin;
} else if (type == OS_SORT_LINK_SWTMR) { } else if (type == OS_SORT_LINK_SWTMR) {
sortLinkHeader = &cpu->swtmrSortLink; sortLinkHeader = &cpu->swtmrSortLink;//获取该CPU的定时器链表
spinLock = &cpu->swtmrSortLinkSpin; spinLock = &cpu->swtmrSortLinkSpin;
} else { } else {
LOS_Panic("Sort link type error : %u\n", type); LOS_Panic("Sort link type error : %u\n", type);
...@@ -185,29 +194,45 @@ VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type) ...@@ -185,29 +194,45 @@ VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type)
LOS_SpinLockSave(spinLock, &intSave); LOS_SpinLockSave(spinLock, &intSave);
if (node->responseTime != OS_SORT_LINK_INVALID_TIME) { if (node->responseTime != OS_SORT_LINK_INVALID_TIME) {
OsDeleteNodeSortLink(sortLinkHeader, node); OsDeleteNodeSortLink(sortLinkHeader, node);//从CPU的执行链表上摘除
} }
LOS_SpinUnlockRestore(spinLock, intSave); LOS_SpinUnlockRestore(spinLock, intSave);
} }
/*!
* @brief OsGetNextExpireTime 获取下一个超时时间
*
* @param startTime
* @return
*
* @see
*/
UINT64 OsGetNextExpireTime(UINT64 startTime) UINT64 OsGetNextExpireTime(UINT64 startTime)
{ {
UINT32 intSave; UINT32 intSave;
Percpu *cpu = OsPercpuGet(); Percpu *cpu = OsPercpuGet();//获取当前CPU
SortLinkAttribute *taskHeader = &cpu->taskSortLink; SortLinkAttribute *taskHeader = &cpu->taskSortLink;
SortLinkAttribute *swtmrHeader = &cpu->swtmrSortLink; SortLinkAttribute *swtmrHeader = &cpu->swtmrSortLink;
LOS_SpinLockSave(&cpu->taskSortLinkSpin, &intSave); LOS_SpinLockSave(&cpu->taskSortLinkSpin, &intSave);
UINT64 taskExpirTime = OsGetSortLinkNextExpireTime(taskHeader, startTime); UINT64 taskExpirTime = OsGetSortLinkNextExpireTime(taskHeader, startTime);//拿到下一个过期时间,注意此处拿到的一定是最短的时间
LOS_SpinUnlockRestore(&cpu->taskSortLinkSpin, intSave); LOS_SpinUnlockRestore(&cpu->taskSortLinkSpin, intSave);
LOS_SpinLockSave(&cpu->swtmrSortLinkSpin, &intSave); LOS_SpinLockSave(&cpu->swtmrSortLinkSpin, &intSave);
UINT64 swtmrExpirTime = OsGetSortLinkNextExpireTime(swtmrHeader, startTime); UINT64 swtmrExpirTime = OsGetSortLinkNextExpireTime(swtmrHeader, startTime);
LOS_SpinUnlockRestore(&cpu->swtmrSortLinkSpin, intSave); LOS_SpinUnlockRestore(&cpu->swtmrSortLinkSpin, intSave);
return (taskExpirTime < swtmrExpirTime) ? taskExpirTime : swtmrExpirTime; return (taskExpirTime < swtmrExpirTime) ? taskExpirTime : swtmrExpirTime;//比较返回更短的那个.
} }
/*!
* @brief OsSortLinkGetTargetExpireTime
* 返回离触发目标时间的tick数
* @param targetSortList
* @return
*
* @see
*/
UINT32 OsSortLinkGetTargetExpireTime(const SortLinkList *targetSortList) UINT32 OsSortLinkGetTargetExpireTime(const SortLinkList *targetSortList)
{ {
UINT64 currTimes = OsGetCurrSchedTimeCycle(); UINT64 currTimes = OsGetCurrSchedTimeCycle();
...@@ -215,7 +240,7 @@ UINT32 OsSortLinkGetTargetExpireTime(const SortLinkList *targetSortList) ...@@ -215,7 +240,7 @@ UINT32 OsSortLinkGetTargetExpireTime(const SortLinkList *targetSortList)
return 0; return 0;
} }
return (UINT32)(targetSortList->responseTime - currTimes) / OS_CYCLE_PER_TICK; return (UINT32)(targetSortList->responseTime - currTimes) / OS_CYCLE_PER_TICK;//响应时间减去当前时间置算出剩余tick数
} }
UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader) UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader)
......
git add -A git add -A
git commit -m ' 因同步官源,代码覆盖,部分模块需重新注解 git commit -m ' CPU的工作量是如何分配的, 读懂对 SortLinkList 的注解即可
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码 百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
博客输出站点(国内):http://weharmonyos.com 博客输出站点(国内):http://weharmonyos.com
博客输出站点(国外):https://weharmony.github.io 博客输出站点(国外):https://weharmony.github.io
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册