Beispiel #1
0
LW_API  
ULONG  API_CpuDown (ULONG  ulCPUId)
{
    INTREG          iregInterLevel;
    PLW_CLASS_CPU   pcpu;

    if ((ulCPUId == 0) || (ulCPUId >= LW_NCPUS)) {
        _ErrorHandle(EINVAL);
        return  (EINVAL);
    }
    
    __KERNEL_ENTER();
    pcpu = LW_CPU_GET(ulCPUId);
    if (!LW_CPU_IS_ACTIVE(pcpu) || 
        (LW_CPU_GET_IPI_PEND2(pcpu) & LW_IPI_DOWN_MSK)) {
        __KERNEL_EXIT();
        return  (ERROR_NONE);
    }
    
    LW_SPIN_LOCK_QUICK(&pcpu->CPU_slIpi, &iregInterLevel);
    LW_CPU_ADD_IPI_PEND2(pcpu, LW_IPI_DOWN_MSK);
    LW_SPIN_UNLOCK_QUICK(&pcpu->CPU_slIpi, iregInterLevel);
    
    _ThreadOffAffinity(pcpu);                                           /*  关闭与此 CPU 有关的亲和度   */
    __KERNEL_EXIT();
    
    _SmpSendIpi(ulCPUId, LW_IPI_DOWN, 0, LW_FALSE);                     /*  使用核间中断通知 CPU 停止   */
    
    return  (ERROR_NONE);
}
Beispiel #2
0
LW_API  
ULONG  API_TShellSigEvent (LW_OBJECT_HANDLE  ulShell, struct sigevent *psigevent, INT  iSigCode)
{
    REGISTER PLW_CLASS_TCB    ptcbShell;
    REGISTER PLW_CLASS_TCB    ptcbJoin;
             LW_OBJECT_HANDLE ulJoin = LW_OBJECT_HANDLE_INVALID;
             UINT16           usIndex;
    
    usIndex = _ObjectGetIndex(ulShell);
    
    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Thread_Invalid(usIndex)) {
        __KERNEL_EXIT();                                                /*  退出内核                    */
        return  (ERROR_THREAD_NULL);
    }
    
    ptcbShell = __GET_TCB_FROM_INDEX(usIndex);
    ptcbJoin  = ptcbShell->TCB_ptcbJoin;
    if (ptcbJoin) {                                                     /*  等待其他线程结束            */
        ulJoin = ptcbJoin->TCB_ulId;
    }
    __KERNEL_EXIT();                                                    /*  退出内核                    */
    
    if (ulJoin) {
        _doSigEvent(ulJoin, psigevent, iSigCode);
    
    } else {
        _doSigEvent(ulShell, psigevent, iSigCode);
    }
    
    return  (ERROR_NONE);
}
Beispiel #3
0
/*********************************************************************************************************
** 函数名称: API_TShellGetOption
** 功能描述: 获取新的 shell 选项.
** 输 入  : hTShellHandle   shell 线程
**           pulOpt          shell 选项
** 输 出  : 错误代码.
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
INT  API_TShellGetOption (LW_OBJECT_HANDLE  hTShellHandle, ULONG  *pulOpt)
{
    PLW_CLASS_TCB   ptcbShell;
    UINT16          usIndex;
    
    if (!pulOpt) {
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }
    
    usIndex = _ObjectGetIndex(hTShellHandle);
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(hTShellHandle, _OBJECT_THREAD)) {               /*  检查 ID 类型有效性          */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (PX_ERROR);
    }
