/********************************************************************************************************* ** 函数名称: pause ** 功能描述: 等待一个信号的到来 ** 输 入 : NONE ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT pause (VOID) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_PCB ppcb; __THREAD_CANCEL_POINT(); /* 测试取消点 */ LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ MONITOR_EVT_LONG1(MONITOR_EVENT_ID_SIGNAL, MONITOR_EVENT_SIGNAL_PAUSE, ptcbCur->TCB_ulId, LW_NULL); iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核 */ ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_SIGNAL; /* 等待信号 */ ppcb = _GetPcb(ptcbCur); __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */ __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核 */ _ErrorHandle(EINTR); return (PX_ERROR); }
/********************************************************************************************************* ** 函数名称: API_ThreadSetCancelType ** 功能描述: 设置当前线程被动取消时的动作, ** 可以为 PTHREAD_CANCEL_ASYNCHRONOUS or PTHREAD_CANCEL_DEFERRED ** 输 入 : ** iNewType 新类型 ** piOldType 先早类型 ** 输 出 : ERRNO ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT API_ThreadSetCancelType (INT iNewType, INT *piOldType) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; if (iNewType != LW_THREAD_CANCEL_ASYNCHRONOUS && iNewType != LW_THREAD_CANCEL_DEFERRED) { _ErrorHandle(EINVAL); return (EINVAL); } LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ if (ptcbCur->TCB_iCancelState == LW_THREAD_CANCEL_ENABLE && ptcbCur->TCB_iCancelType == LW_THREAD_CANCEL_DEFERRED && (ptcbCur->TCB_bCancelRequest)) { /* 需要删除 */ LW_OBJECT_HANDLE ulId = ptcbCur->TCB_ulId; #if LW_CFG_THREAD_DEL_EN > 0 API_ThreadDelete(&ulId, LW_THREAD_CANCELED); #endif /* LW_CFG_THREAD_DEL_EN > 0 */ return (ERROR_NONE); } iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核同时关闭中断 */ if (piOldType) { *piOldType = ptcbCur->TCB_iCancelType; } ptcbCur->TCB_iCancelType = iNewType; __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核同时打开中断 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: vprocStackAlloc ** 功能描述: 分配 stack ** 输 入 : ptcbNew 新建任务 ** ulOption 任务创建选项 ** stSize 堆栈大小 ** 输 出 : 堆栈 ** 全局变量: ** 调用模块: *********************************************************************************************************/ PVOID vprocStackAlloc (PLW_CLASS_TCB ptcbNew, ULONG ulOption, size_t stSize) { PVOID pvRet; #if (LW_CFG_VMM_EN > 0) && !defined(LW_CFG_CPU_ARCH_PPC) PLW_CLASS_TCB ptcbCur; LW_LD_VPROC *pvproc; LW_TCB_GET_CUR_SAFE(ptcbCur); if (ptcbNew->TCB_iStkLocation == LW_TCB_STK_NONE) { /* 还没有确定堆栈的位置 */ pvproc = __LW_VP_GET_TCB_PROC(ptcbCur); if ((pvproc && !(ulOption & LW_OPTION_OBJECT_GLOBAL)) || (ulOption & LW_OPTION_THREAD_STK_MAIN)) { ptcbNew->TCB_iStkLocation = LW_TCB_STK_VMM; /* 使用 VMM 堆栈 */ } else { ptcbNew->TCB_iStkLocation = LW_TCB_STK_HEAP; /* 使用系统堆栈 */ } } if (ptcbNew->TCB_iStkLocation == LW_TCB_STK_VMM) { pvRet = API_VmmMalloc(stSize); } else #endif /* LW_CFG_VMM_EN > 0 */ { ptcbNew->TCB_iStkLocation = LW_TCB_STK_HEAP; pvRet = __KHEAP_ALLOC(stSize); } return (pvRet); }
/********************************************************************************************************* ** 函数名称: __tshellTtyInputHistoryGet ** 功能描述: shell 获取一条输入历史. ** 输 入 : bNext 向前还是向后 ** ppvCookie 上次获取的位置 ** psicContext 当前输入相上下文 ** 输 出 : 是否获取成功 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static BOOL __tshellHistoryGet (BOOL bNext, PVOID *ppvCookie, __PSHELL_INPUT_CTX psicContext) { PLW_CLASS_TCB ptcbCur; __PSHELL_HISTORY_CTX psihc; __PSHELL_HISTORY psihHistory = (__PSHELL_HISTORY)*ppvCookie; PLW_LIST_RING pringGet; LW_TCB_GET_CUR_SAFE(ptcbCur); psihc = __TTINY_SHELL_GET_HIS(ptcbCur); if (psihc->SIHC_pringHeader == LW_NULL) { /* 没有历史记录 */ return (LW_FALSE); } if (psihHistory == LW_NULL) { pringGet = psihc->SIHC_pringHeader; } else { if (bNext) { pringGet = _list_ring_get_next(&psihHistory->SIH_ringManage); } else { pringGet = _list_ring_get_prev(&psihHistory->SIH_ringManage); } } psihHistory = _LIST_ENTRY(pringGet, __SHELL_HISTORY, SIH_ringManage); lib_strlcpy(CTX_BUFFER, psihHistory->SIH_cInputSave, LW_CFG_SHELL_MAX_COMMANDLEN); *ppvCookie = (PVOID)psihHistory; return (LW_TRUE); }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: sigwaitinfo ** 功能描述: 等待 sigset 内信号的到来,以串行的方式从信号队列中取出信号进行处理, 信号将不再被执行. ** 输 入 : psigset 指定的信号集 ** psiginfo 获取的信号信息 ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigwaitinfo (const sigset_t *psigset, struct siginfo *psiginfo) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_PCB ppcb; INT iSigNo; PLW_CLASS_SIGCONTEXT psigctx; struct siginfo siginfo; LW_CLASS_SIGWAIT sigwt; if (!psigset) { _ErrorHandle(EINVAL); return (PX_ERROR); } __THREAD_CANCEL_POINT(); /* 测试取消点 */ LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ MONITOR_EVT_D2(MONITOR_EVENT_ID_SIGNAL, MONITOR_EVENT_SIGNAL_SIGWAIT, ptcbCur->TCB_ulId, *psigset, LW_NULL); __KERNEL_ENTER(); /* 进入内核 */ psigctx = _signalGetCtx(ptcbCur); iSigNo = _sigPendGet(psigctx, psigset, &siginfo); /* 检查当前是否有等待的信号 */ if (__issig(iSigNo)) { __KERNEL_EXIT(); /* 退出内核 */ if (psiginfo) { *psiginfo = siginfo; } return (siginfo.si_signo); } iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_SIGNAL; /* 等待信号 */ ppcb = _GetPcb(ptcbCur); __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ sigwt.SIGWT_sigset = *psigset; psigctx->SIGCTX_sigwait = &sigwt; /* 保存等待信息 */ if (__KERNEL_EXIT()) { /* 是否其他信号激活 */ psigctx->SIGCTX_sigwait = LW_NULL; _ErrorHandle(EINTR); /* SA_RESTART 也退出 */ return (PX_ERROR); } psigctx->SIGCTX_sigwait = LW_NULL; if (psiginfo) { *psiginfo = sigwt.SIGWT_siginfo; } return (sigwt.SIGWT_siginfo.si_signo); }
/********************************************************************************************************* ** 函数名称: sigprocmask ** 功能描述: 测试或改变当前线程的信号掩码 ** 输 入 : iCmd 命令 ** psigset 新信号集 ** psigsetOld 先早信号集 ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigprocmask (INT iCmd, const sigset_t *psigset, sigset_t *psigsetOld) { PLW_CLASS_TCB ptcbCur; PLW_CLASS_SIGCONTEXT psigctx; sigset_t sigsetBlock; if (LW_CPU_GET_CUR_NESTING()) { /* 不能在中断中调用 */ return (PX_ERROR); } LW_TCB_GET_CUR_SAFE(ptcbCur); psigctx = _signalGetCtx(ptcbCur); if (psigsetOld) { /* 保存古老的 */ *psigsetOld = psigctx->SIGCTX_sigsetSigBlockMask; } if (!psigset) { /* 新的是否有效 */ return (ERROR_NONE); } __KERNEL_ENTER(); /* 进入内核 */ switch (iCmd) { case SIG_BLOCK: /* 添加阻塞 */ sigsetBlock = *psigset; sigsetBlock &= ~__SIGNO_UNMASK; /* 有些信号是不可屏蔽的 */ psigctx->SIGCTX_sigsetSigBlockMask |= sigsetBlock; __KERNEL_EXIT(); /* 退出内核 */ return (ERROR_NONE); case SIG_UNBLOCK: /* 删除阻塞 */ psigctx->SIGCTX_sigsetSigBlockMask &= ~(*psigset); break; case SIG_SETMASK: /* 设置阻塞 */ psigctx->SIGCTX_sigsetSigBlockMask = *psigset; break; default: /* 错误 */ __KERNEL_EXIT(); /* 退出内核 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "command invalidate.\r\n"); _ErrorHandle(EINVAL); return (PX_ERROR); } _sigPendRun(ptcbCur); /* 可能有先前被阻塞信号需要运行*/ __KERNEL_EXIT(); /* 退出内核 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __tshellTtyInputHistorySave ** 功能描述: shell 记录一条输入. ** 输 入 : psicContext 输入上下文 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __tshellHistorySave (__PSHELL_INPUT_CTX psicContext) { PLW_CLASS_TCB ptcbCur; __PSHELL_HISTORY_CTX psihc; __PSHELL_HISTORY psihHistory; PLW_LIST_RING pring; LW_TCB_GET_CUR_SAFE(ptcbCur); psihc = __TTINY_SHELL_GET_HIS(ptcbCur); pring = psihc->SIHC_pringHeader; while (pring) { /* 循环查找是否与以前的相同 */ psihHistory = _LIST_ENTRY(pring, __SHELL_HISTORY, SIH_ringManage); if (lib_strcmp(psihHistory->SIH_cInputSave, CTX_BUFFER) == 0) { /* 如果相同 */ if (pring == psihc->SIHC_pringHeader) { return; /* 如果是表头, 则不需要处理 */ } else { _List_Ring_Del(&psihHistory->SIH_ringManage, &psihc->SIHC_pringHeader); _List_Ring_Add_Ahead(&psihHistory->SIH_ringManage, &psihc->SIHC_pringHeader); /* 放在表头位置 */ return; } } pring = _list_ring_get_next(pring); if (pring == psihc->SIHC_pringHeader) { break; } } psihHistory = (__PSHELL_HISTORY)__SHEAP_ALLOC(sizeof(__SHELL_HISTORY) + lib_strlen(CTX_BUFFER)); if (psihHistory) { lib_strcpy(psihHistory->SIH_cInputSave, CTX_BUFFER); _List_Ring_Add_Ahead(&psihHistory->SIH_ringManage, &psihc->SIHC_pringHeader); /* 加入新的输入 */ psihc->SIHC_uiCounter++; if (psihc->SIHC_uiCounter > __INPUT_SAVE_MAX) { /* 需要删除最老的一条 */ PLW_LIST_RING pringPrev = _list_ring_get_prev(psihc->SIHC_pringHeader); psihHistory = _LIST_ENTRY(pringPrev, __SHELL_HISTORY, SIH_ringManage); _List_Ring_Del(&psihHistory->SIH_ringManage, &psihc->SIHC_pringHeader); __SHEAP_FREE(psihHistory); psihc->SIHC_uiCounter--; } } }
/********************************************************************************************************* ** 函数名称: API_TShellTermAlert ** 功能描述: tty 终端响铃 ** 输 入 : iFd 输出目标 ** 输 出 : NONE ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API VOID API_TShellTermAlert (INT iFd) { PLW_CLASS_TCB ptcbCur; LW_TCB_GET_CUR_SAFE(ptcbCur); if (!(__TTINY_SHELL_GET_OPT(ptcbCur) & LW_OPTION_TSHELL_VT100)) { return; } fdprintf(iFd, "\a"); }
/********************************************************************************************************* ** 函数名称: API_TShellSetTitel ** 功能描述: tty 终端设置标题 ** 输 入 : iFd 输出目标 ** pcTitel 标题 ** 输 出 : NONE ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API VOID API_TShellSetTitel (INT iFd, CPCHAR pcTitel) { PLW_CLASS_TCB ptcbCur; LW_TCB_GET_CUR_SAFE(ptcbCur); if (!(__TTINY_SHELL_GET_OPT(ptcbCur) & LW_OPTION_TSHELL_VT100)) { return; } fdprintf(iFd, "\x1B]0;%s\x07", pcTitel); }
/********************************************************************************************************* ** 函数名称: sigsuspend ** 功能描述: 使用指定的掩码等待一个有效信号的到来, 然后返回先前的信号掩码. ** 输 入 : psigsetMask 指定的信号掩码 ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigsuspend (const sigset_t *psigsetMask) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_PCB ppcb; BOOL bIsRun; PLW_CLASS_SIGCONTEXT psigctx; sigset_t sigsetOld; if (!psigsetMask) { _ErrorHandle(EINVAL); return (PX_ERROR); } __THREAD_CANCEL_POINT(); /* 测试取消点 */ LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ MONITOR_EVT_D2(MONITOR_EVENT_ID_SIGNAL, MONITOR_EVENT_SIGNAL_SIGSUSPEND, ptcbCur->TCB_ulId, *psigsetMask, LW_NULL); __KERNEL_ENTER(); /* 进入内核 */ psigctx = _signalGetCtx(ptcbCur); sigsetOld = psigctx->SIGCTX_sigsetSigBlockMask; /* 记录先前的掩码 */ psigctx->SIGCTX_sigsetSigBlockMask = *psigsetMask & (~__SIGNO_UNMASK); bIsRun = _sigPendRun(ptcbCur); if (bIsRun) { __KERNEL_EXIT(); /* 退出内核 */ sigprocmask(SIG_SETMASK, &sigsetOld, LW_NULL); /* 设置为原先的 mask */ _ErrorHandle(EINTR); return (PX_ERROR); } iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_SIGNAL; /* 等待信号 */ ppcb = _GetPcb(ptcbCur); __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ __KERNEL_EXIT(); /* 退出内核 */ sigprocmask(SIG_SETMASK, &sigsetOld, NULL); _ErrorHandle(EINTR); return (PX_ERROR); }
/********************************************************************************************************* ** 函数名称: API_CoroutineDelete ** 功能描述: 删除一个指定的协程. ** 输 入 : pvCrcb 协程句柄 ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ULONG API_CoroutineDelete (PVOID pvCrcb) { INTREG iregInterLevel; REGISTER PLW_CLASS_COROUTINE pcrcbDel = (PLW_CLASS_COROUTINE)pvCrcb; REGISTER PLW_CLASS_COROUTINE pcrcbNow; PLW_CLASS_TCB ptcbCur; if (!LW_SYS_STATUS_IS_RUNNING()) { /* 系统必须已经启动 */ _ErrorHandle(ERROR_KERNEL_NOT_RUNNING); return (ERROR_KERNEL_NOT_RUNNING); } if (LW_CPU_GET_CUR_NESTING()) { /* 不能在中断中调用 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n"); _ErrorHandle(ERROR_KERNEL_IN_ISR); return (ERROR_KERNEL_IN_ISR); } if (!pcrcbDel) { _DebugHandle(__ERRORMESSAGE_LEVEL, "coroutine handle invalidate.\r\n"); _ErrorHandle(EINVAL); return (EINVAL); } LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ pcrcbNow = _LIST_ENTRY(ptcbCur->TCB_pringCoroutineHeader, LW_CLASS_COROUTINE, COROUTINE_ringRoutine); /* 获得当前协程 */ if (pcrcbNow == pcrcbDel) { /* 删除当前协程 */ return (API_CoroutineExit()); } LW_SPIN_LOCK_QUICK(&ptcbCur->TCB_slLock, &iregInterLevel); _List_Ring_Del(&pcrcbDel->COROUTINE_ringRoutine, &ptcbCur->TCB_pringCoroutineHeader); /* 从协程表中删除 */ LW_SPIN_UNLOCK_QUICK(&ptcbCur->TCB_slLock, iregInterLevel); MONITOR_EVT_LONG2(MONITOR_EVENT_ID_COROUTINE, MONITOR_EVENT_COROUTINE_DELETE, ptcbCur->TCB_ulId, pcrcbDel, LW_NULL); if (pcrcbDel->COROUTINE_bIsNeedFree) { _StackFree(ptcbCur, pcrcbDel->COROUTINE_pstkStackLowAddr, LW_TRUE); /* 释放内存 */ } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: sigpending ** 功能描述: 获得当前被暂时搁置未处理的信号 (有处理函数. 但是被屏蔽了) ** 输 入 : psigset 信号集 ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigpending (sigset_t *psigset) { PLW_CLASS_SIGCONTEXT psigctx; PLW_CLASS_TCB ptcbCur; if (psigset) { LW_TCB_GET_CUR_SAFE(ptcbCur); psigctx = _signalGetCtx(ptcbCur); *psigset = psigctx->SIGCTX_sigsetPending; return (ERROR_NONE); } else { return (PX_ERROR); } }
/********************************************************************************************************* ** 函数名称: API_TimeSleepEx ** 功能描述: 线程睡眠函数 (精度为 TICK HZ) ** 输 入 : ulTick 睡眠的时间 ** bSigRet 是否允许信号唤醒 ** 输 出 : ERROR_NONE or EINTR ** 全局变量: ** 调用模块: API 函数 (不得在中断中调用) *********************************************************************************************************/ LW_API ULONG API_TimeSleepEx (ULONG ulTick, BOOL bSigRet) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_PCB ppcb; REGISTER ULONG ulKernelTime; if (LW_CPU_GET_CUR_NESTING()) { /* 不能在中断中调用 */ _ErrorHandle(ERROR_KERNEL_IN_ISR); return (ERROR_KERNEL_IN_ISR); } LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ MONITOR_EVT_LONG2(MONITOR_EVENT_ID_THREAD, MONITOR_EVENT_THREAD_SLEEP, ptcbCur->TCB_ulId, ulTick, LW_NULL); __wait_again: if (!ulTick) { /* 不进行延迟 */ return (ERROR_NONE); } iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核 */ ppcb = _GetPcb(ptcbCur); __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */ ptcbCur->TCB_ulDelay = ulTick; __ADD_TO_WAKEUP_LINE(ptcbCur); /* 加入等待扫描链 */ __KERNEL_TIME_GET_NO_SPINLOCK(ulKernelTime, ULONG); /* 记录系统时间 */ if (__KERNEL_EXIT_IRQ(iregInterLevel)) { /* 被信号激活 */ if (bSigRet) { _ErrorHandle(EINTR); return (EINTR); } ulTick = _sigTimeoutRecalc(ulKernelTime, ulTick); /* 重新计算等待时间 */ goto __wait_again; /* 继续等待 */ } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: sigaltstack ** 功能描述: 设置信号上下文的堆栈 ** 输 入 : ss 新的堆栈信息 ** oss 老的堆栈信息 ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigaltstack (const stack_t *ss, stack_t *oss) { PLW_CLASS_TCB ptcbCur; PLW_CLASS_SIGCONTEXT psigctx; stack_t *pstack; if (ss && (ss->ss_flags & SS_ONSTACK)) { if (!ss->ss_sp || !ALIGNED(ss->ss_sp, LW_CFG_HEAP_ALIGNMENT)) { /* 必须满足对齐关系 */ _ErrorHandle(EINVAL); return (PX_ERROR); } if (ss->ss_size < MINSIGSTKSZ) { _ErrorHandle(ENOMEM); return (PX_ERROR); } } LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ __KERNEL_ENTER(); /* 进入内核 */ psigctx = _signalGetCtx(ptcbCur); if (oss) { *oss = psigctx->SIGCTX_stack; } if (ss) { pstack = &psigctx->SIGCTX_stack; if (pstack->ss_flags & SS_ONSTACK) { /* 正在使用用户堆栈 */ if ((ptcbCur->TCB_pstkStackNow >= (PLW_STACK)pstack->ss_sp) && (ptcbCur->TCB_pstkStackNow < (PLW_STACK)((size_t)pstack->ss_sp + pstack->ss_size))) { _ErrorHandle(EPERM); /* 正在信号上下文中使用此堆栈 */ __KERNEL_EXIT(); /* 退出内核 */ return (PX_ERROR); } } *pstack = *ss; pstack->ss_size &= ~(LW_CFG_HEAP_ALIGNMENT - 1); } __KERNEL_EXIT(); /* 退出内核 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: sigTrap ** 功能描述: 向指定任务发送信号, 同时停止自己. (本程序在异常上下文中执行) ** 输 入 : ulId 线程 id (不允许为进程号) ** sigvalue 信号参数 ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigTrap (LW_OBJECT_HANDLE ulId, const union sigval sigvalue) { REGISTER PLW_CLASS_TCB ptcbCur; if (!LW_CPU_GET_CUR_NESTING()) { /* 必须在异常中 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "not in exception mode.\r\n"); return (PX_ERROR); } LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ __KERNEL_ENTER(); /* 进入内核 */ _ThreadStop(ptcbCur); __KERNEL_EXIT(); /* 退出内核 */ _excJobAdd(__sig_trap, (PVOID)ulId, (PVOID)ptcbCur->TCB_ulId, sigvalue.sival_ptr, 0, 0, 0); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __tshellReadlineInit ** 功能描述: shell 初始化 readline. ** 输 入 : NONE ** 输 出 : 初始化是否成功 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __tshellReadlineInit (VOID) { PLW_CLASS_TCB ptcbCur; __PSHELL_HISTORY_CTX psihc; LW_TCB_GET_CUR_SAFE(ptcbCur); psihc = __TTINY_SHELL_GET_HIS(ptcbCur); if (psihc == LW_NULL) { psihc = (__PSHELL_HISTORY_CTX)__SHEAP_ALLOC(sizeof(__SHELL_HISTORY_CTX)); if (psihc == LW_NULL) { fprintf(stderr, "read line tool no memory!\n"); return (PX_ERROR); } lib_bzero(psihc, sizeof(__SHELL_HISTORY_CTX)); __TTINY_SHELL_SET_HIS(ptcbCur, psihc); } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: sigaction ** 功能描述: 设置一个指定信号的服务向量, 同时可获取原始服务向量. ** (由于与 struct sigaction 重名, 所以这里直接使用 sigaction 函数名) ** 输 入 : iSigNo 信号 ** psigactionNew 新的处理结构 ** psigactionOld 先早的处理结构 ** 输 出 : ERROR_NONE , EINVAL ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigaction (INT iSigNo, const struct sigaction *psigactionNew, struct sigaction *psigactionOld) { struct sigaction *psigaction; PLW_CLASS_SIGCONTEXT psigctx; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_SIGPEND psigpend; REGISTER INT iSigIndex = __sigindex(iSigNo); /* TCB_sigaction 下标 */ if (!__issig(iSigNo)) { _ErrorHandle(EINVAL); return (PX_ERROR); } if ((iSigNo == SIGKILL) || (iSigNo == SIGSTOP)) { /* 不能捕获和忽略 */ _ErrorHandle(EINVAL); return (PX_ERROR); } LW_TCB_GET_CUR_SAFE(ptcbCur); psigctx = _signalGetCtx(ptcbCur); psigaction = &psigctx->SIGCTX_sigaction[iSigIndex]; if (psigactionOld) { *psigactionOld = *psigaction; /* 保存先早信息 */ } if (psigactionNew == LW_NULL) { return (ERROR_NONE); } __KERNEL_ENTER(); *psigaction = *psigactionNew; /* 拷贝新的处理控制块 */ psigaction->sa_mask &= ~__SIGNO_UNMASK; /* 有些信号不可屏蔽 */ __KERNEL_EXIT(); if (psigaction->sa_handler == SIG_IGN) { /* 设置为忽略该信号 */ __KERNEL_ENTER(); /* 进入内核 */ psigctx->SIGCTX_sigsetPending &= ~__sigmask(iSigNo); /* 没有等待 unmask 后执行的信号*/ psigctx->SIGCTX_sigsetKill &= ~__sigmask(iSigNo); /* 没有在屏蔽状态 kill 这个信号*/ { /* 删除队列中的相关信号节点 */ PLW_LIST_RING pringHead = psigctx->SIGCTX_pringSigQ[iSigIndex]; REGISTER PLW_LIST_RING pringSigP = pringHead; if (pringHead) { /* 唤醒队列中存在节点 */ do { psigpend = _LIST_ENTRY(pringSigP, LW_CLASS_SIGPEND, SIGPEND_ringSigQ); /* 获得 sigpend 控制块地址 */ pringSigP = _list_ring_get_next(pringSigP); /* 下一个节点 */ if ((psigpend->SIGPEND_siginfo.si_code != SI_KILL) && (psigpend->SIGPEND_iNotify == SIGEV_SIGNAL)) { _sigPendFree(psigpend); /* 需要交换空闲队列 */ } } while (pringSigP != pringHead); } } __KERNEL_EXIT(); /* 退出内核 */ } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: nanosleep ** 功能描述: 使调用此函数的线程睡眠一个指定的时间, 睡眠过程中可能被信号唤醒. (POSIX) ** 输 入 : rqtp 睡眠的时间 ** rmtp 保存剩余时间的结构. ** 输 出 : ERROR_NONE or PX_ERROR error == EINTR 表示被信号激活. ** 全局变量: ** 调用模块: API 函数 (不得在中断中调用) *********************************************************************************************************/ LW_API INT nanosleep (const struct timespec *rqtp, struct timespec *rmtp) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_PCB ppcb; REGISTER ULONG ulKernelTime; REGISTER INT iRetVal; INT iSchedRet; REGISTER ULONG ulError; ULONG ulTick; struct timespec tvStart; struct timespec tvTemp; if ((!rqtp) || (rqtp->tv_nsec < 0) || (rqtp->tv_nsec >= __TIMEVAL_NSEC_MAX)) { /* 时间格式错误 */ _ErrorHandle(EINVAL); return (PX_ERROR); } ulTick = __timespecToTick((struct timespec *)rqtp); if (!ulTick) { /* 不到一个 tick */ __timePassSpec(rqtp); /* 平静度过 */ if (rmtp) { rmtp->tv_sec = 0; /* 不存在时间差别 */ rmtp->tv_nsec = 0; } return (ERROR_NONE); } __timeGetHighResolution(&tvStart); /* 记录开始的时间 */ __THREAD_CANCEL_POINT(); /* 测试取消点 */ LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ MONITOR_EVT_LONG2(MONITOR_EVENT_ID_THREAD, MONITOR_EVENT_THREAD_SLEEP, ptcbCur->TCB_ulId, ulTick, LW_NULL); __wait_again: iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核 */ ppcb = _GetPcb(ptcbCur); __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */ ptcbCur->TCB_ulDelay = ulTick; __ADD_TO_WAKEUP_LINE(ptcbCur); /* 加入等待扫描链 */ __KERNEL_TIME_GET_NO_SPINLOCK(ulKernelTime, ULONG); /* 记录系统时间 */ iSchedRet = __KERNEL_EXIT_IRQ(iregInterLevel); /* 调度器解锁 */ if (iSchedRet == LW_SIGNAL_EINTR) { iRetVal = PX_ERROR; /* 被信号激活 */ ulError = EINTR; } else { if (iSchedRet == LW_SIGNAL_RESTART) { /* 信号要求重启等待 */ ulTick = _sigTimeoutRecalc(ulKernelTime, ulTick); /* 重新计算等待时间 */ if (ulTick != 0ul) { goto __wait_again; /* 重新等待剩余的 tick */ } } iRetVal = ERROR_NONE; /* 自然唤醒 */ ulError = ERROR_NONE; } if (ulError == ERROR_NONE) { /* tick 已经延迟结束 */ __timeGetHighResolution(&tvTemp); __timespecSub(&tvTemp, &tvStart); /* 计算已经延迟的时间 */ if (__timespecLeftTime(&tvTemp, rqtp)) { /* 还有剩余时间需要延迟 */ struct timespec tvNeed = *rqtp; __timespecSub(&tvNeed, &tvTemp); __timePassSpec(&tvNeed); /* 平静度过 */ } if (rmtp) { rmtp->tv_sec = 0; /* 不存在时间差别 */ rmtp->tv_nsec = 0; } } else { /* 信号唤醒 */ if (rmtp) { *rmtp = *rqtp; __timeGetHighResolution(&tvTemp); __timespecSub(&tvTemp, &tvStart); /* 计算已经延迟的时间 */ if (__timespecLeftTime(&tvTemp, rmtp)) { /* 没有延迟够 */ __timespecSub(rmtp, &tvTemp); /* 计算没有延迟够的时间 */ } } } _ErrorHandle(ulError); /* 设置 errno 值 */ return (iRetVal); }
/********************************************************************************************************* ** 函数名称: API_CoroutineExit ** 功能描述: 在当前线程正在执行的协程删除 ** 输 入 : NONE ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ULONG API_CoroutineExit (VOID) { INTREG iregInterLevel; PLW_CLASS_CPU pcpuCur; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_COROUTINE pcrcbExit; REGISTER PLW_CLASS_COROUTINE pcrcbNext; REGISTER PLW_LIST_RING pringNext; if (!LW_SYS_STATUS_IS_RUNNING()) { /* 系统必须已经启动 */ _ErrorHandle(ERROR_KERNEL_NOT_RUNNING); return (ERROR_KERNEL_NOT_RUNNING); } 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); pcrcbExit = _LIST_ENTRY(ptcbCur->TCB_pringCoroutineHeader, LW_CLASS_COROUTINE, COROUTINE_ringRoutine); /* 获得当前协程 */ if (&pcrcbExit->COROUTINE_ringRoutine == _list_ring_get_next(&pcrcbExit->COROUTINE_ringRoutine)) { /* 仅有这一个协程 */ #if LW_CFG_THREAD_DEL_EN > 0 API_ThreadExit(LW_NULL); #endif /* LW_CFG_THREAD_DEL_EN > 0 */ return (ERROR_NONE); } pringNext = _list_ring_get_next(&pcrcbExit->COROUTINE_ringRoutine); pcrcbNext = _LIST_ENTRY(pringNext, LW_CLASS_COROUTINE, COROUTINE_ringRoutine); /* 获得下一个协程 */ LW_SPIN_LOCK_QUICK(&ptcbCur->TCB_slLock, &iregInterLevel); _List_Ring_Del(&pcrcbExit->COROUTINE_ringRoutine, &ptcbCur->TCB_pringCoroutineHeader); /* 从协程表中删除 */ LW_SPIN_UNLOCK_QUICK(&ptcbCur->TCB_slLock, iregInterLevel); ptcbCur->TCB_pringCoroutineHeader = pringNext; /* 转动到下一个协程 */ MONITOR_EVT_LONG2(MONITOR_EVENT_ID_COROUTINE, MONITOR_EVENT_COROUTINE_DELETE, ptcbCur->TCB_ulId, pcrcbExit, LW_NULL); if (pcrcbExit->COROUTINE_bIsNeedFree) { _StackFree(ptcbCur, pcrcbExit->COROUTINE_pstkStackLowAddr, LW_TRUE); /* 释放内存 */ } iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ INIT_DUMMY_STACK(); pcpuCur = LW_CPU_GET_CUR(); pcpuCur->CPU_pcrcbCur = &_K_pcrcbDummy; pcpuCur->CPU_pcrcbNext = pcrcbNext; archCrtCtxSwitch(LW_CPU_GET_CUR()); /* 协程切换 */ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ return (ERROR_NONE); /* 理论上是无法运行到这里的 */ }
/********************************************************************************************************* ** 函数名称: __pthreadDataSet ** 功能描述: 设置指定 key 在当前线程内部数据节点. (无则创建) ** 输 入 : lId 键id ** pvData 初始数据 ** 输 出 : ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __pthreadDataSet (long lId, const void *pvData) { __PX_KEY_NODE *pkeyn = (__PX_KEY_NODE *)lId; __PX_KEY_DATA *pkeyd; PLW_CLASS_TCB ptcbCur; LW_OBJECT_HANDLE ulMe; __PX_CONTEXT *pctx; PLW_LIST_LINE plineTemp; if (pkeyn == LW_NULL) { /* 没有 key 键 */ errno = EINVAL; return (EINVAL); } LW_TCB_GET_CUR_SAFE(ptcbCur); ulMe = ptcbCur->TCB_ulId; pctx = _posixCtxGet(ptcbCur); if (pctx == LW_NULL) { /* 没有线程上下文 */ errno = ENOMEM; return (EINVAL); } /* * 查找是否已经创建了相关私有数据 */ __PX_KEY_LOCK(pkeyn); /* 锁住 key 键 */ for (plineTemp = pkeyn->PKEYN_plineKeyHeader; plineTemp != LW_NULL; plineTemp = _list_line_get_next(plineTemp)) { pkeyd = (__PX_KEY_DATA *)plineTemp; /* 链表是 KEY DATA 的第一个元素*/ if (pkeyd->PKEYD_ulOwner == ulMe) { /* 找到对应当前线程的数据 */ pkeyd->PKEYD_pvData = (void *)pvData; break; } } __PX_KEY_UNLOCK(pkeyn); /* 解锁 key 键 */ if (plineTemp) { return (ERROR_NONE); /* 已经找到了对应的节点 */ } /* * 如果没有找到, 则需要新建私有数据 */ pkeyd = (__PX_KEY_DATA *)__SHEAP_ALLOC(sizeof(__PX_KEY_DATA)); /* 没有节点, 需要新建 */ if (pkeyd == LW_NULL) { errno = ENOMEM; return (ENOMEM); } pkeyd->PKEYD_lId = lId; /* 通过 id 反向查找 key */ pkeyd->PKEYD_pvData = (void *)pvData; pkeyd->PKEYD_ulOwner = ulMe; /* 记录线程 ID */ __PX_KEY_LOCK(pkeyn); /* 锁住 key 键 */ _List_Line_Add_Ahead(&pkeyd->PKEYD_lineManage, &pkeyn->PKEYN_plineKeyHeader); /* 加入对应 key 键链表 */ __PX_KEY_UNLOCK(pkeyn); /* 解锁 key 键 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: waitread ** 功能描述: select() 变种,等待单个文件可读. ** 输 入 : iFd 文件描述符 ** ptmvalTO 等待超时时间, LW_NULL 表示永远等待. ** 输 出 : 正常等待到的文件数, 为 1 表示文件可以读, 为 0 表示超时 ,错误返回 PX_ERROR. ** errno == ERROR_IO_SELECT_UNSUPPORT_IN_DRIVER 驱动程序不支持 ** errno == ERROR_IO_SELECT_CONTEXT 线程不存在 context ** errno == ERROR_THREAD_WAIT_TIMEOUT 等待超时 ** errno == ERROR_KERNEL_IN_ISR 在中断中调用 ** errno == ERROR_IOS_INVALID_FILE_DESCRIPTOR 文件描述符无效. ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT waitread (INT iFd, struct timeval *ptmvalTO) { REGISTER INT iIsOk = ERROR_NONE; /* 初始化为没有错误 */ REGISTER INT iWidth = iFd + 1; /* iFd + 1 */ REGISTER INT iWidthInBytes; /* 需要检测的位数占多少字节 */ REGISTER ULONG ulWaitTime; /* 等待时间 */ REGISTER LW_SEL_CONTEXT *pselctx; PLW_CLASS_TCB ptcbCur; fd_set fdsetRead; LW_SEL_WAKEUPNODE selwunNode; /* 生成的 NODE 模板 */ ULONG ulError; if (LW_CPU_GET_CUR_NESTING()) { _ErrorHandle(ERROR_KERNEL_IN_ISR); /* 不能在中断中调用 */ return (PX_ERROR); } if (iFd > (FD_SETSIZE - 1) || iFd < 0) { /* 文件号错误 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "file descriptor invalidate..\r\n"); _ErrorHandle(ERROR_IOS_INVALID_FILE_DESCRIPTOR); /* 文件描述符无效 */ return (PX_ERROR); } LW_TCB_GET_CUR_SAFE(ptcbCur); pselctx = ptcbCur->TCB_pselctxContext; if (!pselctx) { /* 没有 select context */ _DebugHandle(__ERRORMESSAGE_LEVEL, "no select context.\r\n"); _ErrorHandle(ERROR_IO_SELECT_CONTEXT); return (PX_ERROR); } iWidthInBytes = __HOWMANY(iWidth, NFDBITS) * sizeof(fd_mask); /* 需要检测的位数占多少字节 */ FD_ZERO(&fdsetRead); /* 清除文件集 */ FD_SET(iFd, &fdsetRead); /* 指定文件置位 */ __selFdsetInit(iWidthInBytes, &fdsetRead, /* 设置 OrigRead 文件位 */ LW_NULL, LW_NULL, pselctx); /* __selTaskDeleteHook 使用 */ FD_CLR(iFd, &fdsetRead); /* 清除文件集 */ if (!ptmvalTO) { /* 计算等待时间 */ ulWaitTime = LW_OPTION_WAIT_INFINITE; /* 无限等待 */ } else { ulWaitTime = __timevalToTick(ptmvalTO); /* 计算超时时间 */ } pselctx->SELCTX_pfdsetReadFds = &fdsetRead; pselctx->SELCTX_pfdsetWriteFds = LW_NULL; /* 保存用户参数地址 */ pselctx->SELCTX_pfdsetExceptFds = LW_NULL; API_SemaphoreBClear(pselctx->SELCTX_hSembWakeup); /* 清除信号量 */ selwunNode.SELWUN_hThreadId = API_ThreadIdSelf(); selwunNode.SELWUN_seltypType = SELREAD; selwunNode.SELWUN_iFd = iFd; pselctx->SELCTX_iWidth = iWidth; /* 记录最大文件号 */ pselctx->SELCTX_bPendedOnSelect = LW_TRUE; /* 需要 delete hook 清除 NODE */ iIsOk = ioctl(iFd, FIOSELECT, (LONG)&selwunNode); /* FIOSELECT */ if (iIsOk != ERROR_NONE) { ULONG ulError = API_GetLastError(); iIsOk = ioctl(iFd, FIOUNSELECT, (LONG)&selwunNode); /* FIOUNSELECT */ if (ulError == ERROR_IO_UNKNOWN_REQUEST) { _ErrorHandle(ERROR_IO_SELECT_UNSUPPORT_IN_DRIVER); /* 驱动程序不支持 */ } pselctx->SELCTX_bPendedOnSelect = LW_FALSE; /* 自行清理完毕 */ return (PX_ERROR); /* 错误 */ } API_SemaphoreBPend(pselctx->SELCTX_hSembWakeup, ulWaitTime); /* 开始等待 */ ulError = API_GetLastError(); iIsOk = ioctl(iFd, FIOUNSELECT, (LONG)&selwunNode); /* FIOUNSELECT */ pselctx->SELCTX_bPendedOnSelect = LW_FALSE; /* 自行清理完毕 */ if (iIsOk != ERROR_NONE) { return (PX_ERROR); /* 出现错误 */ } else { _ErrorHandle(ulError); } if (FD_ISSET(iFd, &fdsetRead)) { /* 检查文件是否可读 */ return (1); } else { return (0); } }
LW_API ULONG API_SemaphoreMPost (LW_OBJECT_HANDLE ulId) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER UINT16 usIndex; REGISTER PLW_CLASS_EVENT pevent; REGISTER PLW_CLASS_TCB ptcb; REGISTER PLW_LIST_RING *ppringList; /* 等待队列地址 */ 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_SEM_M)) { /* 类型是否正确 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n"); _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); } if (_Event_Index_Invalid(usIndex)) { /* 下标是否正正确 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n"); _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); } #endif pevent = &_K_eventBuffer[usIndex]; if (!LW_SYS_STATUS_IS_RUNNING()) { /* 系统还没有启动 */ return (ERROR_NONE); } __KERNEL_ENTER(); /* 进入内核 */ if (_Event_Type_Invalid(usIndex, LW_TYPE_EVENT_MUTEX)) { __KERNEL_EXIT(); /* 退出内核 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n"); _ErrorHandle(ERROR_EVENT_TYPE); return (ERROR_EVENT_TYPE); } if (ptcbCur != (PLW_CLASS_TCB)pevent->EVENT_pvTcbOwn) { /* 是否是拥有者 */ __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(ERROR_EVENT_NOT_OWN); /* 没有事件所有权 */ return (ERROR_EVENT_NOT_OWN); } if (pevent->EVENT_pvPtr) { /* 检测是否进行了连续调用 */ pevent->EVENT_pvPtr = (PVOID)((ULONG)pevent->EVENT_pvPtr - 1); /* 临时计数器-- */ __KERNEL_EXIT(); /* 退出内核 */ return (ERROR_NONE); } iregInterLevel = KN_INT_DISABLE(); if (_EventWaitNum(pevent)) { if (pevent->EVENT_ulOption & LW_OPTION_WAIT_PRIORITY) { /* 优先级等待队列 */ _EVENT_DEL_Q_PRIORITY(ppringList); /* 检查需要激活的队列 */ /* 激活优先级等待线程 */ ptcb = _EventReadyPriorityLowLevel(pevent, LW_NULL, ppringList); } else { _EVENT_DEL_Q_FIFO(ppringList); /* 检查需要激活的FIFO队列 */ /* 激活FIFO等待线程 */ ptcb = _EventReadyFifoLowLevel(pevent, LW_NULL, ppringList); } KN_INT_ENABLE(iregInterLevel); _EventPrioTryResume(pevent, ptcbCur); /* 尝试返回之前的优先级 */ pevent->EVENT_ulMaxCounter = (ULONG)ptcb->TCB_ucPriority; pevent->EVENT_pvTcbOwn = (PVOID)ptcb; /* 保存线程信息 */ _EventReadyHighLevel(ptcb, LW_THREAD_STATUS_SEM); /* 处理 TCB */ MONITOR_EVT_LONG2(MONITOR_EVENT_ID_SEMM, MONITOR_EVENT_SEM_POST, ulId, ptcb->TCB_ulId, LW_NULL); __KERNEL_EXIT(); /* 退出内核 */ if (pevent->EVENT_ulOption & LW_OPTION_DELETE_SAFE) { /* 退出安全模式 */ _ThreadUnsafeInternal(); } return (ERROR_NONE); } else { /* 没有线程等待 */ KN_INT_ENABLE(iregInterLevel); if (pevent->EVENT_ulCounter == LW_FALSE) { /* 检查是否还有空间加 */ pevent->EVENT_ulCounter = (ULONG)LW_TRUE; pevent->EVENT_ulMaxCounter = LW_PRIO_LOWEST; /* 清空保存信息 */ pevent->EVENT_pvTcbOwn = LW_NULL; __KERNEL_EXIT(); /* 退出内核 */ if (pevent->EVENT_ulOption & LW_OPTION_DELETE_SAFE) { /* 退出安全模式 */ _ThreadUnsafeInternal(); } return (ERROR_NONE); } else { /* 已经满了 */ __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(ERROR_EVENT_FULL); return (ERROR_EVENT_FULL); } } }
/********************************************************************************************************* ** 函数名称: sigtimedwait ** 功能描述: 等待 sigset 内信号的到来,以串行的方式从信号队列中取出信号进行处理, 信号将不再被执行. ** 输 入 : psigset 指定的信号集 ** psiginfo 获取的信号信息 ** ptv 超时时间 (NULL 表示一直等待) ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigtimedwait (const sigset_t *psigset, struct siginfo *psiginfo, const struct timespec *ptv) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_PCB ppcb; INT iSigNo; PLW_CLASS_SIGCONTEXT psigctx; struct siginfo siginfo; LW_CLASS_SIGWAIT sigwt; ULONG ulTimeout; if (!psigset) { _ErrorHandle(EINVAL); return (PX_ERROR); } if (ptv == LW_NULL) { /* 永久等待 */ ulTimeout = LW_OPTION_WAIT_INFINITE; } else { ulTimeout = __timespecToTick(ptv); } __THREAD_CANCEL_POINT(); /* 测试取消点 */ LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ MONITOR_EVT_D2(MONITOR_EVENT_ID_SIGNAL, MONITOR_EVENT_SIGNAL_SIGWAIT, ptcbCur->TCB_ulId, *psigset, LW_NULL); __KERNEL_ENTER(); /* 进入内核 */ psigctx = _signalGetCtx(ptcbCur); iSigNo = _sigPendGet(psigctx, psigset, &siginfo); /* 检查当前是否有等待的信号 */ if (__issig(iSigNo)) { __KERNEL_EXIT(); /* 退出内核 */ if (psiginfo) { *psiginfo = siginfo; } return (siginfo.si_signo); } if (ulTimeout == LW_OPTION_NOT_WAIT) { /* 不进行等待 */ __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(EAGAIN); return (PX_ERROR); } iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_SIGNAL; /* 等待信号 */ ptcbCur->TCB_ucWaitTimeout = LW_WAIT_TIME_CLEAR; /* 清空等待时间 */ ppcb = _GetPcb(ptcbCur); __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */ if (ulTimeout != LW_OPTION_WAIT_INFINITE) { ptcbCur->TCB_ulDelay = ulTimeout; /* 设置超时时间 */ __ADD_TO_WAKEUP_LINE(ptcbCur); /* 加入等待扫描链 */ } else { ptcbCur->TCB_ulDelay = 0ul; } KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ sigwt.SIGWT_sigset = *psigset; psigctx->SIGCTX_sigwait = &sigwt; /* 保存等待信息 */ if (__KERNEL_EXIT()) { /* 是否其他信号激活 */ psigctx->SIGCTX_sigwait = LW_NULL; _ErrorHandle(EINTR); /* SA_RESTART 也退出 */ return (PX_ERROR); } __KERNEL_ENTER(); /* 进入内核 */ if (ptcbCur->TCB_ucWaitTimeout == LW_WAIT_TIME_OUT) { /* 等待超时 */ __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(EAGAIN); return (PX_ERROR); } __KERNEL_EXIT(); /* 退出内核 */ psigctx->SIGCTX_sigwait = LW_NULL; if (psiginfo) { *psiginfo = sigwt.SIGWT_siginfo; } return (sigwt.SIGWT_siginfo.si_signo); }
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); }
LW_API ULONG API_MsgQueueReceive (LW_OBJECT_HANDLE ulId, PVOID pvMsgBuffer, size_t stMaxByteSize, size_t *pstMsgLen, ULONG ulTimeout) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER UINT16 usIndex; REGISTER PLW_CLASS_EVENT pevent; REGISTER PLW_CLASS_MSGQUEUE pmsgqueue; REGISTER UINT8 ucPriorityIndex; REGISTER PLW_LIST_RING *ppringList; ULONG ulTimeSave; /* 系统事件记录 */ INT iSchedRet; ULONG ulEventOption; /* 事件创建选项 */ size_t stMsgLenTemp; /* 临时记录变量 */ 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 (pstMsgLen == LW_NULL) { pstMsgLen = &stMsgLenTemp; /* 临时变量记录消息长短 */ } __wait_again: #if LW_CFG_ARG_CHK_EN > 0 if (!pvMsgBuffer || !stMaxByteSize) { _DebugHandle(__ERRORMESSAGE_LEVEL, "pvMsgBuffer invalidate.\r\n"); _ErrorHandle(ERROR_MSGQUEUE_MSG_NULL); return (ERROR_MSGQUEUE_MSG_NULL); } if (!_ObjectClassOK(ulId, _OBJECT_MSGQUEUE)) { _DebugHandle(__ERRORMESSAGE_LEVEL, "msgqueue handle invalidate.\r\n"); _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); } if (_Event_Index_Invalid(usIndex)) { _DebugHandle(__ERRORMESSAGE_LEVEL, "msgqueue handle invalidate.\r\n"); _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); } #endif pevent = &_K_eventBuffer[usIndex]; iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核 */ if (_Event_Type_Invalid(usIndex, LW_TYPE_EVENT_MSGQUEUE)) { __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "msgqueue handle invalidate.\r\n"); _ErrorHandle(ERROR_MSGQUEUE_TYPE); return (ERROR_MSGQUEUE_TYPE); } pmsgqueue = (PLW_CLASS_MSGQUEUE)pevent->EVENT_pvPtr; ptcbCur->TCB_ulRecvOption = LW_OPTION_NOERROR; /* 接收大消息自动截断 */ if (pevent->EVENT_ulCounter) { /* 事件有效 */ pevent->EVENT_ulCounter--; _MsgQueueGetMsg(pmsgqueue, pvMsgBuffer, stMaxByteSize, pstMsgLen); /* 获得消息 */ __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核 */ return (ERROR_NONE); } if (ulTimeout == LW_OPTION_NOT_WAIT) { /* 不等待 */ __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核 */ _ErrorHandle(ERROR_THREAD_WAIT_TIMEOUT); /* 超时 */ return (ERROR_THREAD_WAIT_TIMEOUT); } ptcbCur->TCB_pstMsgByteSize = pstMsgLen; ptcbCur->TCB_stMaxByteSize = stMaxByteSize; ptcbCur->TCB_pvMsgQueueMessage = pvMsgBuffer; /* 记录信息 */ ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_MSGQUEUE; /* 写状态位,开始等待 */ ptcbCur->TCB_ucWaitTimeout = LW_WAIT_TIME_CLEAR; /* 清空等待时间 */ if (ulTimeout == LW_OPTION_WAIT_INFINITE) { /* 是否是无穷等待 */ ptcbCur->TCB_ulDelay = 0ul; } else { ptcbCur->TCB_ulDelay = ulTimeout; /* 设置超时时间 */ } __KERNEL_TIME_GET_NO_SPINLOCK(ulTimeSave, ULONG); /* 记录系统时间 */ if (pevent->EVENT_ulOption & LW_OPTION_WAIT_PRIORITY) { _EVENT_INDEX_Q_PRIORITY(ptcbCur->TCB_ucPriority, ucPriorityIndex); _EVENT_PRIORITY_Q_PTR(ppringList, ucPriorityIndex); ptcbCur->TCB_ppringPriorityQueue = ppringList; /* 记录等待队列位置 */ _EventWaitPriority(pevent, ppringList); /* 加入优先级等待表 */ } else { /* 按 FIFO 等待 */ _EVENT_FIFO_Q_PTR(ppringList); /* 确定 FIFO 队列的位置 */ _EventWaitFifo(pevent, ppringList); /* 加入 FIFO 等待表 */ } KN_INT_ENABLE(iregInterLevel); /* 使能中断 */ ulEventOption = pevent->EVENT_ulOption; MONITOR_EVT_LONG2(MONITOR_EVENT_ID_MSGQ, MONITOR_EVENT_MSGQ_PEND, ulId, ulTimeout, LW_NULL); iSchedRet = __KERNEL_EXIT(); /* 调度器解锁 */ if (iSchedRet == LW_SIGNAL_EINTR) { if (ulEventOption & LW_OPTION_SIGNAL_INTER) { _ErrorHandle(EINTR); return (EINTR); } ulTimeout = _sigTimeoutRecalc(ulTimeSave, ulTimeout); /* 重新计算超时时间 */ goto __wait_again; } else if (iSchedRet == LW_SIGNAL_RESTART) { ulTimeout = _sigTimeoutRecalc(ulTimeSave, ulTimeout); /* 重新计算超时时间 */ goto __wait_again; } if (ptcbCur->TCB_ucWaitTimeout == LW_WAIT_TIME_OUT) { iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核 */ if (ptcbCur->TCB_ucWaitTimeout == LW_WAIT_TIME_CLEAR) { /* 是否在上面瞬间被激活 */ __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核 */ return (ERROR_NONE); } if (pevent->EVENT_ulOption & LW_OPTION_WAIT_PRIORITY) { _EventTimeoutPriority(pevent, ppringList); /* 等待超时恢复 */ } else { _EventTimeoutFifo(pevent, ppringList); /* 等待超时恢复 */ } __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核 */ _ErrorHandle(ERROR_THREAD_WAIT_TIMEOUT); /* 超时 */ return (ERROR_THREAD_WAIT_TIMEOUT); } else { if (ptcbCur->TCB_ucIsEventDelete == LW_EVENT_EXIST) { /* 事件是否存在 */ return (ERROR_NONE); } else { _ErrorHandle(ERROR_MSGQUEUE_WAS_DELETED); /* 已经被删除 */ return (ERROR_MSGQUEUE_WAS_DELETED); } } }