/********************************************************************************************************* ** 函数名称: API_ThreadOnce2 ** 功能描述: 线程安全的仅执行一边指定函数. ** 输 入 : pbOnce once 相关 BOOL 全局变量, 必须初始化为 LW_FALSE. ** pfuncRoutine 需要执行的函数. ** pvArg 执行参数 ** 输 出 : ERROR_NONE ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT API_ThreadOnce2 (BOOL *pbOnce, VOIDFUNCPTR pfuncRoutine, PVOID pvArg) { INTREG iregInterLevel; REGISTER INT iOk = LW_FALSE; __LW_ATOMIC_LOCK(iregInterLevel); /* 锁定 */ if (*pbOnce == LW_FALSE) { /* 互斥的判断是否执行 */ *pbOnce = LW_TRUE; iOk = LW_TRUE; /* 设置独立标志 */ } __LW_ATOMIC_UNLOCK(iregInterLevel); /* 解锁 */ if (pfuncRoutine && iOk) { LW_SOFUNC_PREPARE(pfuncRoutine); pfuncRoutine(pvArg); /* 执行 */ } return (ERROR_NONE); }
PVOID _ITimerThread (PVOID pvArg) { INTREG iregInterLevel; REGISTER PLW_CLASS_TIMER ptmr; PTIMER_CALLBACK_ROUTINE pfuncRoutine; PVOID pvRoutineArg; #if (LW_CFG_RMS_EN > 0) && (LW_CFG_MAX_RMSS > 0) LW_OBJECT_HANDLE ulRms = API_RmsCreate("rms_timer", LW_OPTION_OBJECT_GLOBAL, LW_NULL); #endif (VOID)pvArg; for (;;) { PLW_CLASS_WAKEUP_NODE pwun; ULONG ulCounter = LW_ITIMER_RATE; #if (LW_CFG_RMS_EN > 0) && (LW_CFG_MAX_RMSS > 0) API_RmsPeriod(ulRms, LW_ITIMER_RATE); /* 使用 RMS 进行周期运行 */ #else API_TimeSleep(LW_ITIMER_RATE); /* 等待一个扫描周期 */ #endif iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核同时关闭中断 */ __WAKEUP_PASS_FIRST(&_K_wuITmr, pwun, ulCounter); ptmr = _LIST_ENTRY(pwun, LW_CLASS_TIMER, TIMER_wunTimer); _WakeupDel(&_K_wuITmr, pwun); if (ptmr->TIMER_ulOption & LW_OPTION_AUTO_RESTART) { ptmr->TIMER_ulCounter = ptmr->TIMER_ulCounterSave; _WakeupAdd(&_K_wuITmr, pwun); } else { ptmr->TIMER_ucStatus = LW_TIMER_STATUS_STOP; /* 填写停止标志位 */ } pfuncRoutine = ptmr->TIMER_cbRoutine; pvRoutineArg = ptmr->TIMER_pvArg; __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核同时打开中断 */ LW_SOFUNC_PREPARE(pfuncRoutine); pfuncRoutine(pvRoutineArg); iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核同时关闭中断 */ __WAKEUP_PASS_SECOND(); KN_INT_ENABLE(iregInterLevel); /* 这里允许响应中断 */ iregInterLevel = KN_INT_DISABLE(); __WAKEUP_PASS_END(); __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核同时打开中断 */ } return (LW_NULL); }
/********************************************************************************************************* ** 函数名称: __pthreadDataDeleteByThread ** 功能描述: 删除所有与当前线程相关的内部数据节点. ** 输 入 : NONE ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __pthreadDataDeleteByThread (LW_OBJECT_HANDLE ulId, PVOID pvRetVal, PLW_CLASS_TCB ptcbDel) { __PX_KEY_NODE *pkeyn; __PX_KEY_DATA *pkeyd; LW_OBJECT_HANDLE ulMe = ptcbDel->TCB_ulId; __PX_CONTEXT *pctx = _posixCtxTryGet(ptcbDel); /* 不存在则不创建 */ PLW_LIST_LINE plineTempK; PLW_LIST_LINE plineTempD; PVOID pvPrevValue; BOOL bCall = LW_TRUE; #if LW_CFG_MODULELOADER_EN > 0 LW_LD_VPROC *pvprocDel; #endif /* LW_CFG_MODULELOADER_EN */ if (pctx == LW_NULL) { /* 不是 posix 线程 */ return; } #if LW_CFG_MODULELOADER_EN > 0 pvprocDel = __LW_VP_GET_TCB_PROC(ptcbDel); if (pvprocDel && pvprocDel->VP_bForceTerm) { /* 进程不需要执行 destructor */ bCall = LW_FALSE; } #endif /* LW_CFG_MODULELOADER_EN */ /* * 线程删除, 需要遍历所有 key 键的私有数据表, 删除与本线程相关的私有数据 */ __re_check: __PX_LOCK(); /* 锁住 posix 库 */ for (plineTempK = _G_plineKeyHeader; plineTempK != LW_NULL; plineTempK = _list_line_get_next(plineTempK)) { /* 遍历所有 key 键 */ pkeyn = (__PX_KEY_NODE *)plineTempK; plineTempD = pkeyn->PKEYN_plineKeyHeader; /* 遍历 key 键内的所有节点 */ while (plineTempD) { pkeyd = (__PX_KEY_DATA *)plineTempD; plineTempD = _list_line_get_next(plineTempD); if (pkeyd->PKEYD_ulOwner == ulMe) { /* 是否为当前线程数据节点 */ if (pkeyd->PKEYD_pvData) { /* 需要调用 destructor */ pvPrevValue = pkeyd->PKEYD_pvData; pkeyd->PKEYD_pvData = LW_NULL; /* 下次不再调用 destructor */ __PX_UNLOCK(); /* 解锁 posix 库 */ if (pkeyn->PKEYN_pfuncDestructor && bCall) { /* 调用删除函数 */ LW_SOFUNC_PREPARE(pkeyn->PKEYN_pfuncDestructor); pkeyn->PKEYN_pfuncDestructor(pvPrevValue); } goto __re_check; /* 重新检查 */ } _List_Line_Del(&pkeyd->PKEYD_lineManage, &pkeyn->PKEYN_plineKeyHeader); /* 从链表中删除 */ __SHEAP_FREE(pkeyd); /* 释放线程私有数据内存 */ } } } __PX_UNLOCK(); /* 解锁 posix 库 */ }