#endif

    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Thread_Invalid(usIndex)) {
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (PX_ERROR);
    }
    
    ptcbShell = __GET_TCB_FROM_INDEX(usIndex);
    *pulOpt   = __TTINY_SHELL_GET_OPT(ptcbShell);
    __KERNEL_EXIT();                                                    /*  退出内核                    */
    
    return  (ERROR_NONE);
}
Beispiel #4
0
/*********************************************************************************************************
** 函数名称: API_SetLastErrorEx
** 功能描述: 设置指定任务的 errno
** 输 入  : ulId      任务 ID
**           ulError   错误号
** 输 出  : ERROR CODE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
ULONG  API_SetLastErrorEx (LW_OBJECT_HANDLE  ulId, ULONG  ulError)
{
    REGISTER UINT16             usIndex;
    REGISTER PLW_CLASS_TCB      ptcb;
    
    usIndex = _ObjectGetIndex(ulId);
    
    if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) {
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    
    if (_Thread_Index_Invalid(usIndex)) {                               /*  检查线程有效性              */
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (ERROR_THREAD_NULL);
    }
    
    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Thread_Invalid(usIndex)) {
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (ERROR_THREAD_NULL);
    }
    
    ptcb = _K_ptcbTCBIdTable[usIndex];
    
    ptcb->TCB_ulLastError = ulError;
    
    __KERNEL_EXIT();                                                    /*  退出内核                    */
    
    return  (ERROR_NONE);
}
Beispiel #5
0
/*********************************************************************************************************
** 函数名称: 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);
}
Beispiel #6
0
/*********************************************************************************************************
** 函数名称: 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);
}
LW_API  
PVOID  API_RegionGetAlign (LW_OBJECT_HANDLE  ulId, size_t  stByteSize, size_t  stAlign)
{
    REGISTER PLW_CLASS_HEAP            pheap;
    REGISTER UINT16                    usIndex;
    REGISTER PVOID                     pvAllocate;
    
    usIndex = _ObjectGetIndex(ulId);
    
    if (LW_CPU_GET_CUR_NESTING()) {                                     /*  不能在中断中调用            */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n");
        _ErrorHandle(ERROR_KERNEL_IN_ISR);
        return  (LW_NULL);
    }
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!stByteSize) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "ulByteSize invalidate\r\n");
        _ErrorHandle(ERROR_REGION_SIZE);
        return  (LW_NULL);
    }
    
    if (!_ObjectClassOK(ulId, _OBJECT_REGION)) {                        /*  对象类型检查                */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "region handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (LW_NULL);
    }
    
    if ((stAlign < sizeof(PVOID)) || (stAlign & (stAlign - 1))) {       /*  检查对齐关系                */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "iAlign invalidate.\r\n");
        _ErrorHandle(ERROR_REGION_ALIGN);
        return  (LW_NULL);
    }
    
    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Heap_Index_Invalid(usIndex)) {                                 /*  缓冲区索引检查              */
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "region handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (LW_NULL);
    }
#else
    __KERNEL_ENTER();                                                   /*  进入内核                    */
