Beispiel #1
0
/*********************************************************************************************************
** 函数名称: __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--;
        }
    }
}
Beispiel #2
0
/*********************************************************************************************************
** 函数名称: API_PciDevHandleGet
** 功能描述: 获取一个设备的句柄
** 输 入  : iBus           总线号
**           iDevice        设备号
**           iFunction      功能号
** 输 出  : 设备控制句柄
** 全局变量:
** 调用模块:
                                           API 函数
*********************************************************************************************************/
LW_API
PCI_DEV_HANDLE  API_PciDevHandleGet (INT  iBus, INT  iDevice, INT  iFunction)
{
    PLW_LIST_LINE       plineTemp  = LW_NULL;
    PCI_DEV_HANDLE      hDevHandle = LW_NULL;

    hDevHandle = LW_NULL;
    __PCI_DEV_LOCK();
    for (plineTemp  = _GplinePciDevHeader;
         plineTemp != LW_NULL;
         plineTemp  = _list_line_get_next(plineTemp)) {
        hDevHandle = _LIST_ENTRY(plineTemp, PCI_DEV_TCB, PDT_lineDevNode);
        if ((hDevHandle->PDT_iDevBus      == iBus     ) &&
            (hDevHandle->PDT_iDevDevice   == iDevice  ) &&
            (hDevHandle->PDT_iDevFunction == iFunction)) {
            break;
        }
    }
    __PCI_DEV_UNLOCK();

    if (plineTemp) {
        return  (hDevHandle);
    } else {
        return  (LW_NULL);
    }
}
Beispiel #3
0
/*********************************************************************************************************
** 函数名称: _ThreadUnwaitStatus
** 功能描述: 从等待目标线程状态设置链表中退出, 并激活其他任务等待我的状态改变.(进入内核并关中断状态被调用)
** 输 入  : ptcbCur       当前线程控制块
**           ptcbDest      目标线程控制块
**           uiStatusReq   请求改变的
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
** 注  意  : 这里只是退出链表, 并不操作就续表.
*********************************************************************************************************/
VOID  _ThreadUnwaitStatus (PLW_CLASS_TCB  ptcb)
{
    PLW_CLASS_TCB  ptcbDest = ptcb->TCB_ptcbWaitStatus;
    PLW_CLASS_TCB  ptcbWait;
    PLW_CLASS_PCB  ppcb;

    if (ptcbDest) {
        _List_Line_Del(&ptcb->TCB_lineStatusPend, 
                       &ptcbDest->TCB_plineStatusReqHeader);
                       
        ptcb->TCB_ptcbWaitStatus    = LW_NULL;
        ptcb->TCB_uiStatusChangeReq = 0;
    }
    
    while (ptcb->TCB_plineStatusReqHeader) {                            /*  有其他线程请求              */
        ptcbWait = _LIST_ENTRY(ptcb->TCB_plineStatusReqHeader, 
                               LW_CLASS_TCB, 
                               TCB_lineStatusPend);
        ptcbWait->TCB_ptcbWaitStatus = LW_NULL;
        
        _List_Line_Del(&ptcbWait->TCB_lineStatusPend, 
                       &ptcb->TCB_plineStatusReqHeader);
        
        if (!__LW_THREAD_IS_READY(ptcbWait)) {                          /*  如果没有就绪, 取消 WSTAT    */
            ptcbWait->TCB_usStatus &= ~LW_THREAD_STATUS_WSTAT;
            if (__LW_THREAD_IS_READY(ptcbWait)) {
                ptcbWait->TCB_ucSchedActivate = LW_SCHED_ACT_INTERRUPT; /*  中断激活方式                */
                ppcb = _GetPcb(ptcbWait);
                __ADD_TO_READY_RING(ptcbWait, ppcb);
            }
        }
    }
}
Beispiel #4
0
/*********************************************************************************************************
** 函数名称: API_InterVectorDisconnect
** 功能描述: 解除系统指定向量中断服务
** 输 入  : ulVector                      中断向量号
**           pfuncIsr                      服务函数
**           pvArg                         服务函数参数
** 输 出  : ERROR CODE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API
ULONG  API_InterVectorDisconnect (ULONG             ulVector,
                                  PINT_SVR_ROUTINE  pfuncIsr,
                                  PVOID             pvArg)
{
    INTREG              iregInterLevel;
    BOOL                bNeedFree = LW_FALSE;
    
    PLW_LIST_LINE       plineTemp;
    PLW_CLASS_INTACT    piaction;
    PLW_CLASS_INTDESC   pidesc;

    if (LW_CPU_GET_CUR_NESTING()) {                                     /*  不能在中断中调用            */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n");
        _ErrorHandle(ERROR_KERNEL_IN_ISR);
        return  (ERROR_KERNEL_IN_ISR);
    }
    
    INTER_SHOWLOCK_CREATE();

    if (_Inter_Vector_Invalid(ulVector)) {
        _ErrorHandle(ERROR_KERNEL_VECTOR_NULL);
        return  (ERROR_KERNEL_VECTOR_NULL);
    }
    
    if (pfuncIsr == LW_NULL) {
        _ErrorHandle(ERROR_KERNEL_VECTOR_NULL);
        return  (ERROR_KERNEL_VECTOR_NULL);
    }
    
    INTER_SHOWLOCK_LOCK();

    pidesc = LW_IVEC_GET_IDESC(ulVector);

    LW_SPIN_LOCK_QUICK(&pidesc->IDESC_slLock, &iregInterLevel);         /*  关闭中断同时锁住 spinlock   */
    
    for (plineTemp  = pidesc->IDESC_plineAction;
         plineTemp != LW_NULL;
         plineTemp  = _list_line_get_next(plineTemp)) {
         
        piaction = _LIST_ENTRY(plineTemp, LW_CLASS_INTACT, IACT_plineManage);
        if ((piaction->IACT_pfuncIsr == pfuncIsr) &&
            (piaction->IACT_pvArg    == pvArg)) {
            _List_Line_Del(&piaction->IACT_plineManage,
                           &pidesc->IDESC_plineAction);
            bNeedFree = LW_TRUE;
            break;
        }
    }
    
    LW_SPIN_UNLOCK_QUICK(&pidesc->IDESC_slLock, iregInterLevel);        /*  打开中断, 同时打开 spinlock */
    
    INTER_SHOWLOCK_UNLOCK();
    
    if (bNeedFree) {
        __KHEAP_FREE(piaction);
    }
    
    return  (ERROR_NONE);
}
Beispiel #5
0
/*********************************************************************************************************
** 函数名称: __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);
}
Beispiel #6
0
/*********************************************************************************************************
** 函数名称: API_HotplugPollDelete
** 功能描述: 从 hotplug 事件处理上下文中, 删除一个循环检测函数.
** 输 入  : pfunc                      函数指针
**           pvArg                      函数参数
** 输 出  : 操作是否成功
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
INT  API_HotplugPollDelete (VOIDFUNCPTR   pfunc, PVOID  pvArg)
{
    PLW_HOTPLUG_POLLNODE        phppn = LW_NULL;
    PLW_LIST_LINE               plineTemp;
    
    __HOTPLUG_LOCK();                                                   /*  lock hotplug poll list      */
    for (plineTemp  = _G_plineHotplugPoll;
         plineTemp != LW_NULL;
         plineTemp  = _list_line_get_next(plineTemp)) {
         
        phppn = _LIST_ENTRY(plineTemp, LW_HOTPLUG_POLLNODE, HPPN_lineManage);
        if ((phppn->HPPN_pfunc == pfunc) &&
            (phppn->HPPN_pvArg == pvArg)) {
            _List_Line_Del(&phppn->HPPN_lineManage, &_G_plineHotplugPoll);
            break;
        }
    }
    __HOTPLUG_UNLOCK();                                                 /*  unlock hotplug poll list    */
    
    if (plineTemp != LW_NULL) {
        __resDelRawHook(&phppn->HPPN_resraw);
        __SHEAP_FREE(phppn);
        return  (ERROR_NONE);
    }
    
    _ErrorHandle(ERROR_HOTPLUG_POLL_NODE_NULL);
    return  (PX_ERROR);
}
Beispiel #7
0
/*********************************************************************************************************
** 函数名称: _hotplugDevPutMsg
** 功能描述: 产生一条 hotplug 消息
** 输 入  : iMsg      信息类型
**           pvMsg     需要保存的消息
**           stSize    消息长度.
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
VOID  _hotplugDevPutMsg (INT  iMsg, CPVOID pvMsg, size_t stSize)
{
    PLW_LIST_LINE       plineTemp;
    PLW_HOTPLUG_FILE    photplugfil;
    BOOL                bWakeup = LW_FALSE;
    
    if ((_G_hotplugdev.HOTPDEV_ulMutex   == LW_OBJECT_HANDLE_INVALID) ||
        (_G_hotplugdev.HOTPDEV_plineFile == LW_NULL)) {
        return;
    }
    
    HOTPLUG_DEV_LOCK();
    for (plineTemp  = _G_hotplugdev.HOTPDEV_plineFile;
         plineTemp != LW_NULL;
         plineTemp  = _list_line_get_next(plineTemp)) {
        
        photplugfil = _LIST_ENTRY(plineTemp, LW_HOTPLUG_FILE, HOTPFIL_lineManage);
        if ((photplugfil->HOTPFIL_iMsg == iMsg) ||
            (photplugfil->HOTPFIL_iMsg == LW_HOTPLUG_MSG_ALL)) {
            _bmsgPut(photplugfil->HOTPFIL_pbmsg, pvMsg, stSize);
            API_SemaphoreBPost(photplugfil->HOTPFIL_ulReadSync);
            bWakeup = LW_TRUE;
        }
    }
    HOTPLUG_DEV_UNLOCK();
    
    if (bWakeup) {
        SEL_WAKE_UP_ALL(&_G_hotplugdev.HOTPDEV_selwulList, SELREAD);
    }
}
Beispiel #8
0
VOID  _WatchDogTick (VOID)
{
             INTREG                 iregInterLevel;
    REGISTER PLW_CLASS_TCB          ptcb;
             PLW_CLASS_WAKEUP_NODE  pwun;
             ULONG                  ulCounter = 1;
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核同时关闭中断        */
    
    __WAKEUP_PASS_FIRST(&_K_wuWatchDog, pwun, ulCounter);
    
    ptcb = _LIST_ENTRY(pwun, LW_CLASS_TCB, TCB_wunWatchDog);
    
    __DEL_FROM_WATCHDOG_LINE(ptcb);                                     /*  从扫描链表中删除            */
    
    KN_INT_ENABLE(iregInterLevel);
    
    bspWdTimerHook(ptcb->TCB_ulId);
    __LW_WATCHDOG_TIMER_HOOK(ptcb->TCB_ulId);                           /*  执行回调函数                */
    
    iregInterLevel = KN_INT_DISABLE();
    
    __WAKEUP_PASS_SECOND();
    
    KN_INT_ENABLE(iregInterLevel);                                      /*  这里允许响应中断            */
    
    iregInterLevel = KN_INT_DISABLE();
    
    __WAKEUP_PASS_END();
    
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核同时打开中断        */
}
Beispiel #9
0
/*********************************************************************************************************
** 函数名称: __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();
}
Beispiel #10
0
/*********************************************************************************************************
** 函数名称: _dmaGetFirstInWaitList
** 功能描述: 从指定 DMA 通道的获得等待队列中第一个节点, 但是不删除.
** 输 入  : pdmanNode     要删除的节点.
** 输 出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
__PDMA_WAITNODE     _dmaGetFirstInWaitList (__PDMA_CHANNEL    pdmacChannel)
{
    REGISTER __PDMA_WAITNODE   pdmanNode;
    REGISTER PLW_LIST_RING     pringNode;

    pringNode = pdmacChannel->DMAC_pringHead;
    if (pringNode) {
        pdmanNode = _LIST_ENTRY(pringNode, __DMA_WAITNODE, DMAN_ringManage);
        return  (pdmanNode);
    } else {
        return  (LW_NULL);
    }
}
Beispiel #11
0
/*********************************************************************************************************
** 函数名称: _ThreadStatusChangeCur
** 功能描述: 改变当前线程状态 (内核状态且关闭中断状态被调用)
** 输 入  : ptcbCur       当前 CPU
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
** 注  意  : 
*********************************************************************************************************/
VOID  _ThreadStatusChangeCur (PLW_CLASS_CPU    pcpuCur)
{
    PLW_CLASS_TCB  ptcbCur;
    PLW_CLASS_TCB  ptcb;
    PLW_CLASS_PCB  ppcb;

    ptcbCur = pcpuCur->CPU_ptcbTCBCur;                                  /*  当前线程                    */

    if (ptcbCur->TCB_plineStatusReqHeader) {                            /*  需要阻塞                    */
        if (__LW_THREAD_IS_READY(ptcbCur)) {
            ppcb = _GetPcb(ptcbCur);
            __DEL_FROM_READY_RING(ptcbCur, ppcb);                       /*  从就绪表中删除              */
        }
        
        do {
            ptcb = _LIST_ENTRY(ptcbCur->TCB_plineStatusReqHeader, LW_CLASS_TCB, TCB_lineStatusPend);
            
            switch (ptcb->TCB_uiStatusChangeReq) {
            
            case LW_TCB_REQ_SUSPEND:
                ptcbCur->TCB_ulSuspendNesting++;
                ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_SUSPEND;
                break;
                
            case LW_TCB_REQ_STOP:
                ptcbCur->TCB_ulStopNesting++;
                ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_STOP;
                break;
                
            case LW_TCB_REQ_WDEATH:
                ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_WDEATH;
                break;
            }
            
            ptcb->TCB_ptcbWaitStatus    = LW_NULL;
            ptcb->TCB_uiStatusChangeReq = 0;                            /*  请求修改的状态成功          */
            
            _List_Line_Del(&ptcb->TCB_lineStatusPend, 
                           &ptcbCur->TCB_plineStatusReqHeader);
            
            if (!__LW_THREAD_IS_READY(ptcb)) {                          /*  如果没有就绪, 取消 WSTAT    */
                ptcb->TCB_usStatus &= ~LW_THREAD_STATUS_WSTAT;
                if (__LW_THREAD_IS_READY(ptcb)) {
                    ptcb->TCB_ucSchedActivate = LW_SCHED_ACT_INTERRUPT; /*  中断激活方式                */
                    ppcb = _GetPcb(ptcb);
                    __ADD_TO_READY_RING(ptcb, ppcb);
                }
            }
        } while (ptcbCur->TCB_plineStatusReqHeader);
    }
}
/*********************************************************************************************************
** 函数名称: 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);
}
Beispiel #13
0
/*********************************************************************************************************
** 函数名称: _dmaWaitnodeAlloc
** 功能描述: 从缓冲区中申请一个 DMA 等待节点
** 输 入  : NONE
** 输 出  : 新申请出的节点, 缓冲区内没有空闲接点时, 返回 LW_NULL;
** 全局变量:
** 调用模块:
*********************************************************************************************************/
__PDMA_WAITNODE     _dmaWaitnodeAlloc (VOID)
{
    REGISTER PLW_LIST_RING      pringNewNode;
    REGISTER __PDMA_WAITNODE    pdmanNewNode;

    if (_G_pringDmanFreeHeader) {                                       /*  还存在空闲的节点            */
        pringNewNode = _G_pringDmanFreeHeader;
        _List_Ring_Del(_G_pringDmanFreeHeader,
                       &_G_pringDmanFreeHeader);                         /*  删除表头的节点              */
        pdmanNewNode = _LIST_ENTRY(pringNewNode, __DMA_WAITNODE, DMAN_ringManage);
        return  (pdmanNewNode);                                         /*  返回新节点                  */
    } else {
        return  (LW_NULL);                                              /*  没有新节点了                */
    }
}
Beispiel #14
0
/*********************************************************************************************************
** 函数名称: __ram_unlink_dir
** 功能描述: ramfs 删除一个目录
** 输 入  : plineDir         目录头链表
** 输 出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static VOID  __ram_unlink_dir (LW_LIST_LINE_HEADER plineDir)
{
    PLW_LIST_LINE   plineTemp;
    PRAM_NODE       pramn;
    
    while (plineDir) {
        plineTemp = plineDir;
        plineDir  = _list_line_get_next(plineDir);
        pramn     = _LIST_ENTRY(plineTemp, RAM_NODE, RAMN_lineBrother);
        if (S_ISDIR(pramn->RAMN_mode) && pramn->RAMN_plineSon) {        /*  目录文件                    */
            __ram_unlink_dir(pramn->RAMN_plineSon);                     /*  递归删除子目录              */
        }
        __ram_unlink(pramn);
    }
}
Beispiel #15
0
/*********************************************************************************************************
** 函数名称: __tshellReadlineClean
** 功能描述: shell 退出时清除 readline 信息.
** 输 入  : ulId                          线程 ID
**           pvRetVal                      返回值
**           ptcbDel                       删除的 TCB
** 输 出  : 读取个数
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  __tshellReadlineClean (LW_OBJECT_HANDLE  ulId, PVOID  pvRetVal, PLW_CLASS_TCB  ptcbDel)
{
    __PSHELL_HISTORY_CTX    psihc = __TTINY_SHELL_GET_HIS(ptcbDel);
    __PSHELL_HISTORY        psihHistory;
    
    if (psihc) {
        while (psihc->SIHC_pringHeader) {
            psihHistory = _LIST_ENTRY(psihc->SIHC_pringHeader, __SHELL_HISTORY, SIH_ringManage);
            _List_Ring_Del(&psihHistory->SIH_ringManage, 
                           &psihc->SIHC_pringHeader);
            __SHEAP_FREE(psihHistory);
        }
        
        __SHEAP_FREE(psihc);
        __TTINY_SHELL_SET_HIS(ptcbDel, LW_NULL);
    }
}
Beispiel #16
0
/*********************************************************************************************************
** 函数名称: _CoroutineDeleteAll
** 功能描述: 释放指定线程所有的协程空间.
** 输 入  : ptcb                     线程控制块
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  _CoroutineFreeAll (PLW_CLASS_TCB    ptcb)
{
    REGISTER PLW_CLASS_COROUTINE    pcrcbTemp;
    REGISTER PLW_LIST_RING          pringTemp;
    
    pringTemp = ptcb->TCB_pringCoroutineHeader;
    
    while (pringTemp) {
        _List_Ring_Del(pringTemp,
                       &ptcb->TCB_pringCoroutineHeader);                /*  从协程表中删除              */
        pcrcbTemp = _LIST_ENTRY(pringTemp, 
                                LW_CLASS_COROUTINE,
                                COROUTINE_ringRoutine);
        if (pcrcbTemp->COROUTINE_bIsNeedFree) {
            _StackFree(ptcb, pcrcbTemp->COROUTINE_pstkStackLowAddr, LW_TRUE);
        }
        pringTemp = ptcb->TCB_pringCoroutineHeader;
    }
}
Beispiel #17
0
/*********************************************************************************************************
** 函数名称: _ThreadTick
** 功能描述: 扫描等待唤醒链表, tick 处理函数
** 输 入  : NONE
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  _ThreadTick (VOID)
{
             INTREG                 iregInterLevel;
    REGISTER PLW_CLASS_TCB          ptcb;
    REGISTER PLW_CLASS_PCB          ppcb;
             PLW_CLASS_WAKEUP_NODE  pwun;
             ULONG                  ulCounter = 1;
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核同时关闭中断        */
    
    __WAKEUP_PASS_FIRST(&_K_wuDelay, pwun, ulCounter);
    
    ptcb = _LIST_ENTRY(pwun, LW_CLASS_TCB, TCB_wunDelay);
    
    __DEL_FROM_WAKEUP_LINE(ptcb);                                       /*  从等待链中删除              */
    
    if (ptcb->TCB_usStatus & LW_THREAD_STATUS_PEND_ANY) {               /*  检查是否在等待事件          */
        ptcb->TCB_usStatus &= (~LW_THREAD_STATUS_PEND_ANY);             /*  等待超时清除事件等待位      */
        ptcb->TCB_ucWaitTimeout = LW_WAIT_TIME_OUT;                     /*  等待超时                    */
    
    } else {
        ptcb->TCB_ucWaitTimeout = LW_WAIT_TIME_CLEAR;                   /*  没有等待事件                */
    }
    
    if (__LW_THREAD_IS_READY(ptcb)) {                                   /*  检查是否就绪                */
        ptcb->TCB_ucSchedActivate = LW_SCHED_ACT_OTHER;
        ppcb = _GetPcb(ptcb);                                           /*  获得优先级控制块            */
        __ADD_TO_READY_RING(ptcb, ppcb);                                /*  加入就绪环                  */
    }
    
    __WAKEUP_PASS_SECOND();
    
    KN_INT_ENABLE(iregInterLevel);                                      /*  这里允许响应中断            */
    
    iregInterLevel = KN_INT_DISABLE();
    
    __WAKEUP_PASS_END();
    
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核同时打开中断        */
}
Beispiel #18
0
/*********************************************************************************************************
** 函数名称: __aioAttachWait
** 功能描述: 向指定的 aiocb 中连接 wait 信息 (这里必须锁定 _G_aioqueue)
** 输 入  : paiocb            指定的 aiocb 
**           paiowait          wait 信息
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
INT  __aioAttachWait (const struct aiocb  *paiocb, struct aiowait  *paiowait)
{
    PLW_LIST_LINE   plineTempAiorc;
    PLW_LIST_LINE   plineTempAiocb;
    
    AIO_REQ_CHAIN   *paiorc;
    struct aioreq   *paioreqTemp;
    struct aiocb    *paiocbTemp;
    
    BOOL             bIsOk = LW_FALSE;
    
    for (plineTempAiorc  = _G_aioqueue.aioq_plinework;
         plineTempAiorc != LW_NULL;
         plineTempAiorc  = _list_line_get_next(plineTempAiorc)) {
         
        paiorc = _LIST_ENTRY(plineTempAiorc, AIO_REQ_CHAIN, aiorc_line);
        if (paiorc->aiorc_fildes == paiocb->aio_fildes) {
            API_SemaphoreMPend(paiorc->aiorc_mutex, LW_OPTION_WAIT_INFINITE);
            for (plineTempAiocb  = paiorc->aiorc_plineaiocb;
                 plineTempAiocb != LW_NULL;
                 plineTempAiocb  = _list_line_get_next(plineTempAiocb)) {
                 
                paioreqTemp = _LIST_ENTRY(plineTempAiocb, struct aioreq, aioreq_line);
                paiocbTemp  = _LIST_ENTRY(paioreqTemp, struct aiocb, aio_req);
                
                if (paiocbTemp == paiocb) {
                    if (paiocbTemp->aio_pwait) {                        /*  不允许重复保存              */
                        API_SemaphoreMPost(paiorc->aiorc_mutex);
                        return  (PX_ERROR);
                    }
                    paiocbTemp->aio_pwait  = paiowait;
                    paiowait->aiowt_paiocb = paiocbTemp;
                    bIsOk = LW_TRUE;
                    break;
                }
            }
            API_SemaphoreMPost(paiorc->aiorc_mutex);
            break;
        }
    }
