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

注解钩子函数的宏实现

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    鸿蒙研究站 | http://weharmonyos.com (国内)
              | https://weharmony.github.io (国外)
    oschina | https://my.oschina.net/weharmony
    博客园 | https://www.cnblogs.com/weharmony/
    知乎 | https://www.zhihu.com/people/weharmonyos
    csdn | https://blog.csdn.net/kuangyufei
    51cto | https://harmonyos.51cto.com/column/34
    掘金 | https://juejin.cn/user/756888642000808
    公众号 | 鸿蒙研究站 (weharmonyos)
上级 9fed5f28
......@@ -308,12 +308,19 @@ STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, UINT64 currTime, SWTMR_CTRL_
/*
* Description: Tick interrupt interface module of software timer
* Return : LOS_OK on success or error code on failure
*///OsSwtmrScan 由系统时钟中断处理函数调用
LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID)//扫描定时器,如果碰到超时的,就放入超时队列
*/
/*!
* @brief OsSwtmrScan 由系统时钟中断处理函数调用
* 扫描定时器,如果碰到超时的,就放入超时队列
* @return
*
* @see
*/
LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID)
{
Percpu *cpu = OsPercpuGet();
SortLinkAttribute* swtmrSortLink = &OsPercpuGet()->swtmrSortLink;
LOS_DL_LIST *listObject = &swtmrSortLink->sortLink;
Percpu *cpu = OsPercpuGet();//获取当前CPU
SortLinkAttribute* swtmrSortLink = &OsPercpuGet()->swtmrSortLink;//获取需由CPU处理的软件定时器总信息
LOS_DL_LIST *listObject = &swtmrSortLink->sortLink;//获取定时器链表,上面挂的是等待时间到触发的定时器
/*
* it needs to be carefully coped with, since the swtmr is in specific sortlink
......@@ -325,25 +332,25 @@ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID)//扫描定时器,如果碰到超时的,
LOS_SpinUnlock(&cpu->swtmrSortLinkSpin);
return;
}
SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
UINT64 currTime = OsGetCurrSchedTimeCycle();
while (sortList->responseTime <= currTime) {
sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
swtmr->startTime = GET_SORTLIST_VALUE(sortList);
OsDeleteNodeSortLink(swtmrSortLink, sortList);
SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);//获取节点
UINT64 currTime = OsGetCurrSchedTimeCycle();//获取当前时间,用于比较所有定时器的时间是否到了
while (sortList->responseTime <= currTime) {//说明有定时器的时间到了,需要去触发定时器了
sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);//这行代码多余了,可以删除 @note_why
SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);//获取软件定时器控制块
swtmr->startTime = GET_SORTLIST_VALUE(sortList);//获取该定时器的响应时间
OsDeleteNodeSortLink(swtmrSortLink, sortList);//将其从链表上摘除
LOS_SpinUnlock(&cpu->swtmrSortLinkSpin);
OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr);
OsWakePendTimeSwtmr(cpu, currTime, swtmr);
OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr);//回调钩子函数 将调用 LOS_TraceSwtmrExpired
OsWakePendTimeSwtmr(cpu, currTime, swtmr);//触发定时器
LOS_SpinLock(&cpu->swtmrSortLinkSpin);
if (LOS_ListEmpty(listObject)) {
if (LOS_ListEmpty(listObject)) {//链表为空就退出
break;
}
sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);//继续下一个节点
}
LOS_SpinUnlock(&cpu->swtmrSortLinkSpin);
......
......@@ -37,19 +37,19 @@
#endif
LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; ///< 系统时钟,是绝大部分部件工作的时钟源,也是其他所有外设的时钟的来源
LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond;///<每秒Tick数,鸿蒙默认是每秒100次,即:10ms
LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; ///<周期转纳秒级
LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; ///< 系统时钟,是绝大部分部件工作的时钟源,也是其他所有外设的时钟的来源
LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond; ///< 每秒Tick数,鸿蒙默认是每秒100次,即:10ms
LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; ///< 周期转纳秒级
/* spinlock for task module */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); ///<节拍器自旋锁
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); ///< 节拍器自旋锁
/*
* Description : Tick interruption handler | 节拍中断处理函数 ,鸿蒙默认10ms触发一次
* Description : Tick interruption handler | 节拍中断处理函数 ,鸿蒙默认1ms触发一次
*/
LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
{
#ifdef LOSCFG_SCHED_TICK_DEBUG
#ifdef LOSCFG_SCHED_TICK_DEBUG
OsSchedDebugRecordData();
#endif
......@@ -61,6 +61,6 @@ LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
HalClockIrqClear(); /* diff from every platform */
#endif
OsSchedTick();
OsSchedTick();//由时钟发起的调度
}
......@@ -91,8 +91,8 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID)
typedef enum {
INT_NO_RESCH = 0x0, /**< no needs to schedule | 不需要调度*/
INT_PEND_RESCH = 0x1, /**< pending schedule flag | 因不允许抢占或正在中断导致的不允许调度*/
INT_PEND_TICK = 0x2, /**< pending tick | 更新到期时间遇到正在中断导致的不允许调度*/
INT_PEND_RESCH = 0x1, /**< pending schedule flag | 因定时器/任务优先级调整等导致的调度,可以理解为内因触发的调度*/
INT_PEND_TICK = 0x2, /**< pending tick | 因tick导致的调度,可以理解为外因触发的调度*/
} SchedFlag;
/* Check if preemptable with counter flag */
......
......@@ -55,7 +55,7 @@ typedef enum {
*/
typedef struct {
LOS_DL_LIST sortLinkNode; ///< 排序链表,注意上面挂的是一个个等待被执行的任务/软件定时器
UINT64 responseTime; ///< 响应时间,注意是时间短的排在前面,见于 OsAddNode2SortLink 的实现
UINT64 responseTime; ///< 响应时间,这里提取了最近需要触发的定时器/任务的时间,见于 OsAddNode2SortLink 的实现
#ifdef LOSCFG_KERNEL_SMP
UINT32 cpuid; ///< 需要哪个CPU处理
#endif
......
此差异已折叠。
......@@ -71,8 +71,8 @@ typedef struct {
typedef struct {
SchedQueue queueList[OS_PRIORITY_QUEUE_NUM];//进程优先级调度队列,默认32级
UINT32 queueBitmap;//进程优先级调度位图
SchedScan taskScan;//函数指针,扫描任务
SchedScan swtmrScan;//函数指针,扫描定时器
SchedScan taskScan;//函数指针,扫描任务的回调函数
SchedScan swtmrScan;//函数指针,扫描定时器的回调函数
} Sched;
STATIC Sched *g_sched = NULL;//全局调度器
......@@ -775,29 +775,29 @@ BOOL OsSchedModifyProcessSchedParam(LosProcessCB *processCB, UINT16 policy, UINT
return needSched;
}
//由时钟发起的调度
VOID OsSchedTick(VOID)
{
Sched *sched = g_sched;
Percpu *currCpu = OsPercpuGet();
Sched *sched = g_sched; //获取全局调度器
Percpu *currCpu = OsPercpuGet(); //获取当前CPU
BOOL needSched = FALSE;
LosTaskCB *runTask = OsCurrTaskGet();
LosTaskCB *runTask = OsCurrTaskGet(); //获取当前任务
currCpu->tickStartTime = runTask->irqStartTime;
currCpu->tickStartTime = runTask->irqStartTime;//将任务的中断开始时间给CPU的tick开始时间,这个做的目的是什么呢 ? @note_thinking
if (currCpu->responseID == OS_INVALID_VALUE) {
if (sched->swtmrScan != NULL) {
(VOID)sched->swtmrScan();
(VOID)sched->swtmrScan();//扫描软件定时器 实体函数是: OsSwtmrScan
}
needSched = sched->taskScan();
needSched = sched->taskScan();//扫描任务, 实体函数是: OsSchedScanTimerList
if (needSched) {
LOS_MpSchedule(OS_MP_CPU_ALL);
currCpu->schedFlag |= INT_PEND_RESCH;
if (needSched) {//若需调度
LOS_MpSchedule(OS_MP_CPU_ALL);//当前CPU向所有cpu发起核间中断,让其发生一次调度
currCpu->schedFlag |= INT_PEND_RESCH; //内因触发的调度
}
}
currCpu->schedFlag |= INT_PEND_TICK;
currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
currCpu->schedFlag |= INT_PEND_TICK; //贴上外因触发的调度,这个外因指的就是tick时间到了
currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME;//响应时间默认设最大
}
VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask)
......@@ -807,14 +807,14 @@ VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask)
idleTask->timeSlice = idleTask->initTimeSlice;
OsSchedTaskEnQueue(idleTask);
}
/// 向全局调度器注册扫描软件定时器的回调函数
UINT32 OsSchedSwtmrScanRegister(SchedScan func)
{
if (func == NULL) {
return LOS_NOK;
}
g_sched->swtmrScan = func;
g_sched->swtmrScan = func;//正式注册, func 将在 OsSchedTick 中被回调
return LOS_OK;
}
///调度初始化
......@@ -849,7 +849,7 @@ UINT32 OsSchedInit(VOID)
LOS_SpinInit(&cpu->swtmrSortLinkSpin);//操作具体CPU核定时器排序链表
}
g_sched->taskScan = OsSchedScanTimerList;//扫描那些处于等待状态的任务是否时间到了
g_sched->taskScan = OsSchedScanTimerList;// 注册回调函数,扫描那些处于等待状态的任务是否时间到了,将在 OsSchedTick 中回调
#ifdef LOSCFG_SCHED_TICK_DEBUG
ret = OsSchedDebugInit();
......
......@@ -93,7 +93,7 @@ extern UINT32 __heap_end; ///< 堆区结束地址
* Number of Ticks in one second
*/
#ifndef LOSCFG_BASE_CORE_TICK_PER_SECOND
#define LOSCFG_BASE_CORE_TICK_PER_SECOND 1000 /* 1ms per tick */
#define LOSCFG_BASE_CORE_TICK_PER_SECOND 1000 /* 1ms per tick | 每秒节拍数*/
#endif
/**
......@@ -220,7 +220,7 @@ extern UINT32 __heap_end; ///< 堆区结束地址
* Default task stack size
*/
#ifndef LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE //内核默认任务栈大小
#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE SIZE(0x4000) //16K
#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE SIZE(0x4000) ///< 16K
#endif
/**
......
......@@ -48,6 +48,7 @@ extern "C" {
#endif /* __cplusplus */
#ifdef LOSCFG_KERNEL_HOOK
/// 内存模块支持的钩子类型
#define LOS_HOOK_ALL_TYPES_DEF \
/* Hook types supported by memory modules */ \
LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_INIT, (VOID *pool, UINT32 size)) \
......@@ -114,16 +115,16 @@ extern "C" {
LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_USR_EVENT, (VOID *buffer, UINT32 len))
/**
* Defines the types of all hooks.
* Defines the types of all hooks. | 定义所有的钩子类型
*/
#define LOS_HOOK_TYPE_DEF(type, paramList) type,
typedef enum {
/* Used to manage hook pools */
/* Used to manage hook pools | 钩子池 开始位 */
LOS_HOOK_TYPE_START = 0,
/* All supported hook types */
LOS_HOOK_ALL_TYPES_DEF
/* Used to manage hook pools */
/* All supported hook types | 所有支持的钩子类型 ,枚举中写宏,这个得点赞 @note_good */
LOS_HOOK_ALL_TYPES_DEF
/* Used to manage hook pools | 钩子池 结束位 */
LOS_HOOK_TYPE_END
} HookType;
......
......@@ -33,6 +33,7 @@
#include "los_hook_types_parse.h"
#ifdef LOSCFG_KERNEL_HOOK
/// 定义钩子函数
#define LOS_HOOK_TYPE_DEF(type, paramList) \
STATIC type##_FN g_fn##type; \
UINT32 type##_RegHook(type##_FN func) { \
......@@ -60,6 +61,16 @@
LOS_HOOK_ALL_TYPES_DEF;
/*
LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_INIT, (VOID *pool, UINT32 size))
拆完之后变成
STATIC LOS_HOOK_TYPE_MEM_INIT_FN g_fnLOS_HOOK_TYPE_MEM_INIT;
*/
#undef LOS_HOOK_TYPE_DEF
#endif /* LOSCFG_DEBUG_HOOK */
......
......@@ -203,7 +203,7 @@ STATIC VOID LOS_TraceSwtmrDelete(const SWTMR_CTRL_S *swtmr)
{
LOS_TRACE(SWTMR_DELETE, swtmr->usTimerID);
}
/// 指定定时器时间到的日志
STATIC VOID LOS_TraceSwtmrExpired(const SWTMR_CTRL_S *swtmr)
{
LOS_TRACE(SWTMR_EXPIRED, swtmr->usTimerID);
......@@ -266,7 +266,7 @@ STATIC VOID LOS_TraceUsrEvent(VOID *buffer, UINT32 len)
LOS_MemFree(m_aucSysMem0, buffer);
#endif
}
///< 为输出日志而注册的钩子函数
VOID OsTraceCnvInit(VOID)
{
LOS_HookReg(LOS_HOOK_TYPE_MEM_ALLOC, LOS_TraceMemAlloc);
......@@ -299,11 +299,11 @@ VOID OsTraceCnvInit(VOID)
LOS_HookReg(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, LOS_TraceTaskSuspend);
LOS_HookReg(LOS_HOOK_TYPE_ISR_ENTER, LOS_TraceIsrEnter);
LOS_HookReg(LOS_HOOK_TYPE_ISR_EXIT, LOS_TraceIsrExit);
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_CREATE, LOS_TraceSwtmrCreate);
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_DELETE, LOS_TraceSwtmrDelete);
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_EXPIRED, LOS_TraceSwtmrExpired);
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_START, LOS_TraceSwtmrStart);
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_STOP, LOS_TraceSwtmrStop);
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_CREATE, LOS_TraceSwtmrCreate); ///< 创建定时器
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_DELETE, LOS_TraceSwtmrDelete); ///< 删除定时器
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_EXPIRED, LOS_TraceSwtmrExpired); ///< 定时器时间到
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_START, LOS_TraceSwtmrStart); ///< 启动定时器
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_STOP, LOS_TraceSwtmrStop); ///< 停止定时器
LOS_HookReg(LOS_HOOK_TYPE_USR_EVENT, LOS_TraceUsrEvent);
LOS_HookReg(LOS_HOOK_TYPE_IPC_WRITE_DROP, LOS_TraceIpcWriteDrop);
LOS_HookReg(LOS_HOOK_TYPE_IPC_WRITE, LOS_TraceIpcWrite);
......
......@@ -49,13 +49,13 @@ extern "C" {
#ifdef LOSCFG_KERNEL_HOOK
/**
* @ingroup los_hook
* Hook error code: The hook pool is insufficient.
* Hook error code: The hook pool is insufficient.
*
* Value: 0x02001f00
*
* Solution: Deregister the registered hook.
*/
#define LOS_ERRNO_HOOK_POOL_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_HOOK, 0x00)
#define LOS_ERRNO_HOOK_POOL_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_HOOK, 0x00) ///< 钩子池满了
/**
* @ingroup los_hook
......@@ -65,7 +65,7 @@ extern "C" {
*
* Solution: Check the input parameters of LOS_HookReg.
*/
#define LOS_ERRNO_HOOK_REG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HOOK, 0x01)
#define LOS_ERRNO_HOOK_REG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HOOK, 0x01) ///< 钩子函数参数无效
/**
* @ingroup los_hook
......@@ -97,7 +97,7 @@ extern "C" {
* <ul><li>los_hook.h: the header file that contains the API declaration.</li></ul>
* @see
*/
#define LOS_HookReg(hookType, hookFn) hookType##_RegHook(hookFn)
#define LOS_HookReg(hookType, hookFn) hookType##_RegHook(hookFn) ///< 注册钩子函数
/**
* @ingroup los_hook
......@@ -119,12 +119,12 @@ extern "C" {
* <ul><li>los_hook.h: the header file that contains the API declaration.</li></ul>
* @see
*/
#define LOS_HookUnReg(hookType, hookFn) hookType##_UnRegHook(hookFn)
#define LOS_HookUnReg(hookType, hookFn) hookType##_UnRegHook(hookFn) ///< 注销钩子函数
/**
* Call hook functions.
*/
#define OsHookCall(hookType, ...) hookType##_CallHook(__VA_ARGS__)
#define OsHookCall(hookType, ...) hookType##_CallHook(__VA_ARGS__) ///< 回调钩子函数
#else
#define LOS_HookReg(hookType, hookFn)
......
git add -A
git commit -m ' 完善互斥量,信号量注解
git commit -m ' 注解钩子函数的宏实现
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
鸿蒙研究站 | http://weharmonyos.com (国内)
| https://weharmony.github.io (国外)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册