#endif

    pheap = &_K_heapBuffer[usIndex];

    __KERNEL_EXIT();                                                    /*  退出内核                    */

    pvAllocate = _HeapAllocateAlign(pheap, stByteSize, stAlign, __func__);
    
    if (!pvAllocate) {                                                  /*  是否分配成功                */
        _ErrorHandle(ERROR_REGION_NOMEM);
    }
    
    return  (pvAllocate);
}
Beispiel #8
0
/*********************************************************************************************************
** 函数名称: 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);
}
Beispiel #9
0
LW_API  
ULONG  API_RmsGetName (LW_OBJECT_HANDLE  ulId, PCHAR  pcName)
{
    REGISTER PLW_CLASS_RMS       prms;
    REGISTER UINT16              usIndex;
    
    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);
    }
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!pcName) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "name invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_PNAME_NULL);
        return  (ERROR_KERNEL_PNAME_NULL);
    }
    
    if (!_ObjectClassOK(ulId, _OBJECT_RMS)) {                           /*  对象类型检查                */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "RMS handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    
    if (_Rms_Index_Invalid(usIndex)) {                                  /*  缓冲区索引检查              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "RMS handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    
    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Rms_Type_Invalid(usIndex)) {
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "RMS handle invalidate.\r\n");
        _ErrorHandle(ERROR_RMS_NULL);
        return  (ERROR_RMS_NULL);
    }
#else
    __KERNEL_ENTER();                                                   /*  进入内核                    */
#endif

    prms = &_K_rmsBuffer[usIndex];
    
    lib_strcpy(pcName, prms->RMS_cRmsName);
    
    __KERNEL_EXIT();                                                    /*  退出内核                    */
    
    return  (ERROR_NONE);
}
Beispiel #10
0
LW_API  
ULONG  API_RegionAddMem (LW_OBJECT_HANDLE  ulId, PVOID  pvMem, size_t  stByteSize)
{
    REGISTER PLW_CLASS_HEAP            pheap;
    REGISTER UINT16                    usIndex;
    
    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);
    }
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!pvMem || !_Addresses_Is_Aligned(pvMem)) {                      /*  检查地址是否对齐            */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "pvLowAddr is not aligned.\r\n");
        _ErrorHandle(ERROR_KERNEL_MEMORY);
        return  (ERROR_KERNEL_MEMORY);
    }
    
    if (_Heap_ByteSize_Invalid(stByteSize)) {                           /*  分段太小                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "ulRegionByteSize is too low.\r\n");
        _ErrorHandle(ERROR_REGION_SIZE);
        return  (ERROR_REGION_SIZE);
    }
    
    if (!_ObjectClassOK(ulId, _OBJECT_REGION)) {                        /*  对象类型检查                */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "region handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    
    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Heap_Index_Invalid(usIndex)) {                                 /*  缓冲区索引检查              */
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "region handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
#else
    __KERNEL_ENTER();                                                   /*  进入内核                    */
#endif

    pheap = &_K_heapBuffer[usIndex];

    __KERNEL_EXIT();                                                    /*  退出内核                    */

    _HeapAddMemory(pheap, pvMem, stByteSize);
    
    return  (ERROR_NONE);
}
Beispiel #11
0
/*********************************************************************************************************
** 函数名称: 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);
}
Beispiel #12
0
/*********************************************************************************************************
** 函数名称: API_ThreadCancel
** 功能描述: 取消一个指定的线程
** 输 入  : ulId                          线程句柄
** 输 出  : ERROR_NONE or ESRCH
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
ULONG  API_ThreadCancel (LW_OBJECT_HANDLE  *pulId)
{
             INTREG                iregInterLevel;
    REGISTER LW_OBJECT_HANDLE      ulId;
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_TCB         ptcbDel;

    ulId = *pulId;
    
    usIndex = _ObjectGetIndex(ulId);
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) {                        /*  检查 ID 类型有效性          */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    
    if (_Thread_Index_Invalid(usIndex)) {                               /*  检查线程有效性              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (ERROR_THREAD_NULL);
    }
#endif

    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Thread_Invalid(usIndex)) {
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (ERROR_THREAD_NULL);
    }
    
    iregInterLevel = KN_INT_DISABLE();
    
    ptcbDel = _K_ptcbTCBIdTable[usIndex];
    if (ptcbDel->TCB_iCancelState == LW_THREAD_CANCEL_ENABLE) {         /*  允许 CANCEL                 */
        if (ptcbDel->TCB_iCancelType == LW_THREAD_CANCEL_DEFERRED) {    /*  延迟 CANCEL                 */
            ptcbDel->TCB_bCancelRequest = LW_TRUE;                      /*  目标线程进入下一个 TEST 点  */
            __KERNEL_EXIT_IRQ(iregInterLevel);                          /*  退出内核并打开中断          */
        
        } else {                                                        /*  异步取消                    */
            __KERNEL_EXIT_IRQ(iregInterLevel);                          /*  退出内核并打开中断          */
#if LW_CFG_SIGNAL_EN > 0
            kill(ulId, SIGCANCEL);                                      /*  立即发送取消信号            */
#else
            return  (API_ThreadDelete(ulId, LW_NULL));
#endif                                                                  /*  LW_CFG_SIGNAL_EN > 0        */
        }
    
    } else {
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核并打开中断          */
        _ErrorHandle(ERROR_THREAD_DISCANCEL);                           /*  不允许 CACNCEL              */
        return  (ERROR_THREAD_DISCANCEL);
    }
    
    return  (ERROR_NONE);
}
Beispiel #13
0
/*********************************************************************************************************
** 函数名称: API_ThreadIsSafe
** 功能描述: 检测目标线程是否处于安全模式.
** 输 入  : 
**           ulId         线程句柄
** 输 出  :
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
BOOL    API_ThreadIsSafe (LW_OBJECT_HANDLE    ulId)
{
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_TCB         ptcb;
	REGISTER BOOL                  bIsInSafeMode;
	
    usIndex = _ObjectGetIndex(ulId);
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) {                        /*  检查 ID 类型有效性          */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (LW_FALSE);
    }
    
    if (_Thread_Index_Invalid(usIndex)) {                               /*  检查线程有效性              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (LW_FALSE);
    }
#endif

    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Thread_Invalid(usIndex)) {
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (LW_FALSE);
    }
    
    ptcb = _K_ptcbTCBIdTable[usIndex];                                  /*  获得 TCB 指针               */
    
    if (ptcb->TCB_ulThreadSafeCounter) {
        bIsInSafeMode = LW_TRUE;
    
    } else {
        bIsInSafeMode = LW_FALSE;
    }
    
    __KERNEL_EXIT();                                                    /*  退出内核                    */
    
    return  (bIsInSafeMode);
}
Beispiel #14
0
/*********************************************************************************************************
** 函数名称: 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);
}
Beispiel #15
0
/*********************************************************************************************************
** 函数名称: API_ThreadGetSliceEx
** 功能描述: 获得指定线程时间片(扩展接口)
** 输 入  :
**           ulId            线程ID
**           pusSliceTemp    时间片
**           pusCounter      剩余时间片
** 输 出  :
** 全局变量:
** 调用模块:
                                           API 函数
*********************************************************************************************************/
LW_API
ULONG  API_ThreadGetSliceEx (LW_OBJECT_HANDLE  ulId, UINT16  *pusSliceTemp, UINT16  *pusCounter)
{
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_TCB         ptcb;

    usIndex = _ObjectGetIndex(ulId);

#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) {                        /*  检查 ID 类型有效性          */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }

    if (_Thread_Index_Invalid(usIndex)) {                               /*  检查线程有效性              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (ERROR_THREAD_NULL);
    }
#endif

    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Thread_Invalid(usIndex)) {
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (ERROR_THREAD_NULL);
    }

    ptcb = _K_ptcbTCBIdTable[usIndex];

    if (pusSliceTemp) {
        *pusSliceTemp = ptcb->TCB_usSchedSlice;
    }
    if (pusCounter) {
        *pusCounter = ptcb->TCB_usSchedCounter;
    }

    __KERNEL_EXIT();                                                    /*  退出内核                    */

    return  (ERROR_NONE);
}
Beispiel #16
0
/*********************************************************************************************************
** 函数名称: API_KernelGetThreadNum
** 功能描述: 获得当前线程数量
** 输 入  : NONE
** 输 出  : 当前线程数量
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
UINT16  API_KernelGetThreadNum (VOID)
{
    REGISTER UINT16     usThreadNum;
    
    __KERNEL_ENTER();                                                   /*  进入内核                    */
    usThreadNum = _K_usThreadCounter;
    __KERNEL_EXIT();                                                    /*  退出内核                    */

    return  (usThreadNum);
}
Beispiel #17
0
/*********************************************************************************************************
** 函数名称: setpriority
** 功能描述: set or set the nice value
** 输 入  : which         PRIO_PROCESS / PRIO_PGRP / PRIO_USER
**           who           process ID / process group ID / effective user ID
                           who == 0 specifies the current process, process group or user.
**           value         priority (PRIO_MIN ~ PRIO_MAX) 
                           PRIO_MIN -> highest priorioty
                           PRIO_MAX -> lowest priorioty
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  setpriority (int which, id_t who, int value)
{
#if LW_CFG_MODULELOADER_EN > 0
    INT    iRet = PX_ERROR;
    UINT8  ucPriority;
    
    if ((value < PRIO_MIN) ||
        (value > PRIO_MAX)) {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    if (which == PRIO_PROCESS) {
        if (who == 0) {
            who =  (id_t)getpid();
        }
    } else if (which == PRIO_PGRP) {
        if (who == 0) {
            who =  (id_t)getpgid(getpid());
        }
    } else if (PRIO_USER) {
        if (who == 0) {
            who =  (id_t)geteuid();
        }
    } else {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    ucPriority = (UINT8)value;
    
    __KERNEL_ENTER();
    _ThreadTraversal(__sprio_hook, 
                     (PVOID)&iRet, (PVOID)which, (PVOID)who, (PVOID)&ucPriority, 
                     LW_NULL, LW_NULL);
    __KERNEL_EXIT();

    if (iRet == ERROR_NONE) {
        return  (ERROR_NONE);
    
    } else {
        errno = ESRCH;
        return  (PX_ERROR);
    }
#else
    errno = ENOSYS;
    return  (PX_ERROR);
#endif                                                                  /*  LW_CFG_MODULELOADER_EN > 0  */
}
Beispiel #18
0
/*********************************************************************************************************
** 函数名称: API_CoroutineStackCheck
** 功能描述: 检测一个协程的堆栈使用量!!, 该协程的父系线程建立时必须使用 STK_CHK 选项.
** 输 入  : pvCrcb                        协程句柄
**           pstFreeByteSize               空闲堆栈大小   (可为 LW_NULL)
**           pstUsedByteSize               使用堆栈大小   (可为 LW_NULL)
**           pstCrcbByteSize               协程控制块大小 (可为 LW_NULL)
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
ULONG   API_CoroutineStackCheck (PVOID      pvCrcb,
                                 size_t    *pstFreeByteSize,
                                 size_t    *pstUsedByteSize,
                                 size_t    *pstCrcbByteSize)
{
    REGISTER PLW_CLASS_COROUTINE   pcrcb = (PLW_CLASS_COROUTINE)pvCrcb;
    REGISTER size_t                stTotal;
    REGISTER size_t                stFree = 0;
    
    REGISTER PLW_STACK             pstkButtom;

    if (!pcrcb) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "coroutine handle invalidate.\r\n");
        _ErrorHandle(EINVAL);
        return  (EINVAL);
    }
    
    __KERNEL_ENTER();                                                   /*  进入内核                    */
    stTotal = pcrcb->COROUTINE_stStackSize;                             /*  总大小                      */
    
