Example #1
0
/*********************************************************************************************************
** 函数名称: pause
** 功能描述: 等待一个信号的到来
** 输 入  : NONE
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
INT  pause (VOID)
{
             INTREG         iregInterLevel;
             PLW_CLASS_TCB  ptcbCur;
    REGISTER PLW_CLASS_PCB  ppcb;
    
    __THREAD_CANCEL_POINT();                                            /*  测试取消点                  */
    
    LW_TCB_GET_CUR_SAFE(ptcbCur);                                       /*  当前任务控制块              */

    MONITOR_EVT_LONG1(MONITOR_EVENT_ID_SIGNAL, MONITOR_EVENT_SIGNAL_PAUSE, 
                      ptcbCur->TCB_ulId, LW_NULL);
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    
    ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_SIGNAL;                   /*  等待信号                    */
    ppcb = _GetPcb(ptcbCur);
    __DEL_FROM_READY_RING(ptcbCur, ppcb);                               /*  从就绪表中删除              */
    
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核                    */
    
    _ErrorHandle(EINTR);
    return  (PX_ERROR);
}
Example #2
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 #3
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);
}
Example #4
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);
}
Example #5
0
/*********************************************************************************************************
** 函数名称: lib_system
** 功能描述: 
** 输 入  : 
** 输 出  : 
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
INT  lib_system (CPCHAR        pcCmd)
{
#if LW_CFG_SHELL_EN > 0
    INT     iRet;
    
    __THREAD_CANCEL_POINT();                                            /*  测试取消点                  */
    
    iRet = API_TShellExec(pcCmd);

    return  (iRet);
#else
    return  (PX_ERROR);
#endif                                                                  /*  LW_CFG_SHELL_EN > 0         */
}
Example #6
0
/*********************************************************************************************************
** 函数名称: nanosleep 
** 功能描述: 使调用此函数的线程睡眠一个指定的时间, 睡眠过程中可能被信号唤醒. (POSIX)
** 输 入  : rqtp         睡眠的时间
**           rmtp         保存剩余时间的结构.
** 输 出  : ERROR_NONE  or  PX_ERROR

             error == EINTR    表示被信号激活.
** 全局变量: 
** 调用模块: 
                                           API 函数
                                           
                                       (不得在中断中调用)
*********************************************************************************************************/
LW_API  
INT  nanosleep (const struct timespec  *rqtp, struct timespec  *rmtp)
{
             INTREG             iregInterLevel;
             
             PLW_CLASS_TCB      ptcbCur;
    REGISTER PLW_CLASS_PCB      ppcb;
	REGISTER ULONG              ulKernelTime;
	REGISTER INT                iRetVal;
	         INT                iSchedRet;
	
	REGISTER ULONG              ulError;
             ULONG              ulTick;
             
             struct timespec    tvStart;
             struct timespec    tvTemp;
    
    if ((!rqtp)              ||
        (rqtp->tv_nsec <  0) ||
        (rqtp->tv_nsec >= __TIMEVAL_NSEC_MAX)) {                        /*  时间格式错误                */
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }
    
    ulTick = __timespecToTick((struct timespec *)rqtp);
    if (!ulTick) {                                                      /*  不到一个 tick               */
        __timePassSpec(rqtp);                                           /*  平静度过                    */
        if (rmtp) {
            rmtp->tv_sec  = 0;                                          /*  不存在时间差别              */
            rmtp->tv_nsec = 0;
        }
        return  (ERROR_NONE);
    }
    
    __timeGetHighResolution(&tvStart);                                  /*  记录开始的时间              */
    
    __THREAD_CANCEL_POINT();                                            /*  测试取消点                  */
    
    LW_TCB_GET_CUR_SAFE(ptcbCur);                                       /*  当前任务控制块              */
    
    MONITOR_EVT_LONG2(MONITOR_EVENT_ID_THREAD, MONITOR_EVENT_THREAD_SLEEP, 
                      ptcbCur->TCB_ulId, ulTick, LW_NULL);
    
__wait_again:
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核                    */
    
    ppcb = _GetPcb(ptcbCur);
    __DEL_FROM_READY_RING(ptcbCur, ppcb);                               /*  从就绪表中删除              */
    
    ptcbCur->TCB_ulDelay = ulTick;
    __ADD_TO_WAKEUP_LINE(ptcbCur);                                      /*  加入等待扫描链              */
    
    __KERNEL_TIME_GET_NO_SPINLOCK(ulKernelTime, ULONG);                 /*  记录系统时间                */
    
    iSchedRet = __KERNEL_EXIT_IRQ(iregInterLevel);                      /*  调度器解锁                  */
    if (iSchedRet == LW_SIGNAL_EINTR) {
        iRetVal = PX_ERROR;                                             /*  被信号激活                  */
        ulError = EINTR;
    
    } else {
        if (iSchedRet == LW_SIGNAL_RESTART) {                           /*  信号要求重启等待            */
            ulTick = _sigTimeoutRecalc(ulKernelTime, ulTick);           /*  重新计算等待时间            */
            if (ulTick != 0ul) {
                goto    __wait_again;                                   /*  重新等待剩余的 tick         */
            }
        }
        iRetVal = ERROR_NONE;                                           /*  自然唤醒                    */
        ulError = ERROR_NONE;
    }
    
    if (ulError ==  ERROR_NONE) {                                       /*  tick 已经延迟结束           */
        __timeGetHighResolution(&tvTemp);
        __timespecSub(&tvTemp, &tvStart);                               /*  计算已经延迟的时间          */
        if (__timespecLeftTime(&tvTemp, rqtp)) {                        /*  还有剩余时间需要延迟        */
            struct timespec  tvNeed = *rqtp;
            __timespecSub(&tvNeed, &tvTemp);
            __timePassSpec(&tvNeed);                                    /*  平静度过                    */
        }
        if (rmtp) {
            rmtp->tv_sec  = 0;                                          /*  不存在时间差别              */
            rmtp->tv_nsec = 0;
        }
    } else {                                                            /*  信号唤醒                    */
        if (rmtp) {
            *rmtp = *rqtp;
            __timeGetHighResolution(&tvTemp);
            __timespecSub(&tvTemp, &tvStart);                           /*  计算已经延迟的时间          */
            if (__timespecLeftTime(&tvTemp, rmtp)) {                    /*  没有延迟够                  */
                __timespecSub(rmtp, &tvTemp);                           /*  计算没有延迟够的时间        */
            }
        }
    }
             
    _ErrorHandle(ulError);                                              /*  设置 errno 值               */
    return  (iRetVal);
}
Example #7
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);
}
Example #8
0
/*********************************************************************************************************
** 函数名称: aio_suspend
** 功能描述: 等待指定的一个或多个异步 I/O 请求操作完成
** 输 入  : list              aio 请求控制块数组 (如果其中有 NULL, 程序将忽略)
**           nent              数组元素个数
**           timeout           超时时间
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  aio_suspend (const struct aiocb * const list[], int nent, const struct timespec *timeout)
{
    AIO_WAIT_CHAIN     *paiowc;
    struct aiowait     *paiowait;
    ULONG               ulTimeout;
    
    BOOL                bNeedWait = LW_FALSE;
    
    int                 iWait = 0;                                      /*  paiowait 下标               */
    int                 iCnt;                                           /*  list 下标                   */
    int                 iRet = ERROR_NONE;
    
