From 03a811de3a81c43c2f76846dbb4a0086fb878110 Mon Sep 17 00:00:00 2001 From: kuangyufei Date: Wed, 4 Nov 2020 18:41:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=20cpu=20sortlink=20=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A=20=E9=B8=BF=E8=92=99?= =?UTF-8?q?=E5=86=85=E6=A0=B8=E6=BA=90=E7=A0=81=E5=88=86=E6=9E=90=E7=B3=BB?= =?UTF-8?q?=E5=88=97=20=E3=80=90=20CSDN=20|=20OSCHINA=20|=20WIKI=20?= =?UTF-8?q?=E3=80=91=20=E9=B8=BF=E8=92=99=E5=86=85=E6=A0=B8=E6=BA=90?= =?UTF-8?q?=E7=A0=81=E6=B3=A8=E9=87=8A=E4=B8=AD=E6=96=87=E7=89=88=20?= =?UTF-8?q?=E3=80=90=20CSDN=E4=BB=93=20|=20Gitee=E4=BB=93=20|=20Github?= =?UTF-8?q?=E4=BB=93=20|=20Coding=E4=BB=93=20=E3=80=91=E5=9B=9B=E5=A4=A7?= =?UTF-8?q?=E4=BB=93=E5=BA=93=E6=AF=8F=E6=97=A5=E5=90=8C=E6=AD=A5=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E4=BB=A3=E7=A0=81=E5=92=8Cwiki=20=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=BB=99=E9=B8=BF=E8=92=99=E5=86=85=E6=A0=B8=E6=BA=90=E7=A0=81?= =?UTF-8?q?=E9=80=90=E8=A1=8C=E5=8A=A0=E4=B8=8A=E4=B8=AD=E6=96=87=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3,=E8=AF=A6=E7=BB=86=E9=98=90=E8=BF=B0=E6=A1=86?= =?UTF-8?q?=E6=9E=B6=E5=92=8C=E4=BB=A3=E7=A0=81=E7=BB=86=E8=8A=82,=20?= =?UTF-8?q?=E7=B2=BE=E8=AF=BB=20HarmonyOS=20=E5=86=85=E6=A0=B8=E6=BA=90?= =?UTF-8?q?=E7=A0=81,=20=E5=B0=86=E8=BF=85=E9=80=9F=E6=8B=94=E9=AB=98?= =?UTF-8?q?=E5=AF=B9=E8=AE=A1=E7=AE=97=E6=9C=BA=E6=95=B4=E4=BD=93=E7=90=86?= =?UTF-8?q?=E8=A7=A3,=E4=BB=8E=E6=AD=A4=E9=AB=98=E5=B1=8B=E5=BB=BA?= =?UTF-8?q?=E7=93=B4=E7=9C=8B=E9=97=AE=E9=A2=98.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/base/core/los_sortlink.c | 18 ++++++------- kernel/base/core/los_swtmr.c | 36 ++++++++++++------------- kernel/base/include/los_queue_pri.h | 2 +- kernel/base/include/los_sortlink_pri.h | 5 ++-- kernel/base/misc/los_stackinfo.c | 2 +- kernel/include/los_swtmr.h | 32 +++++++++++----------- zzz/git/push.sh | 2 +- zzz/test/main.c | 21 +++++++++------ zzz/test/main.exe | Bin 0 -> 45443 bytes 9 files changed, 62 insertions(+), 56 deletions(-) create mode 100644 zzz/test/main.exe diff --git a/kernel/base/core/los_sortlink.c b/kernel/base/core/los_sortlink.c index 77f38266..9791ed30 100644 --- a/kernel/base/core/los_sortlink.c +++ b/kernel/base/core/los_sortlink.c @@ -45,14 +45,14 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) LOS_DL_LIST *listObject = NULL; UINT32 index; - size = sizeof(LOS_DL_LIST) << OS_TSK_SORTLINK_LOGLEN;//这行代码很精彩,得到 8个 LOS_DL_LIST - listObject = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, size); /* system resident resource *///常驻内存 + size = sizeof(LOS_DL_LIST) << OS_TSK_SORTLINK_LOGLEN;//这行代码很精彩, size=64个字节 每个LOS_DL_LIST8个字节,即等于 8个LOS_DL_LIST + listObject = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, size); /* system resident resource *///常驻内存 size表示字节的意思 if (listObject == NULL) { return LOS_NOK; } (VOID)memset_s(listObject, size, 0, size);//清0 - sortLinkHeader->sortLink = listObject;//可以知道 sortLink是个链表数组 + sortLinkHeader->sortLink = listObject;//可以知道 sortLink是个链表数组,这个很重要 sortLinkHeader->cursor = 0;//游标默认为0 for (index = 0; index < OS_TSK_SORTLINK_LEN; index++, listObject++) {// OS_TSK_SORTLINK_LEN = 8 LOS_ListInit(listObject);//初始化8个链表 @@ -92,7 +92,7 @@ LITE_OS_SEC_TEXT VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, So } else { listSorted = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);//取出SortLinkList do { - if (ROLLNUM(listSorted->idxRollNum) <= ROLLNUM(sortList->idxRollNum)) {// @note_? 这块没看懂,谁能帮帮我 + if (ROLLNUM(listSorted->idxRollNum) <= ROLLNUM(sortList->idxRollNum)) {// @note_why 这块没看懂,谁能帮帮我 ROLLNUM_SUB(sortList->idxRollNum, listSorted->idxRollNum); } else { ROLLNUM_SUB(listSorted->idxRollNum, sortList->idxRollNum); @@ -110,7 +110,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const { LOS_DL_LIST *tmp = listNode->pstPrev; - /* recursive check until double link round to itself */ + /* recursive check until double link round to itself */ //递归检查,直到双链接循环到自身 while (tmp != listNode) { if (tmp == listHead) { goto FOUND; @@ -125,17 +125,17 @@ LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const FOUND: return; } - +//删除排序链表 LITE_OS_SEC_TEXT VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) { LOS_DL_LIST *listObject = NULL; SortLinkList *nextSortList = NULL; UINT32 sortIndex; - sortIndex = SORT_INDEX(sortList->idxRollNum); - listObject = sortLinkHeader->sortLink + sortIndex; + sortIndex = SORT_INDEX(sortList->idxRollNum);//找出对应索引,索引是通过滚动的idxRollNum来定位的 + listObject = sortLinkHeader->sortLink + sortIndex;//找出索引对应的链表 - /* check if pstSortList node is on the right sortlink */ + /* check if pstSortList node is on the right sortlink */ //检查pstSortList节点是否在正确的sortlink上 OsCheckSortLink(listObject, &sortList->sortLinkNode); if (listObject != sortList->sortLinkNode.pstNext) { diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index d330de34..ea3b52f6 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -165,20 +165,20 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) /* * Description: Start Software Timer * Input : swtmr --- Need to start software timer - */ + */ //开始定时器 LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr) { if ((swtmr->ucOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) || (swtmr->ucMode == LOS_SWTMR_MODE_OPP) || (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) { - SET_SORTLIST_VALUE(&(swtmr->stSortList), swtmr->uwExpiry); + SET_SORTLIST_VALUE(&(swtmr->stSortList), swtmr->uwExpiry);//设置过期时间 } else { SET_SORTLIST_VALUE(&(swtmr->stSortList), swtmr->uwInterval); } - OsAdd2SortLink(&OsPercpuGet()->swtmrSortLink, &swtmr->stSortList); + OsAdd2SortLink(&OsPercpuGet()->swtmrSortLink, &swtmr->stSortList); //通过stSortList节点挂到CPU的软件定时器排序链表上 - swtmr->ucState = OS_SWTMR_STATUS_TICKING; + swtmr->ucState = OS_SWTMR_STATUS_TICKING;//定时器状态成正在 ticking 中 #if (LOSCFG_KERNEL_SMP == YES) swtmr->uwCpuid = ArchCurrCpuid(); @@ -279,24 +279,24 @@ LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID)//获取下一个timeout /* * Description: Stop of Software Timer interface * Input : swtmr --- the software timer contrl handler - */ + */ //停止定时器 LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr) { SortLinkAttribute *sortLinkHeader = NULL; #if (LOSCFG_KERNEL_SMP == YES) /* - * the timer is running on the specific processor, - * we need delete the timer from that processor's sortlink. + * the timer is running on the specific processor, //计时器正在特定处理器上运行 + * we need delete the timer from that processor's sortlink. //我们需要从处理器的sortlink中删除计时器 */ - sortLinkHeader = &g_percpu[swtmr->uwCpuid].swtmrSortLink; + sortLinkHeader = &g_percpu[swtmr->uwCpuid].swtmrSortLink;//找到定时器所属CPU的 sortlind #else sortLinkHeader = &g_percpu[0].swtmrSortLink; #endif - OsDeleteSortLink(sortLinkHeader, &swtmr->stSortList); + OsDeleteSortLink(sortLinkHeader, &swtmr->stSortList);//将自己摘出去 - swtmr->ucState = OS_SWTMR_STATUS_CREATED; - swtmr->ucOverrun = 0; + swtmr->ucState = OS_SWTMR_STATUS_CREATED;//状态变成已创建,又可以再利用. + swtmr->ucOverrun = 0;//计次器清0 } /* @@ -359,13 +359,13 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, SWTMR_UNLOCK(intSave); swtmr->uwOwnerPid = OsCurrProcessGet()->processID;//定时器进程归属设定 - swtmr->pfnHandler = handler; - swtmr->ucMode = mode; - swtmr->ucOverrun = 0; - swtmr->uwInterval = interval; - swtmr->uwExpiry = interval; - swtmr->uwArg = arg; - swtmr->ucState = OS_SWTMR_STATUS_CREATED; + swtmr->pfnHandler = handler;//时间到了的回调函数 + swtmr->ucMode = mode; //定时器模式 + swtmr->ucOverrun = 0; //重复计时的次数 + swtmr->uwInterval = interval; //周期性超时间隔 + swtmr->uwExpiry = interval; //一次性超时间隔 + swtmr->uwArg = arg; //回调函数的参数 + swtmr->ucState = OS_SWTMR_STATUS_CREATED; //已创建状态 SET_SORTLIST_VALUE(&(swtmr->stSortList), 0); *swtmrID = swtmr->usTimerID; diff --git a/kernel/base/include/los_queue_pri.h b/kernel/base/include/los_queue_pri.h index 02b81745..efe27852 100644 --- a/kernel/base/include/los_queue_pri.h +++ b/kernel/base/include/los_queue_pri.h @@ -75,7 +75,7 @@ typedef struct { UINT16 queueTail; /**< Node tail */ //队列尾部节点 UINT16 readWriteableCnt[OS_QUEUE_N_RW]; /**< Count of readable or writable resources, 0:readable, 1:writable */ LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */ - LOS_DL_LIST memList; /**< Pointer to the memory linked list */ //@note_? 这么尚未搞明白是啥意思 + LOS_DL_LIST memList; /**< Pointer to the memory linked list */ //@note_why 这里尚未搞明白是啥意思 } LosQueueCB;//读写队列分离 /* queue state */ diff --git a/kernel/base/include/los_sortlink_pri.h b/kernel/base/include/los_sortlink_pri.h index 39c1cd99..09367f29 100644 --- a/kernel/base/include/los_sortlink_pri.h +++ b/kernel/base/include/los_sortlink_pri.h @@ -81,7 +81,8 @@ extern "C" { #define SET_SORTLIST_VALUE(sortList, value) (((SortLinkList *)(sortList))->idxRollNum = (value)) /**************************************** @note_pic - sortLink + + sortLink[0:7] +-------->+-----------------+ | sortLinkNode | +-----------------+ @@ -106,7 +107,7 @@ typedef struct { UINT32 idxRollNum; //滚动数 } SortLinkList; typedef struct { - LOS_DL_LIST *sortLink;//排序节点 + LOS_DL_LIST *sortLink;//排序链表,看上图它指向的结构. UINT16 cursor; //游标 UINT16 reserved; //保留用 } SortLinkAttribute; diff --git a/kernel/base/misc/los_stackinfo.c b/kernel/base/misc/los_stackinfo.c index e24bdead..6c6acbaf 100644 --- a/kernel/base/misc/los_stackinfo.c +++ b/kernel/base/misc/los_stackinfo.c @@ -105,7 +105,7 @@ VOID OsExcStackInfo(VOID) OsExcStackCheck(); } -/***************************************************************************************@note_pic +/*************************************************************************************** @note_pic OsExcStackInfo 各个CPU栈布局图,其他栈也是一样,CPU各核硬件栈都是紧挨着 __undef_stack(SMP) +-------------------+ <--- cpu1 top diff --git a/kernel/include/los_swtmr.h b/kernel/include/los_swtmr.h index 205539f0..1dff7375 100644 --- a/kernel/include/los_swtmr.h +++ b/kernel/include/los_swtmr.h @@ -229,10 +229,10 @@ extern "C" { * Software timer mode */ enum enSwTmrType { - LOS_SWTMR_MODE_ONCE, /**< One-off software timer */ - LOS_SWTMR_MODE_PERIOD, /**< Periodic software timer */ - LOS_SWTMR_MODE_NO_SELFDELETE, /**< One-off software timer, but not self-delete */ - LOS_SWTMR_MODE_OPP /**< After the one-off timer finishes timing, + LOS_SWTMR_MODE_ONCE, /**< One-off software timer */ //一次性的软件计时器 + LOS_SWTMR_MODE_PERIOD, /**< Periodic software timer */ //周期性的软件计时器 + LOS_SWTMR_MODE_NO_SELFDELETE, /**< One-off software timer, but not self-delete */ //一次性软件计时器,但不能自删除 + LOS_SWTMR_MODE_OPP /**< After the one-off timer finishes timing, //一次性完成后启用周期性软件计时器,鸿蒙目前暂时不支持这种方式 the periodic software timer is enabled. This mode is not supported temporarily. */ }; @@ -257,27 +257,27 @@ enum enSwTmrType { * * @see None. */ -typedef VOID (*SWTMR_PROC_FUNC)(UINTPTR arg); +typedef VOID (*SWTMR_PROC_FUNC)(UINTPTR arg); //函数指针, 赋值给 SWTMR_CTRL_S->pfnHandler,回调处理 /** * @ingroup los_swtmr * Software timer control structure */ -typedef struct tagSwTmrCtrl { +typedef struct tagSwTmrCtrl {// @note_why 鸿蒙内核经常出现 uc uw 这样的变量前缀命名,到底是什么意思? SortLinkList stSortList; - UINT8 ucState; /**< Software timer state */ - UINT8 ucMode; /**< Software timer mode */ - UINT8 ucOverrun; /**< Times that a software timer repeats timing */ - UINT16 usTimerID; /**< Software timer ID */ - UINT32 uwCount; /**< Times that a software timer works */ - UINT32 uwInterval; /**< Timeout interval of a periodic software timer */ - UINT32 uwExpiry; /**< Timeout interval of an one-off software timer */ + UINT8 ucState; /**< Software timer state */ //软件计时器的状态 + UINT8 ucMode; /**< Software timer mode */ //软件计时器的模式 + UINT8 ucOverrun; /**< Times that a software timer repeats timing */ //软件计时器重复计时的次数 + UINT16 usTimerID; /**< Software timer ID */ //软件计时器ID,唯一标识,由软件计时器池分配 + UINT32 uwCount; /**< Times that a software timer works */ //软件计时器工作的时间 + UINT32 uwInterval; /**< Timeout interval of a periodic software timer */ //周期性软件计时器的超时间隔 + UINT32 uwExpiry; /**< Timeout interval of an one-off software timer */ //一次性软件计时器的超时间隔 #if (LOSCFG_KERNEL_SMP == YES) - UINT32 uwCpuid; /**< The cpu where the timer running on */ + UINT32 uwCpuid; /**< The cpu where the timer running on */ //多核情况下,定时器运行的cpu #endif - UINTPTR uwArg; /**< Parameter passed in when the callback function + UINTPTR uwArg; /**< Parameter passed in when the callback function //回调函数的参数 that handles software timer timeout is called */ - SWTMR_PROC_FUNC pfnHandler; /**< Callback function that handles software timer timeout */ + SWTMR_PROC_FUNC pfnHandler; /**< Callback function that handles software timer timeout */ //处理软件计时器超时的回调函数 UINT32 uwOwnerPid; /** Owner of this software timer */ } SWTMR_CTRL_S; diff --git a/zzz/git/push.sh b/zzz/git/push.sh index c8328f67..e9eb47ac 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,5 +1,5 @@ git add -A -git commit -m '开始对IPC Futex 部分代码注释,鸿蒙提供了多种IPC方式 +git commit -m '对 cpu sortlink 部分代码注释 鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】 鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新代码和wiki 项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.' diff --git a/zzz/test/main.c b/zzz/test/main.c index b62647df..bebae296 100644 --- a/zzz/test/main.c +++ b/zzz/test/main.c @@ -5,6 +5,11 @@ typedef unsigned long PTE_T; typedef unsigned long VADDR_T; #define IS_ALIGNED(a, b) (!(((UINTPTR)(a)) & (((UINTPTR)(b)) - 1))) +typedef struct LOS_DL_LIST { + struct LOS_DL_LIST *pstPrev; /**< Current node's pointer to the previous node */ + struct LOS_DL_LIST *pstNext; /**< Current node's pointer to the next node */ +} LOS_DL_LIST; + //鸿蒙内核源码分析系列篇 https://blog.csdn.net/kuangyufei void b(){ @@ -17,6 +22,9 @@ void b(){ #define MMU_DESCRIPTOR_L1_SMALL_FRAME (~MMU_DESCRIPTOR_L1_SMALL_MASK) #define MMU_DESCRIPTOR_L1_SMALL_SHIFT 20 #define MMU_DESCRIPTOR_L1_SECTION_ADDR(x) ((x) & MMU_DESCRIPTOR_L1_SMALL_FRAME) +#define OS_TSK_HIGH_BITS 3U +#define OS_TSK_LOW_BITS (32U - OS_TSK_HIGH_BITS) //29 +#define OS_TSK_SORTLINK_LOGLEN OS_TSK_HIGH_BITS //3U PTE_T l1Entry = pte1BasePtr + vaddr >> MMU_DESCRIPTOR_L1_SMALL_SHIFT; printf("pte1BasePtr ad: %x\n",&pte1BasePtr); @@ -43,16 +51,13 @@ void round1(){ //printf("ROUNDUP %d\n",ROUNDUP(9, 2)); //printf("ROUNDDOWN %d\n",ROUNDDOWN(9, 2)); } -int aw; -int bw=99; -void Print(){ - printf("ROUNDUP %d\n",ROUNDUP(0x00000200+512,1024)); -} + int main() { - int b = 0; - //printf("ROUNDUP %d\n",ROUNDUP(0x00000200+512,1024)); - Print(); + int size = 0; + size = sizeof(LOS_DL_LIST) << OS_TSK_SORTLINK_LOGLEN; + printf("LOS_DL_LIST %d\n",sizeof(LOS_DL_LIST *)); + printf("size %d\n",size); return 0; } diff --git a/zzz/test/main.exe b/zzz/test/main.exe new file mode 100644 index 0000000000000000000000000000000000000000..89c1d9a89fa3df11c694c14e30440e0db1079917 GIT binary patch literal 45443 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