#if CPU_STK_GROWTH == 0                                                 /*  寻找堆栈头尾                */
    for (pstkButtom = pcrcb->COROUTINE_pstkStackBottom;
         *pstkButtom == _K_stkFreeFlag;
         pstkButtom--,
         stFree++);
#else
    for (pstkButtom = pcrcb->COROUTINE_pstkStackBottom;
         *pstkButtom == _K_stkFreeFlag;
         pstkButtom++,
         stFree++);
#endif
    __KERNEL_EXIT();                                                    /*  退出内核                    */
    
    if (pstFreeByteSize) {
        *pstFreeByteSize = stFree * sizeof(LW_STACK);
    }
    
    if (pstUsedByteSize) {
        *pstUsedByteSize = (stTotal - stFree) * sizeof(LW_STACK);
    }
    
    if (pstCrcbByteSize) {
        *pstCrcbByteSize = sizeof(LW_CLASS_COROUTINE);
    }
    
    return  (ERROR_NONE);
}
Beispiel #19
0
static VOID  __makeOtherDown (VOID)
{
    ULONG           i;
    PLW_CLASS_TCB   ptcbIdle;
    
    for (i = 1; i < LW_NCPUS; i++) {                                    /*  除 0 以外的其他 CPU         */
        ptcbIdle = _K_ptcbTCBIdTable[i];
        if (LW_PRIO_IS_EQU(ptcbIdle->TCB_ucPriority, LW_PRIO_HIGHEST)) {
            __KERNEL_ENTER();                                           /*  进入内核                    */
            _SchedSetPrio(ptcbIdle, LW_PRIO_HIGHEST);
            __KERNEL_EXIT();                                            /*  退出内核                    */
            
            while (!__LW_THREAD_IS_RUNNING(ptcbIdle)) {
                LW_SPINLOCK_DELAY();
            }
        }
    }
}
Beispiel #20
0
/*********************************************************************************************************
** 函数名称: 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);
}
Beispiel #21
0
/*********************************************************************************************************
** 函数名称: sigqueue
** 功能描述: 发送队列类型信号, 如果是进程, 将发送给其主线程.
** 输 入  : ulId                    线程 id 或者 进程号
**           iSigNo                  信号
**           sigvalue                信号 value
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
INT  sigqueue (LW_OBJECT_HANDLE  ulId, INT   iSigNo, const union sigval  sigvalue)
{
    REGISTER UINT16             usIndex;
    REGISTER PLW_CLASS_TCB      ptcb;
             LW_SEND_VAL        sendval;
             
#if LW_CFG_MODULELOADER_EN > 0
    if (ulId < LW_CFG_MAX_THREADS) {                                    /*  进程号                      */
        ulId = vprocMainThread((pid_t)ulId);
    }
