/********************************************************************************************************* ** 函数名称: API_SetLastErrorEx ** 功能描述: 设置指定任务的 errno ** 输 入 : ulId 任务 ID ** ulError 错误号 ** 输 出 : ERROR CODE ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ULONG API_SetLastErrorEx (LW_OBJECT_HANDLE ulId, ULONG ulError) { REGISTER UINT16 usIndex; REGISTER PLW_CLASS_TCB ptcb; usIndex = _ObjectGetIndex(ulId); if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) { _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); } if (_Thread_Index_Invalid(usIndex)) { /* 检查线程有效性 */ _ErrorHandle(ERROR_THREAD_NULL); return (ERROR_THREAD_NULL); } __KERNEL_ENTER(); /* 进入内核 */ if (_Thread_Invalid(usIndex)) { __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(ERROR_THREAD_NULL); return (ERROR_THREAD_NULL); } ptcb = _K_ptcbTCBIdTable[usIndex]; ptcb->TCB_ulLastError = ulError; __KERNEL_EXIT(); /* 退出内核 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_ThreadCancel ** 功能描述: 取消一个指定的线程 ** 输 入 : ulId 线程句柄 ** 输 出 : ERROR_NONE or ESRCH ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ULONG API_ThreadCancel (LW_OBJECT_HANDLE *pulId) { INTREG iregInterLevel; REGISTER LW_OBJECT_HANDLE ulId; REGISTER UINT16 usIndex; REGISTER PLW_CLASS_TCB ptcbDel; ulId = *pulId; usIndex = _ObjectGetIndex(ulId); #if LW_CFG_ARG_CHK_EN > 0 if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) { /* 检查 ID 类型有效性 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); } if (_Thread_Index_Invalid(usIndex)) { /* 检查线程有效性 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_THREAD_NULL); return (ERROR_THREAD_NULL); } #endif __KERNEL_ENTER(); /* 进入内核 */ if (_Thread_Invalid(usIndex)) { __KERNEL_EXIT(); /* 退出内核 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_THREAD_NULL); return (ERROR_THREAD_NULL); } iregInterLevel = KN_INT_DISABLE(); ptcbDel = _K_ptcbTCBIdTable[usIndex]; if (ptcbDel->TCB_iCancelState == LW_THREAD_CANCEL_ENABLE) { /* 允许 CANCEL */ if (ptcbDel->TCB_iCancelType == LW_THREAD_CANCEL_DEFERRED) { /* 延迟 CANCEL */ ptcbDel->TCB_bCancelRequest = LW_TRUE; /* 目标线程进入下一个 TEST 点 */ __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核并打开中断 */ } else { /* 异步取消 */ __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核并打开中断 */ #if LW_CFG_SIGNAL_EN > 0 kill(ulId, SIGCANCEL); /* 立即发送取消信号 */ #else return (API_ThreadDelete(ulId, LW_NULL)); #endif /* LW_CFG_SIGNAL_EN > 0 */ } } else { __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核并打开中断 */ _ErrorHandle(ERROR_THREAD_DISCANCEL); /* 不允许 CACNCEL */ return (ERROR_THREAD_DISCANCEL); } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_ThreadJoin ** 功能描述: 线程合并 ** 输 入 : ** ulId 要合并的目的线程句柄 ** ppvRetValAddr 存放线程返回值得地址 ** 输 出 : ID ** 全局变量: ** 调用模块: API 函数 (不得在中断中调用) *********************************************************************************************************/ LW_API ULONG API_ThreadJoin (LW_OBJECT_HANDLE ulId, PVOID *ppvRetValAddr) { REGISTER UINT16 usIndex; REGISTER PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_TCB ptcb; usIndex = _ObjectGetIndex(ulId); if (LW_CPU_GET_CUR_NESTING()) { /* 不能在中断中调用 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n"); _ErrorHandle(ERROR_KERNEL_IN_ISR); return (ERROR_KERNEL_IN_ISR); } LW_TCB_GET_CUR_SAFE(ptcbCur); #if LW_CFG_ARG_CHK_EN > 0 if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) { /* 检查 ID 类型有效性 */ _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); } if (_Thread_Index_Invalid(usIndex)) { /* 检查线程有效性 */ _ErrorHandle(ERROR_THREAD_NULL); return (ERROR_THREAD_NULL); } #endif __THREAD_CANCEL_POINT(); /* 测试取消点 */ __KERNEL_ENTER(); /* 进入内核 */ if (_Thread_Invalid(usIndex)) { __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(ERROR_THREAD_NULL); return (ERROR_THREAD_NULL); } ptcb = _K_ptcbTCBIdTable[usIndex]; if (ptcb == ptcbCur) { /* 不能阻塞自己 */ __KERNEL_EXIT(); /* 退出内核 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread join self.\r\n"); _ErrorHandle(ERROR_THREAD_JOIN_SELF); return (ERROR_THREAD_JOIN_SELF); } if (ptcb->TCB_bDetachFlag) { __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(ERROR_THREAD_DETACHED); return (ERROR_THREAD_DETACHED); } _ThreadJoin(ptcb, ppvRetValAddr); /* 合并 */ __KERNEL_EXIT(); /* 退出内核 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_ThreadIsSafe ** 功能描述: 检测目标线程是否处于安全模式. ** 输 入 : ** ulId 线程句柄 ** 输 出 : ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API BOOL API_ThreadIsSafe (LW_OBJECT_HANDLE ulId) { REGISTER UINT16 usIndex; REGISTER PLW_CLASS_TCB ptcb; REGISTER BOOL bIsInSafeMode; usIndex = _ObjectGetIndex(ulId); #if LW_CFG_ARG_CHK_EN > 0 if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) { /* 检查 ID 类型有效性 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (LW_FALSE); } if (_Thread_Index_Invalid(usIndex)) { /* 检查线程有效性 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_THREAD_NULL); return (LW_FALSE); } #endif __KERNEL_ENTER(); /* 进入内核 */ if (_Thread_Invalid(usIndex)) { __KERNEL_EXIT(); /* 退出内核 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_THREAD_NULL); return (LW_FALSE); } ptcb = _K_ptcbTCBIdTable[usIndex]; /* 获得 TCB 指针 */ if (ptcb->TCB_ulThreadSafeCounter) { bIsInSafeMode = LW_TRUE; } else { bIsInSafeMode = LW_FALSE; } __KERNEL_EXIT(); /* 退出内核 */ return (bIsInSafeMode); }
/********************************************************************************************************* ** 函数名称: API_ThreadGetSliceEx ** 功能描述: 获得指定线程时间片(扩展接口) ** 输 入 : ** ulId 线程ID ** pusSliceTemp 时间片 ** pusCounter 剩余时间片 ** 输 出 : ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ULONG API_ThreadGetSliceEx (LW_OBJECT_HANDLE ulId, UINT16 *pusSliceTemp, UINT16 *pusCounter) { REGISTER UINT16 usIndex; REGISTER PLW_CLASS_TCB ptcb; usIndex = _ObjectGetIndex(ulId); #if LW_CFG_ARG_CHK_EN > 0 if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) { /* 检查 ID 类型有效性 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); } if (_Thread_Index_Invalid(usIndex)) { /* 检查线程有效性 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_THREAD_NULL); return (ERROR_THREAD_NULL); } #endif __KERNEL_ENTER(); /* 进入内核 */ if (_Thread_Invalid(usIndex)) { __KERNEL_EXIT(); /* 退出内核 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_THREAD_NULL); return (ERROR_THREAD_NULL); } ptcb = _K_ptcbTCBIdTable[usIndex]; if (pusSliceTemp) { *pusSliceTemp = ptcb->TCB_usSchedSlice; } if (pusCounter) { *pusCounter = ptcb->TCB_usSchedCounter; } __KERNEL_EXIT(); /* 退出内核 */ return (ERROR_NONE); }
LW_API ULONG API_ThreadVarDelete (LW_OBJECT_HANDLE ulId, ULONG *pulAddr) { REGISTER UINT16 usIndex; REGISTER PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_TCB ptcb; REGISTER PLW_LIST_LINE plineVar; REGISTER PLW_CLASS_THREADVAR pthreadvar; usIndex = _ObjectGetIndex(ulId); if (LW_CPU_GET_CUR_NESTING()) { /* 不能在中断中调用 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n"); _ErrorHandle(ERROR_KERNEL_IN_ISR); return (ERROR_KERNEL_IN_ISR); } LW_TCB_GET_CUR_SAFE(ptcbCur); #if LW_CFG_ARG_CHK_EN > 0 if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) { _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); } if (_Thread_Index_Invalid(usIndex)) { /* 检查线程有效性 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_THREAD_NULL); return (ERROR_THREAD_NULL); } #endif __KERNEL_ENTER(); /* 进入内核 */ if (_Thread_Invalid(usIndex)) { __KERNEL_EXIT(); /* 退出内核 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n"); _ErrorHandle(ERROR_THREAD_NULL); return (ERROR_THREAD_NULL); } ptcb = _K_ptcbTCBIdTable[usIndex]; for (plineVar = ptcb->TCB_plinePrivateVars; /* 查找 */ plineVar != LW_NULL; plineVar = _list_line_get_next(plineVar)) { pthreadvar = _LIST_ENTRY(plineVar, LW_CLASS_THREADVAR, PRIVATEVAR_lineVarList); if (pthreadvar->PRIVATEVAR_pulAddress == pulAddr) { if (ptcb == ptcbCur) { *pulAddr = pthreadvar->PRIVATEVAR_ulValueSave; } _List_Line_Del(plineVar, &ptcb->TCB_plinePrivateVars); /* 从 TCB 中解链 */ _Free_ThreadVar_Object(pthreadvar); /* 释放控制块 */ __KERNEL_EXIT(); /* 退出内核 */ return (ERROR_NONE); } } __KERNEL_EXIT(); /* 退出内核 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "var is not in thread context.\r\n"); _ErrorHandle(ERROR_THREAD_VAR_NOT_EXIST); return (ERROR_THREAD_VAR_NOT_EXIST); }
/********************************************************************************************************* ** 函数名称: sigqueue ** 功能描述: 发送队列类型信号, 如果是进程, 将发送给其主线程. ** 输 入 : ulId 线程 id 或者 进程号 ** iSigNo 信号 ** sigvalue 信号 value ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigqueue (LW_OBJECT_HANDLE ulId, INT iSigNo, const union sigval sigvalue) { REGISTER UINT16 usIndex; REGISTER PLW_CLASS_TCB ptcb; LW_SEND_VAL sendval; #if LW_CFG_MODULELOADER_EN > 0 if (ulId < LW_CFG_MAX_THREADS) { /* 进程号 */ ulId = vprocMainThread((pid_t)ulId); } #endif /* LW_CFG_MODULELOADER_EN > 0 */ usIndex = _ObjectGetIndex(ulId); if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) { /* 检查 ID 类型有效性 */ _ErrorHandle(ESRCH); return (PX_ERROR); } if (_Thread_Index_Invalid(usIndex)) { /* 检查线程有效性 */ _ErrorHandle(ESRCH); return (PX_ERROR); } if (!__issig(iSigNo)) { _ErrorHandle(EINVAL); return (PX_ERROR); } if (LW_CPU_GET_CUR_NESTING() || (ulId == API_ThreadIdSelf())) { _excJobAdd((VOIDFUNCPTR)sigqueue, (PVOID)ulId, (PVOID)iSigNo, (PVOID)sigvalue.sival_ptr, 0, 0, 0); return (ERROR_NONE); } #if LW_CFG_SMP_EN > 0 if (LW_NCPUS > 1) { /* 正工作在 SMP 多核模式 */ if (API_ThreadStop(ulId)) { return (PX_ERROR); } } #endif /* LW_CFG_SMP_EN */ __KERNEL_ENTER(); /* 进入内核 */ if (_Thread_Invalid(usIndex)) { __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(ESRCH); return (PX_ERROR); } ptcb = __GET_TCB_FROM_INDEX(usIndex); if (ptcb->TCB_iDeleteProcStatus) { __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(ERROR_THREAD_OTHER_DELETE); return (PX_ERROR); } sendval = _doSigQueue(ptcb, iSigNo, sigvalue); #if LW_CFG_SMP_EN > 0 if (LW_NCPUS > 1) { /* 正工作在 SMP 多核模式 */ _ThreadContinue(ptcb, LW_FALSE); /* 在内核状态下唤醒被停止线程 */ } #endif /* LW_CFG_SMP_EN */ __KERNEL_EXIT(); /* 退出内核 */ #if LW_CFG_SIGNALFD_EN > 0 if (sendval == SEND_BLOCK) { _sigfdReadUnblock(ulId, iSigNo); } #endif /* LW_CFG_SIGNALFD_EN > 0 */ return (ERROR_NONE); }