/********************************************************************************************************* ** 函数名称: __smpProcCallfunc ** 功能描述: 处理核间中断调用函数 ** 输 入 : pcpuCur 当前 CPU ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __smpProcCallfunc (PLW_CLASS_CPU pcpuCur) { #define LW_KERNEL_OWN_CPU() (PLW_CLASS_CPU)(_K_klKernel.KERN_pvCpuOwner) UINT i, uiCnt; PLW_IPI_MSG pipim; PLW_LIST_RING pringTemp; PLW_LIST_RING pringDelete; VOIDFUNCPTR pfuncAsync; PVOID pvAsync; LW_SPIN_LOCK_IGNIRQ(&pcpuCur->CPU_slIpi); /* 锁定 CPU */ pringTemp = pcpuCur->CPU_pringMsg; uiCnt = pcpuCur->CPU_uiMsgCnt; for (i = 0; i < uiCnt; i++) { _BugHandle((!pcpuCur->CPU_pringMsg), LW_TRUE, "ipi call func error!\r\n"); pipim = _LIST_ENTRY(pringTemp, LW_IPI_MSG, IPIM_ringManage); if ((LW_KERNEL_OWN_CPU() == pcpuCur) && (pipim->IPIM_iOption & IPIM_OPT_NOKERN)) { /* 此函数不能再内核锁定状态执行*/ pringTemp = _list_ring_get_next(pringTemp); continue; } pringDelete = pringTemp; pringTemp = _list_ring_get_next(pringTemp); _List_Ring_Del(pringDelete, &pcpuCur->CPU_pringMsg); /* 删除一个节点 */ pcpuCur->CPU_uiMsgCnt--; if (pipim->IPIM_pfuncCall) { pipim->IPIM_iRet = pipim->IPIM_pfuncCall(pipim->IPIM_pvArg);/* 执行同步调用 */ } pfuncAsync = pipim->IPIM_pfuncAsyncCall; pvAsync = pipim->IPIM_pvAsyncArg; KN_SMP_MB(); pipim->IPIM_iWait = 0; /* 调用结束 */ KN_SMP_WMB(); LW_SPINLOCK_NOTIFY(); if (pfuncAsync) { pfuncAsync(pvAsync); /* 执行异步调用 */ } } KN_SMP_MB(); if (pcpuCur->CPU_pringMsg == LW_NULL) { LW_CPU_CLR_IPI_PEND2(pcpuCur, LW_IPI_CALL_MSK); /* 清除 */ } LW_SPIN_UNLOCK_IGNIRQ(&pcpuCur->CPU_slIpi); /* 解锁 CPU */ LW_SPINLOCK_NOTIFY(); }
/********************************************************************************************************* ** 函数名称: __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); }
/********************************************************************************************************* ** 函数名称: __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_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); /* 理论上是无法运行到这里的 */ }
/********************************************************************************************************* ** 函数名称: 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); }