Example #1
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);
}
Example #2
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);
}
Example #3
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);
}
Example #4
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);
}
Example #5
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);
}
Example #6
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);
}
Example #7
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);
}