#ifdef __SYLIXOS_KERNEL
    if (__PROC_GET_PID_CUR() != 0) {                                    /*  需要使用外部库提供的 aio    */
        errno = ENOSYS;
        return  (PX_ERROR);
    }
#endif                                                                  /*  __SYLIXOS_KERNEL            */

    __THREAD_CANCEL_POINT();                                            /*  测试取消点                  */

    if ((nent <= 0) || (list == LW_NULL)) {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    if (timeout == LW_NULL) {                                           /*  永久等待                    */
        ulTimeout = LW_OPTION_WAIT_INFINITE;
    } else {
        ulTimeout = __timespecToTick(timeout);
    }
    
    paiowc = __aioCreateWaitChain(nent, LW_TRUE);                       /*  创建等待队列                */
    if (paiowc == LW_NULL) {
        errno = ENOMEM;                                                 /*  should be EAGAIN ?          */
        return  (PX_ERROR);
    }
    
    paiowait = paiowc->aiowc_paiowait;
    
    API_SemaphoreMPend(_G_aioqueue.aioq_mutex, LW_OPTION_WAIT_INFINITE);
    
    for (iCnt = 0; iCnt < nent; iCnt++) {
        if (list[iCnt]) {
            if (list[iCnt]->aio_req.aioreq_error == EINPROGRESS) {      /*  必须为正在处理状态          */
                
                paiowait[iWait].aiowt_pcond     = &paiowc->aiowc_cond;
                paiowait[iWait].aiowt_pcnt      = LW_NULL;
                paiowait[iWait].aiowt_psigevent = LW_NULL;
                paiowait[iWait].aiowt_paiowc    = LW_NULL;              /*  不需要代理线程释放          */
                
                iRet = __aioAttachWait(list[iCnt], &paiowait[iWait]);
                if (iRet != ERROR_NONE) {
                    errno = EINVAL;
                    break;
                }
                
                _List_Line_Add_Tail(&paiowait[iWait].aiowt_line, 
                                    &paiowc->aiowc_pline);              /*  加入 wait 链表              */
                iWait++;
                
                bNeedWait = LW_TRUE;                                    /*  有 wait 链表节点连接,       */
            } else {
                break;
            }
        }
    }
    
    if (iRet != ERROR_NONE) {                                           /*  __aioAttachWait 失败        */
        __aioDeleteWaitChain(paiowc);
        API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    if ((iCnt == nent) && bNeedWait) {                                  /*  是否需要等待                */
        API_ThreadCleanupPush(__aioWaitCleanup, paiowc);
        
        iRet = (INT)API_ThreadCondWait(&paiowc->aiowc_cond, _G_aioqueue.aioq_mutex, ulTimeout);
        
        API_ThreadCleanupPop(LW_FALSE);                                 /*  这里已经锁定 _G_aioqueue    */
                                                                        /*  不能运行 __aioWaitCleanup   */
        __aioDeleteWaitChain(paiowc);
        
        if (iRet != ERROR_NONE) {
            API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
            errno = EAGAIN;
            return  (PX_ERROR);
        }
    
    } else {                                                            /*  不需要等待                  */
        __aioDeleteWaitChain(paiowc);
    }
    
    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
    
    return  (iRet);
}