#endif                                                                  /*  LW_CFG_MODULELOADER_EN > 0  */
    
    usIndex = _ObjectGetIndex(ulId);
    
    if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) {                        /*  检查 ID 类型有效性          */
        _ErrorHandle(ESRCH);
        return  (PX_ERROR);
    }
    if (_Thread_Index_Invalid(usIndex)) {                               /*  检查线程有效性              */
        _ErrorHandle(ESRCH);
        return  (PX_ERROR);
    }
    
    if (!__issig(iSigNo)) {
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }
    
    if (LW_CPU_GET_CUR_NESTING() || (ulId == API_ThreadIdSelf())) {
        _excJobAdd((VOIDFUNCPTR)sigqueue, (PVOID)ulId, (PVOID)iSigNo, (PVOID)sigvalue.sival_ptr, 
                   0, 0, 0);
        return  (ERROR_NONE);
    }
    
#if LW_CFG_SMP_EN > 0
    if (LW_NCPUS > 1) {                                                 /*  正工作在 SMP 多核模式       */
        if (API_ThreadStop(ulId)) {
            return  (PX_ERROR);
        }
    }
#endif                                                                  /*  LW_CFG_SMP_EN               */

    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Thread_Invalid(usIndex)) {
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _ErrorHandle(ESRCH);
        return  (PX_ERROR);
    }
    
    ptcb = __GET_TCB_FROM_INDEX(usIndex);
    if (ptcb->TCB_iDeleteProcStatus) {
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _ErrorHandle(ERROR_THREAD_OTHER_DELETE);
        return  (PX_ERROR);
    }
    
    sendval = _doSigQueue(ptcb, iSigNo, sigvalue);

