更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_sem_pri.h 文件参考

浏览源代码.

结构体

struct  LosSemCB
 

函数

UINT32 OsSemInit (VOID)
 
UINT32 OsSemPostUnsafe (UINT32 semHandle, BOOL *needSched)
 以不安全的方式释放指定的信号量,所谓不安全指的是不用自旋锁 更多...
 

变量

LosSemCBg_allSem
 信号池,一次分配 LOSCFG_BASE_IPC_SEM_LIMIT 个信号量 更多...
 

函数说明

◆ OsSemInit()

UINT32 OsSemInit ( VOID  )

在文件 los_sem.c103 行定义.

104{
105 LosSemCB *semNode = NULL;
106 UINT32 index;
107
108 LOS_ListInit(&g_unusedSemList);//初始化链表,链表上挂未使用的信号量,用于分配信号量,鸿蒙信号量的个数是有限的,默认1024个
109 /* system resident memory, don't free */
110 g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(LosSemCB)));//分配信号池
111 if (g_allSem == NULL) {
112 return LOS_ERRNO_SEM_NO_MEMORY;
113 }
114
115 for (index = 0; index < LOSCFG_BASE_IPC_SEM_LIMIT; index++) {
116 semNode = ((LosSemCB *)g_allSem) + index;//拿信号控制块, 可以直接g_allSem[index]来嘛
117 semNode->semID = SET_SEM_ID(0, index);//保存ID
118 semNode->semStat = OS_SEM_UNUSED;//标记未使用
119 LOS_ListTailInsert(&g_unusedSemList, &semNode->semList);//通过semList把 信号块挂到空闲链表上
120 }
121
122 if (OsSemDbgInitHook() != LOS_OK) {
123 return LOS_ERRNO_SEM_NO_MEMORY;
124 }
125 return LOS_OK;
126}
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the tail of a doubly linked list.
Definition: los_list.h:244
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
Definition: los_memory.c:1123
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
Definition: los_memory.c:107
LITE_OS_SEC_BSS LosSemCB * g_allSem
信号池,一次分配 LOSCFG_BASE_IPC_SEM_LIMIT 个信号量
Definition: los_sem.c:97
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_unusedSemList
可用的信号量列表,干嘛不用freeList? 可以看出这里是另一个人写的代码
Definition: los_sem.c:96
STATIC INLINE UINT32 OsSemDbgInitHook(VOID)
unsigned int UINT32
Definition: los_typedef.h:57
UINT32 semID
Definition: los_sem_pri.h:51
UINT8 semStat
Definition: los_sem_pri.h:48
LOS_DL_LIST semList
Definition: los_sem_pri.h:52
函数调用图:
这是这个函数的调用关系图:

◆ OsSemPostUnsafe()

UINT32 OsSemPostUnsafe ( UINT32  semHandle,
BOOL needSched 
)

以不安全的方式释放指定的信号量,所谓不安全指的是不用自旋锁

在文件 los_sem.c287 行定义.

288{
289 LosTaskCB *resumedTask = NULL;
290 LosSemCB *semPosted = GET_SEM(semHandle);
291 if ((semPosted->semID != semHandle) || (semPosted->semStat == OS_SEM_UNUSED)) {
292 return LOS_ERRNO_SEM_INVALID;
293 }
294
295 /* Update the operate time, no matter the actual Post success or not */
296 OsSemDbgTimeUpdateHook(semHandle);
297
298 if (semPosted->semCount == OS_SEM_COUNT_MAX) {//当前信号资源不能大于最大资源量
299 return LOS_ERRNO_SEM_OVERFLOW;
300 }
301 if (!LOS_ListEmpty(&semPosted->semList)) {//当前有任务挂在semList上,要去唤醒任务
302 resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(semPosted->semList)));//semList上面挂的都是task->pendlist节点,取第一个task下来唤醒
303 OsTaskWakeClearPendMask(resumedTask);
304 resumedTask->ops->wake(resumedTask);
305 if (needSched != NULL) {//参数不为空,就返回需要调度的标签
306 *needSched = TRUE;//TRUE代表需要调度
307 }
308 } else {//当前没有任务挂在semList上,
309 semPosted->semCount++;//信号资源多一个
310 }
311 OsHookCall(LOS_HOOK_TYPE_SEM_POST, semPosted, resumedTask);
312 return LOS_OK;
313}
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
Definition: los_list.h:321
STATIC INLINE VOID OsSemDbgTimeUpdateHook(UINT32 semID)
STATIC INLINE VOID OsTaskWakeClearPendMask(LosTaskCB *resumeTask)
清除事件阻塞掩码,即任务不再等待任何事件.
Definition: los_task_pri.h:298
UINT16 semCount
Definition: los_sem_pri.h:49
VOID(* wake)(LosTaskCB *taskCB)
任务唤醒
const SchedOps * ops
函数调用图:
这是这个函数的调用关系图:

变量说明

◆ g_allSem

LosSemCB* g_allSem
extern

信号池,一次分配 LOSCFG_BASE_IPC_SEM_LIMIT 个信号量

在文件 los_sem.c97 行定义.