Beispiel #19
0
PLW_CLASS_EVENT  _Allocate_Event_Object (VOID)
{
    REGISTER PLW_LIST_MONO    pmonoFree;
    REGISTER PLW_CLASS_EVENT  peventFree;
    
    if (_LIST_MONO_IS_EMPTY(_K_resrcEvent.RESRC_pmonoFreeHeader)) {     /*  检查缓冲区是否为空          */
        return  (LW_NULL);
    }
    
    pmonoFree  = _list_mono_allocate_seq(&_K_resrcEvent.RESRC_pmonoFreeHeader, 
                                         &_K_resrcEvent.RESRC_pmonoFreeTail);
                                                                        /*  获得资源                    */
    peventFree = _LIST_ENTRY(pmonoFree, LW_CLASS_EVENT, 
                             EVENT_monoResrcList);                      /*  获得资源表容器地址          */
    
    _K_resrcEvent.RESRC_uiUsed++;
    if (_K_resrcEvent.RESRC_uiUsed > _K_resrcEvent.RESRC_uiMaxUsed) {
        _K_resrcEvent.RESRC_uiMaxUsed = _K_resrcEvent.RESRC_uiUsed;
    }
    
    return  (peventFree);
}
Beispiel #20
0
/*********************************************************************************************************
** 函数名称: _Allocate_ThreadPool_Object
** 功能描述: 从空闲 ThreadPool 控件池中取出一个空闲 ThreadPool
** 输 入  : 
** 输 出  : 获得的 ThreadPool 地址,失败返回 NULL
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
PLW_CLASS_THREADPOOL  _Allocate_ThreadPool_Object (VOID)
{
    REGISTER PLW_LIST_MONO         pmonoFree;
    REGISTER PLW_CLASS_THREADPOOL  pthreadpool;
    
    if (_LIST_MONO_IS_EMPTY(_S_resrcThreadPool.RESRC_pmonoFreeHeader)) {
        return  (LW_NULL);
    }
        
    pmonoFree   = _list_mono_allocate_seq(&_S_resrcThreadPool.RESRC_pmonoFreeHeader,
                                          &_S_resrcThreadPool.RESRC_pmonoFreeTail); 
                                                                        /*  获得资源                    */
                                          
    pthreadpool = _LIST_ENTRY(pmonoFree, LW_CLASS_THREADPOOL, TPCB_monoResrcList);
    
    _S_resrcThreadPool.RESRC_uiUsed++;
    if (_S_resrcThreadPool.RESRC_uiUsed > _S_resrcThreadPool.RESRC_uiMaxUsed) {
        _S_resrcThreadPool.RESRC_uiMaxUsed = _S_resrcThreadPool.RESRC_uiUsed;
    }

    return  (pthreadpool);
}
Beispiel #21
0
/*********************************************************************************************************
** 函数名称: _Allocate_Heap_Object
** 功能描述: 从空闲 Heap 控件池中取出一个空闲 Heap
** 输 入  : 
** 输 出  : 获得的 Heap 地址,失败返回 NULL
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
PLW_CLASS_HEAP  _Allocate_Heap_Object (VOID)
{
    REGISTER PLW_LIST_MONO    pmonoFree;
    REGISTER PLW_CLASS_HEAP   pheapFree;
    
    if (_LIST_MONO_IS_EMPTY(_K_resrcHeap.RESRC_pmonoFreeHeader)) {
        return  (LW_NULL);
    }
    
    pmonoFree = _list_mono_allocate_seq(&_K_resrcHeap.RESRC_pmonoFreeHeader, 
                                        &_K_resrcHeap.RESRC_pmonoFreeTail);
                                                                        /*  获得资源                   */
    pheapFree = _LIST_ENTRY(pmonoFree, LW_CLASS_HEAP, 
                            HEAP_monoResrcList);                        /*  获得资源表容器地址         */
    
    _K_resrcHeap.RESRC_uiUsed++;
    if (_K_resrcHeap.RESRC_uiUsed > _K_resrcHeap.RESRC_uiMaxUsed) {
        _K_resrcHeap.RESRC_uiMaxUsed = _K_resrcHeap.RESRC_uiUsed;
    }
    
    return  (pheapFree);
}
Beispiel #22
0
/*********************************************************************************************************
** 函数名称: __aioSearchFd
** 功能描述: 从指定的 AIO_REQ_CHAIN 中搜索与指定文件描述符相同的 aio req chain 节点. 
             (这里必须锁定 _G_aioqueue)
** 输 入  : plineHeader       搜索链表头
**           iFd               文件描述符
** 输 出  : 查找到的 aio req chain 节点
** 全局变量: 
** 调用模块: 
** 注  意  : 这个函数 search 到的 aiorc 都是没有被 cancel 的. 如果被 cancel 了, 一定会有代理线程将 cancel
             的 aiorc 删除. 
*********************************************************************************************************/
AIO_REQ_CHAIN  *__aioSearchFd (LW_LIST_LINE_HEADER  plineHeader, int  iFd)
{
    AIO_REQ_CHAIN  *paiorc;
    PLW_LIST_LINE   plineTemp;
    
    for (plineTemp  = plineHeader;
         plineTemp != LW_NULL;
         plineTemp  = _list_line_get_next(plineTemp)) {
         
        paiorc = _LIST_ENTRY(plineTemp, AIO_REQ_CHAIN, aiorc_line);
        if ((paiorc->aiorc_fildes == iFd) &&
            (paiorc->aiorc_iscancel == 0)) {                            /*  注意, cancel的paiorc不返回  */
            break;
        }
    }
    
    if (plineTemp) {
        return  (paiorc);
    } else {
        return  (LW_NULL);
    }
}
Beispiel #23
0
/*********************************************************************************************************
** 函数名称: __tshellPciDevCmdShow
** 功能描述: 打印 PCI 设备列表
** 输 入  : NONE
** 输 出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static
VOID  __tshellPciDevCmdShow (VOID)
{
    static PCHAR        pcPciDevShowHdr = \
    " INDEX   BUS   DEV   FUNC  VENDOR DEVICE  SUBV   SUBD           DRVNAME\n"
    "------- ----- ----- ------ ------ ------ ------ ------ ------------------------\n";

    PLW_LIST_LINE       plineTemp  = LW_NULL;
    PCI_DEV_HANDLE      hDevHandle = LW_NULL;
    PCI_DRV_HANDLE      hDrvHandle = LW_NULL;
    REGISTER INT        i;

    printf("pci dev number total : %d\n", _GuiPciDevTotalNum);
    printf(pcPciDevShowHdr);

    __PCI_DEV_LOCK();
    i = 0;
    for (plineTemp  = _GplinePciDevHeader;
         plineTemp != LW_NULL;
         plineTemp  = _list_line_get_next(plineTemp)) {
        hDevHandle = _LIST_ENTRY(plineTemp, PCI_DEV_TCB, PDT_lineDevNode);
        hDrvHandle = (PCI_DRV_HANDLE)hDevHandle->PDT_pvDevDriver;
        printf("%7d %5d %5d %6d %6x %6x %6x %6x %-24s\n",
               i,
               hDevHandle->PDT_iDevBus,
               hDevHandle->PDT_iDevDevice,
               hDevHandle->PDT_iDevFunction,
               hDevHandle->PDT_phDevHdr.PCIH_pcidHdr.PCID_usVendorId,
               hDevHandle->PDT_phDevHdr.PCIH_pcidHdr.PCID_usDeviceId,
               hDevHandle->PDT_phDevHdr.PCIH_pcidHdr.PCID_usSubVendorId,
               hDevHandle->PDT_phDevHdr.PCIH_pcidHdr.PCID_usSubSystemId,
               ((hDrvHandle == LW_NULL) ? "NULL" : hDrvHandle->PDT_cDrvName));
        i += 1;
    }
    __PCI_DEV_UNLOCK();

    fflush(stdout);                                                     /*  清空输出                    */
}
Beispiel #24
0
/*********************************************************************************************************
** 函数名称: API_PciDevDelete
** 功能描述: 删除一个 PCI 设备
** 输 入  : hHandle       设备控制句柄
** 输 出  : ERROR or OK
** 全局变量:
** 调用模块:
                                           API 函数
*********************************************************************************************************/
LW_API
INT  API_PciDevDelete (PCI_DEV_HANDLE  hHandle)
{
    PLW_LIST_LINE       plineTemp  = LW_NULL;
    PCI_DEV_HANDLE      hDevHandle = LW_NULL;

    if (hHandle == LW_NULL) {
        __PCI_DEV_LOCK();
        for (plineTemp  = _GplinePciDevHeader;
             plineTemp != LW_NULL;
             plineTemp  = _list_line_get_next(plineTemp)) {
            hDevHandle = _LIST_ENTRY(plineTemp, PCI_DEV_TCB, PDT_lineDevNode);
            _List_Line_Del(&hDevHandle->PDT_lineDevNode, &_GplinePciDevHeader);
            _GuiPciDevTotalNum -= 1;
            __SHEAP_FREE(hDevHandle);
        }
        __PCI_DEV_UNLOCK();

        return  (ERROR_NONE);
    }

    hDevHandle = API_PciDevHandleGet(hHandle->PDT_iDevBus,
                                     hHandle->PDT_iDevDevice,
                                     hHandle->PDT_iDevFunction);
    if ((hDevHandle == LW_NULL) ||
        (hDevHandle != hHandle)) {
        return  (PX_ERROR);
    }

    __PCI_DEV_LOCK();
    _List_Line_Del(&hHandle->PDT_lineDevNode, &_GplinePciDevHeader);
    _GuiPciDevTotalNum -= 1;
    __PCI_DEV_UNLOCK();

    __SHEAP_FREE(hHandle);

    return  (ERROR_NONE);
}
Beispiel #25
0
/*********************************************************************************************************
** 函数名称: __selPtyAdd 
** 功能描述: 向指定的 pty wake up list 添加一个等待节点. (ioctl FIOSELECT 使用)
** 输 入  : p_ptyddev          Ty 虚拟设备控制块
             lArg               select wake up node 控制结构
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID    __selPtyAdd (P_PTY_D_DEV   p_ptyddev, LONG  lArg)
{
    REGISTER TY_DEV_ID            ptyDev;
    REGISTER PLW_SEL_WAKEUPNODE   pselwunNode = (PLW_SEL_WAKEUPNODE)lArg;
    REGISTER P_PTY_H_DEV          p_ptyhdev   = (P_PTY_H_DEV)_LIST_ENTRY(p_ptyddev, 
                                                PTY_DEV, 
                                                PTYDEV_ptyddev);        /*  获得 HOST 端口              */
                                                     
    ptyDev = &p_ptyhdev->PTYHDEV_tydevTyDev;
    
    SEL_WAKE_NODE_ADD(&p_ptyddev->PTYDDEV_selwulList, pselwunNode);     /*  添加节点                    */
    
    switch (pselwunNode->SELWUN_seltypType) {
    
    case SELREAD:                                                       /*  等待数据可读                */
        if ((rngNBytes(ptyDev->TYDEV_vxringidWrBuf) > 0) ||
            (ptyDev->TYDEV_tydevwrstat.TYDEVWRSTAT_bCR)) {
            SEL_WAKE_UP(pselwunNode);                                   /*  检测主机是否有数据需要发送  */
        } else {
            ptyDev->TYDEV_tydevwrstat.TYDEVWRSTAT_bBusy = LW_FALSE;     /*  确保可以被 Startup 激活     */
        }
        break;
    
    case SELWRITE:                                                      /*  等待数据可写                */
        if (rngFreeBytes(ptyDev->TYDEV_vxringidRdBuf) > 0) {            /*  检测主机接收缓存是否有空间  */
            SEL_WAKE_UP(pselwunNode);                                   /*  唤醒节点                    */
        }
        break;
        
    case SELEXCEPT:                                                     /*  等待设备异常                */
        if ((LW_DEV_GET_USE_COUNT(&p_ptyddev->PTYDDEV_devhdrDevice) == 0) ||
            (LW_DEV_GET_USE_COUNT(&p_ptyhdev->PTYHDEV_tydevTyDev.TYDEV_devhdrHdr)
             == 0)) {                                                   /*  设备关闭了                  */
            SEL_WAKE_UP(pselwunNode);                                   /*  唤醒节点                    */
        }
        break;
    }
}
Beispiel #26
0
/*********************************************************************************************************
** 函数名称: _hotplugThread
** 功能描述: hotplug 事件处理线程
** 输 入  : NONE
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static VOID  _hotplugThread (VOID)
{
    ULONG  ulError;
    
    for (;;) {
        ulError = _jobQueueExec(&_G_jobqHotplug, LW_HOTPLUG_SEC * LW_TICK_HZ);
        if (ulError) {                                                  /*  需要处理轮询事件            */
            PLW_HOTPLUG_POLLNODE    phppn;
            PLW_LIST_LINE           plineTemp;
            
            __HOTPLUG_LOCK();                                           /*  lock hotplug poll list      */
            for (plineTemp  = _G_plineHotplugPoll;
                 plineTemp != LW_NULL;
                 plineTemp  = _list_line_get_next(plineTemp)) {
                
                phppn = _LIST_ENTRY(plineTemp, LW_HOTPLUG_POLLNODE, HPPN_lineManage);
                if (phppn->HPPN_pfunc) {
                    phppn->HPPN_pfunc(phppn->HPPN_pvArg);               /*  调用先前安装的循环检测函数  */
                }
            }
            __HOTPLUG_UNLOCK();                                         /*  unlock hotplug poll list    */
        }
    }
}
Beispiel #27
0
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);
}
Beispiel #28
0
/*********************************************************************************************************
** 函数名称: 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);
}
/*********************************************************************************************************
** 函数名称: 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);                                               /*  理论上是无法运行到这里的    */
}
Beispiel #30
0
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);
}