#if LW_CFG_SMP_EN > 0
    if (LW_NCPUS > 1) {                                                 /*  正工作在 SMP 多核模式       */
        _ThreadContinue(ptcb, LW_FALSE);                                /*  在内核状态下唤醒被停止线程  */
    }
#endif                                                                  /*  LW_CFG_SMP_EN               */
    __KERNEL_EXIT();                                                    /*  退出内核                    */
    
#if LW_CFG_SIGNALFD_EN > 0
    if (sendval == SEND_BLOCK) {
        _sigfdReadUnblock(ulId, iSigNo);
    }
#endif                                                                  /*  LW_CFG_SIGNALFD_EN > 0      */
    
    return  (ERROR_NONE);
}
Beispiel #22
0
ULONG  __threadDelete (PLW_CLASS_TCB  ptcbDel, BOOL  bIsInSafe, 
                       PVOID  pvRetVal, BOOL  bIsAlreadyWaitDeath)
{
             INTREG                iregInterLevel;
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_PCB         ppcbDel;
    REGISTER LW_OBJECT_HANDLE      ulId;
    REGISTER PVOID                 pvFreeLowAddr;                       /*  要释放的内存地址            */
             PVOID                 pvVProc;
             
#if (LW_CFG_EVENTSET_EN > 0) && (LW_CFG_MAX_EVENTSETS > 0)
    REGISTER PLW_EVENTSETNODE      pesnPtr;
#endif

    ulId    = ptcbDel->TCB_ulId;
    usIndex = _ObjectGetIndex(ulId);
    
    if (bIsAlreadyWaitDeath == LW_FALSE) {
        _ThreadDeleteWaitDeath(ptcbDel);                                /*  将要删除的线程进入僵死状态  */
    }
    
    __KERNEL_ENTER();                                                   /*  进入内核                    */
    
    ppcbDel = _GetPcb(ptcbDel);
    
    iregInterLevel = KN_INT_DISABLE();                                  /*  关闭中断                    */
    
    if (ptcbDel->TCB_ptcbDeleteWait) {                                  /*  目标线程正在等待其他任务删除*/
        ptcbDel->TCB_ptcbDeleteWait->TCB_ptcbDeleteMe = (PLW_CLASS_TCB)1;
        ptcbDel->TCB_ptcbDeleteWait = LW_NULL;
    }
    
#if (LW_CFG_EVENT_EN > 0) && (LW_CFG_MAX_EVENTS > 0)
    if (ptcbDel->TCB_peventPtr) {                                       /*  等待事件中                  */
        _EventUnlink(ptcbDel);                                          /*  解等待连                    */
    }
#endif

#if (LW_CFG_EVENTSET_EN > 0) && (LW_CFG_MAX_EVENTSETS > 0)
    pesnPtr = ptcbDel->TCB_pesnPtr;
    if (pesnPtr) {
        _EventSetUnlink(pesnPtr);                                       /*  解事件集                    */
    }
#endif

#if LW_CFG_SMP_EN > 0
    if (ptcbDel->TCB_ptcbWaitStatus ||
        ptcbDel->TCB_plineStatusReqHeader) {                            /*  正在请求其他线程改变状态    */
        _ThreadUnwaitStatus(ptcbDel);
    }
#endif                                                                  /*  LW_CFG_SMP_EN               */
    
    if (__LW_THREAD_IS_READY(ptcbDel)) {                                /*  是否就绪                    */
        __DEL_FROM_READY_RING(ptcbDel, ppcbDel);                        /*  从就绪队列中删除            */
        
    } else {
        if (ptcbDel->TCB_usStatus & LW_THREAD_STATUS_DELAY) {
            __DEL_FROM_WAKEUP_LINE(ptcbDel);                            /*  从等待链中删除              */
            ptcbDel->TCB_ulDelay = 0ul;
        }
        ptcbDel->TCB_usStatus = LW_THREAD_STATUS_RDY;                   /*  防止 Tick 中断激活          */
    }
    
#if LW_CFG_SOFTWARE_WATCHDOG_EN > 0
    if (ptcbDel->TCB_bWatchDogInQ) {
        __DEL_FROM_WATCHDOG_LINE(ptcbDel);                              /*  从 watch dog 中删除         */
        ptcbDel->TCB_ulWatchDog = 0ul;
    }
#endif
    KN_INT_ENABLE(iregInterLevel);
    
    pvFreeLowAddr = (PVOID)ptcbDel->TCB_pstkStackLowAddr;               /*  记录地址                    */
    
#if (LW_CFG_THREAD_PRIVATE_VARS_EN > 0) && (LW_CFG_MAX_THREAD_GLB_VARS > 0)
    _ThreadVarDelete(ptcbDel);                                          /*  删除并恢复私有化的全局变量  */
#endif
    
    iregInterLevel = KN_INT_DISABLE();                                  /*  关闭中断                    */ 
    
    _K_usThreadCounter--;
    _K_ptcbTCBIdTable[usIndex] = LW_NULL;                               /*  TCB 表清0                   */
    
    _List_Line_Del(&ptcbDel->TCB_lineManage, &_K_plineTCBHeader);       /*  从管理练表中删除            */
    
    KN_INT_ENABLE(iregInterLevel);                                      /*  打开中断                    */
    
    if (ptcbDel->TCB_ptcbJoin) {
        _ThreadDisjoin(ptcbDel->TCB_ptcbJoin, ptcbDel);                 /*  退出 join 状态, 不操作就绪表*/
    }
    
    _ThreadDisjoinWakeupAll(ptcbDel, pvRetVal);                         /*  DETACH                      */
    
    __KERNEL_EXIT();                                                    /*  退出内核                    */
    
#if LW_CFG_COROUTINE_EN > 0
    _CoroutineFreeAll(ptcbDel);                                         /*  删除协程内存空间            */
#endif                                                                  /*  LW_CFG_COROUTINE_EN > 0     */
    
    if (bIsInSafe) {
        _DebugFormat(__ERRORMESSAGE_LEVEL, 
                     "thread \"%s\" has been delete in SAFE mode.\r\n",
                     ptcbDel->TCB_cThreadName);
    } else {
        _DebugFormat(__LOGMESSAGE_LEVEL, 
                     "thread \"%s\" has been delete.\r\n",
                     ptcbDel->TCB_cThreadName);
    }
    
    pvVProc = ptcbDel->TCB_pvVProcessContext;                           /*  进程信息                    */
    
    if (ptcbDel->TCB_ucStackAutoAllocFlag) {                            /*  是否是内核堆开辟堆栈        */
#if LW_CFG_MODULELOADER_EN > 0
        vprocStackFree(ptcbDel, pvFreeLowAddr, LW_FALSE);
#else
        __KHEAP_FREE(pvFreeLowAddr);                                    /*  释放堆栈空间                */
#endif                                                                  /*  LW_CFG_MODULELOADER_EN > 0  */
    }
    
    _TCBDestroy(ptcbDel);                                               /*  销毁 TCB                    */
    
    __KERNEL_MODE_PROC(
        _Free_Tcb_Object(ptcbDel);                                      /*  释放 ID                     */
    );
Beispiel #23
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);
}
Beispiel #24
0
/*********************************************************************************************************
** 函数名称: 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);
}
Beispiel #25
0
LW_API  
ULONG  API_SemaphoreCPost (LW_OBJECT_HANDLE  ulId)
{
             INTREG                iregInterLevel;
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_EVENT       pevent;
    REGISTER PLW_CLASS_TCB         ptcb;
    REGISTER PLW_LIST_RING        *ppringList;                          /*  等待队列地址                */
    
    usIndex = _ObjectGetIndex(ulId);
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_SEM_C)) {                         /*  类型是否正确                */
        _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];
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    if (_Event_Type_Invalid(usIndex, LW_TYPE_EVENT_SEMC)) {
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "semaphore handle invalidate.\r\n");
        _ErrorHandle(ERROR_EVENT_TYPE);
        return  (ERROR_EVENT_TYPE);
    }
    
    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);                                  /*  使能中断                    */
        
        _EventReadyHighLevel(ptcb, LW_THREAD_STATUS_SEM);               /*  处理 TCB                    */
        
        MONITOR_EVT_LONG2(MONITOR_EVENT_ID_SEMC, MONITOR_EVENT_SEM_POST, 
                          ulId, ptcb->TCB_ulId, LW_NULL);
        
        __KERNEL_EXIT();                                                /*  退出内核                    */
        return  (ERROR_NONE);
    
    } else {                                                            /*  没有线程等待                */
        if (pevent->EVENT_ulCounter < pevent->EVENT_ulMaxCounter) {     /*  检查是否还有空间加          */
            pevent->EVENT_ulCounter++;
            __KERNEL_EXIT_IRQ(iregInterLevel);                          /*  退出内核                    */
            return  (ERROR_NONE);
        
        } else {                                                        /*  已经满了                    */
            __KERNEL_EXIT_IRQ(iregInterLevel);                          /*  退出内核                    */
            _ErrorHandle(ERROR_EVENT_FULL);
            return  (ERROR_EVENT_FULL);
        }
    }
}
Beispiel #26
0
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);
        }
    }
}
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
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);
        }
    }
}