示例#1
0
文件: sched.c 项目: Ga-vin/libsylixos
/*********************************************************************************************************
** 函数名称: sched_yield
** 功能描述: 将当前任务插入到同优先级调度器链表的最后, 主动让出一次 CPU 调度.
** 输 入  : NONE
** 输 出  : ERROR_NONE
** 全局变量:
** 调用模块:
                                           API 函数
*********************************************************************************************************/
LW_API
int  sched_yield (void)
{
    API_ThreadYield(API_ThreadIdSelf());

    return  (ERROR_NONE);
}
示例#2
0
/*********************************************************************************************************
** 函数名称: __pthreadDataGet
** 功能描述: 获取指定 key 在当前线程内部数据节点.
** 输 入  : lId           键id
**           ppvData       初始数据(返回)
** 输 出  : ERROR CODE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static INT  __pthreadDataGet (long  lId, void  **ppvData)
{
    __PX_KEY_NODE       *pkeyn = (__PX_KEY_NODE *)lId;
    __PX_KEY_DATA       *pkeyd;
    LW_OBJECT_HANDLE     ulMe  = API_ThreadIdSelf();
    PLW_LIST_LINE        plineTemp;
    
    if (ppvData == LW_NULL) {
        errno = EINVAL;
        return  (EINVAL);
    }
    
    if (pkeyn == LW_NULL) {                                             /*  没有 key 键                 */
        errno = EINVAL;
        return  (EINVAL);
    }
    
    *ppvData = LW_NULL;
    
    __PX_KEY_LOCK(pkeyn);                                               /*  锁住 key 键                 */
    for (plineTemp  = pkeyn->PKEYN_plineKeyHeader;
         plineTemp != LW_NULL;
         plineTemp  = _list_line_get_next(plineTemp)) {
        
        pkeyd = (__PX_KEY_DATA *)plineTemp;                             /*  链表是 KEY DATA 的第一个元素*/
        if (pkeyd->PKEYD_ulOwner == ulMe) {                             /*  找到对应当前线程的数据      */
            *ppvData = pkeyd->PKEYD_pvData;
            break;
        }
    }
    __PX_KEY_UNLOCK(pkeyn);                                             /*  解锁 key 键                 */
    
    return  (ERROR_NONE);
}
示例#3
0
文件: sched.c 项目: Ga-vin/libsylixos
/*********************************************************************************************************
** 函数名称: sched_getscheduler
** 功能描述: 获得指定任务调度器
** 输 入  : pid           进程 / 线程 ID
** 输 出  : 调度策略
** 全局变量:
** 调用模块:
                                           API 函数
*********************************************************************************************************/
LW_API
int  sched_getscheduler (pid_t  pid)
{
    UINT8               ucPolicy;
    LW_OBJECT_HANDLE    ulThread;

#if LW_CFG_MODULELOADER_EN > 0
    if (pid == 0) {
        pid =  getpid();
    }
    if (pid == 0) {
        ulThread = API_ThreadIdSelf();
    } else {
        ulThread = vprocMainThread(pid);
    }
    if (ulThread == LW_OBJECT_HANDLE_INVALID) {
        errno = ESRCH;
        return  (PX_ERROR);
    }
#else
    ulThread = (LW_OBJECT_HANDLE)pid;
    PX_ID_VERIFY(ulThread, LW_OBJECT_HANDLE);
#endif                                                                  /*  LW_CFG_MODULELOADER_EN > 0  */

    if (API_ThreadGetSchedParam(ulThread,
                                &ucPolicy,
                                LW_NULL)) {
        errno = ESRCH;
        return  (PX_ERROR);
    } else {
        return  ((int)ucPolicy);
    }
}
示例#4
0
文件: aio.c 项目: Ga-vin/libsylixos
/*********************************************************************************************************
** 函数名称: aio_fsync
** 功能描述: aio 同步文件的内容, 将缓冲内部的数据写入文件
** 输 入  : op                操作选项 (O_SYNC or O_DSYNC)
**           paiocb            aio 请求控制块
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  aio_fsync (int op, struct aiocb *paiocb)
{
    INT     iRet;
    
#ifdef __SYLIXOS_KERNEL
    if (__PROC_GET_PID_CUR() != 0) {                                    /*  需要使用外部库提供的 aio    */
        errno = ENOSYS;
        return  (PX_ERROR);
    }
#endif                                                                  /*  __SYLIXOS_KERNEL            */

    if (!paiocb) {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    paiocb->aio_lio_opcode = LIO_SYNC;
    
    paiocb->aio_req.aioreq_thread = API_ThreadIdSelf();
    paiocb->aio_pwait = LW_NULL;
    
    API_SemaphoreMPend(_G_aioqueue.aioq_mutex, LW_OPTION_WAIT_INFINITE);
    iRet = __aioEnqueue(paiocb);
    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
    
    return  (iRet);
}
示例#5
0
/*********************************************************************************************************
** 函数名称: API_HotplugContext
** 功能描述: 是否在 hotplug 处理线程中
** 输 入  : 
** 输 出  : 
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
BOOL  API_HotplugContext (VOID)
{
    if (API_ThreadIdSelf() == _G_hHotplug) {
        return  (LW_TRUE);
    } else {
        return  (LW_FALSE);
    }
}
示例#6
0
/*********************************************************************************************************
** 函数名称: API_KernelReboot
** 功能描述: 内核重新启动函数
** 输 入  : iRebootType        重启类型 
                                LW_REBOOT_FORCE
                                LW_REBOOT_WARM
                                LW_REBOOT_COLD
                                LW_REBOOT_SHUTDOWN
                                LW_REBOOT_POWEROFF
**           ulStartAddress     启动地址
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
VOID   API_KernelRebootEx (INT  iRebootType, addr_t  ulStartAddress)
{
    INTREG  iregInterLevel;
    ULONG   ulI;
    
    if (iRebootType == LW_REBOOT_FORCE) {
        archReboot(iRebootType, ulStartAddress);                        /*  调用体系架构重启操作        */
        _BugHandle(LW_TRUE, LW_TRUE, "kernel reboot error!\r\n");       /*  不会运行到这里              */
    }

    if (LW_CPU_GET_CUR_NESTING() || (API_ThreadIdSelf() != API_KernelGetExc())) {
        _excJobAdd(API_KernelRebootEx, (PVOID)iRebootType, (PVOID)ulStartAddress, 0, 0, 0, 0);
        return;
    }

    _DebugHandle(__LOGMESSAGE_LEVEL, "kernel rebooting...\r\n");
    
    _K_ulRebootStartAddress = ulStartAddress;                           /*  记录局部变量, 防止 XXX      */
    
#if LW_CFG_SMP_EN > 0
    if (LW_NCPUS > 1) {
        __makeOtherDown();                                              /*  将其他 CPU 设置为 idle 模式 */
    }
#endif                                                                  /*  LW_CFG_SMP_EN               */
    
    if (iRebootType != LW_REBOOT_FORCE) {
        __LW_KERNEL_REBOOT_HOOK(iRebootType);                           /*  调用回调函数                */
        _cppRtUninit();                                                 /*  卸载 C++ 运行时             */
    }
    
    for (ulI = 0; ulI < LW_CFG_MAX_INTER_SRC; ulI++) {
        API_InterVectorDisable(ulI);                                    /*  关闭所有中断                */
    }
    
    iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核同时关闭中断        */

#if LW_CFG_CACHE_EN > 0
    API_CacheDisable(DATA_CACHE);                                       /*  禁能 CACHE                  */
    API_CacheDisable(INSTRUCTION_CACHE);
#endif                                                                  /*  LW_CFG_CACHE_EN > 0         */

#if LW_CFG_VMM_EN > 0
    API_VmmMmuDisable();                                                /*  关闭 MMU                    */
#endif                                                                  /*  LW_CFG_VMM_EN > 0           */

    archReboot(iRebootType, _K_ulRebootStartAddress);                   /*  调用体系架构重启操作        */
    
    _BugHandle(LW_TRUE, LW_TRUE, "kernel reboot error!\r\n");           /*  不会运行到这里              */
    
    __KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核同时打开中断        */
}
示例#7
0
文件: sched.c 项目: Ga-vin/libsylixos
/*********************************************************************************************************
** 函数名称: sched_rr_get_interval
** 功能描述: 获得指定任务调度器
** 输 入  : pid           进程 / 线程 ID
**           interval      current execution time limit.
** 输 出  : ERROR or OK
** 全局变量:
** 调用模块:
                                           API 函数
*********************************************************************************************************/
LW_API
int  sched_rr_get_interval (pid_t  pid, struct timespec  *interval)
{
    UINT8               ucPolicy;
    UINT16              usCounter = 0;
    LW_OBJECT_HANDLE    ulThread;

    if (!interval) {
        errno = EINVAL;
        return  (PX_ERROR);
    }

#if LW_CFG_MODULELOADER_EN > 0
    if (pid == 0) {
        pid =  getpid();
    }
    if (pid == 0) {
        ulThread = API_ThreadIdSelf();
    } else {
        ulThread = vprocMainThread(pid);
    }
    if (ulThread == LW_OBJECT_HANDLE_INVALID) {
        errno = ESRCH;
        return  (PX_ERROR);
    }
#else
    ulThread = (LW_OBJECT_HANDLE)pid;
    PX_ID_VERIFY(ulThread, LW_OBJECT_HANDLE);
#endif                                                                  /*  LW_CFG_MODULELOADER_EN > 0  */

    if (API_ThreadGetSchedParam(ulThread,
                                &ucPolicy,
                                LW_NULL)) {
        errno = ESRCH;
        return  (PX_ERROR);
    }
    if (ucPolicy != LW_OPTION_SCHED_RR) {
        errno = EINVAL;
        return  (PX_ERROR);
    }

    if (API_ThreadGetSliceEx(ulThread, LW_NULL, &usCounter)) {
        errno = ESRCH;
        return  (PX_ERROR);
    }

    __tickToTimespec((ULONG)usCounter, interval);

    return  (ERROR_NONE);
}
示例#8
0
文件: sched.c 项目: Ga-vin/libsylixos
/*********************************************************************************************************
** 函数名称: sched_setparam
** 功能描述: 设置指定任务调度器参数
** 输 入  : pid           进程 / 线程 ID
**           pschedparam   调度器参数
** 输 出  : ERROR or OK
** 全局变量:
** 调用模块:
                                           API 函数
*********************************************************************************************************/
LW_API
int  sched_setparam (pid_t  pid, const struct sched_param  *pschedparam)
{
    UINT8               ucPriority;
    ULONG               ulError;
    LW_OBJECT_HANDLE    ulThread;

    if (pschedparam == LW_NULL) {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    if ((pschedparam->sched_priority < __PX_PRIORITY_MIN) ||
            (pschedparam->sched_priority > __PX_PRIORITY_MAX)) {
        errno = EINVAL;
        return  (PX_ERROR);
    }

    ucPriority= (UINT8)PX_PRIORITY_CONVERT(pschedparam->sched_priority);

#if LW_CFG_MODULELOADER_EN > 0
    if (pid == 0) {
        pid =  getpid();
    }
    if (pid == 0) {
        ulThread = API_ThreadIdSelf();
    } else {
        ulThread = vprocMainThread(pid);
    }
    if (ulThread == LW_OBJECT_HANDLE_INVALID) {
        errno = ESRCH;
        return  (PX_ERROR);
    }
#else
    ulThread = (LW_OBJECT_HANDLE)pid;
    PX_ID_VERIFY(ulThread, LW_OBJECT_HANDLE);
#endif                                                                  /*  LW_CFG_MODULELOADER_EN > 0  */

    ulError = API_ThreadSetPriority(ulThread, ucPriority);
    if (ulError) {
        errno = ESRCH;
        return  (PX_ERROR);
    } else {
        return  (ERROR_NONE);
    }
}
示例#9
0
/*********************************************************************************************************
** 函数名称: pthread_rwlock_wrlock
** 功能描述: 等待一个读写锁可写.
** 输 入  : prwlock        句柄
** 输 出  : ERROR CODE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  pthread_rwlock_wrlock (pthread_rwlock_t  *prwlock)
{
    if (prwlock == LW_NULL) {
        errno = EINVAL;
        return  (EINVAL);
    }
    
    __pthread_rwlock_init_invisible(prwlock);

    __PX_RWLOCK_LOCK(prwlock);                                          /*  锁定读写锁                  */
    prwlock->PRWLOCK_uiWPendCounter++;                                  /*  等待写的数量++              */
    do {
        if (prwlock->PRWLOCK_uiOpCounter == 0) {
            /*
             *  没有正在操作的线程
             */
            prwlock->PRWLOCK_uiOpCounter++;                             /*  正在操作的线程++            */
            prwlock->PRWLOCK_uiWPendCounter--;                          /*  退出等待状态                */
            prwlock->PRWLOCK_uiStatus = __PX_RWLOCK_STATUS_WRITING;     /*  转换为写模式                */
            break;
            
        } else {
            /*
             *  如果有等待写入的线程或者存在正在读取的线程.
             */
            __PX_RWLOCK_UNLOCK(prwlock);                                /*  解锁读写锁                  */
            API_SemaphoreCPend(prwlock->PRWLOCK_ulWSemaphore,
                               LW_OPTION_WAIT_INFINITE);                /*  等待读写锁状态变换          */
            __PX_RWLOCK_LOCK(prwlock);                                  /*  锁定读写锁                  */
        }
    } while (1);
    prwlock->PRWLOCK_ulOwner = API_ThreadIdSelf();                      /*  读写锁拥有者                */
    __PX_RWLOCK_UNLOCK(prwlock);                                        /*  解锁读写锁                  */
    
    return  (ERROR_NONE);
}
示例#10
0
/*********************************************************************************************************
** 函数名称: pthread_rwlock_trywrlock
** 功能描述: 非阻塞等待一个读写锁可写.
** 输 入  : prwlock        句柄
** 输 出  : ERROR CODE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  pthread_rwlock_trywrlock (pthread_rwlock_t  *prwlock)
{
    if (prwlock == LW_NULL) {
        errno = EINVAL;
        return  (EINVAL);
    }
    
    __pthread_rwlock_init_invisible(prwlock);

    __PX_RWLOCK_LOCK(prwlock);                                          /*  锁定读写锁                  */
    if (prwlock->PRWLOCK_uiOpCounter == 0) {
        prwlock->PRWLOCK_uiOpCounter++;                                 /*  正在操作的线程++            */
        prwlock->PRWLOCK_uiStatus = __PX_RWLOCK_STATUS_WRITING;         /*  转换为写模式                */
        prwlock->PRWLOCK_ulOwner  = API_ThreadIdSelf();                 /*  读写锁拥有者                */
        __PX_RWLOCK_UNLOCK(prwlock);                                    /*  解锁读写锁                  */
        return  (ERROR_NONE);
    
    } else {
        __PX_RWLOCK_UNLOCK(prwlock);                                    /*  解锁读写锁                  */
        errno = EBUSY;
        return  (EBUSY);
    }
}
示例#11
0
/*********************************************************************************************************
** 函数名称: pthread_rwlock_unlock
** 功能描述: 释放一个读写锁.
** 输 入  : prwlock        句柄
** 输 出  : ERROR CODE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  pthread_rwlock_unlock (pthread_rwlock_t  *prwlock)
{
    ULONG       ulReleasNum;

    if (prwlock == LW_NULL) {
        errno = EINVAL;
        return  (EINVAL);
    }
    
    __pthread_rwlock_init_invisible(prwlock);

    __PX_RWLOCK_LOCK(prwlock);                                          /*  锁定读写锁                  */
    if (prwlock->PRWLOCK_uiStatus == __PX_RWLOCK_STATUS_WRITING) {
        /*
         *  写状态下释放.
         */
        if (prwlock->PRWLOCK_ulOwner != API_ThreadIdSelf()) {           /*  不是读写锁拥有者            */
            __PX_RWLOCK_UNLOCK(prwlock);                                /*  解锁读写锁                  */
            errno = EPERM;
            return  (EPERM);
        }
        
        prwlock->PRWLOCK_uiStatus = __PX_RWLOCK_STATUS_READING;         /*  重新进入可读模式            */
        prwlock->PRWLOCK_ulOwner  = LW_OBJECT_HANDLE_INVALID;           /*  没有写拥有者                */
        
    }
    
    prwlock->PRWLOCK_uiOpCounter--;                                     /*  操作数量--                  */
    
    /*
     *  SylixOS 使用写优先原则(其优点详见 www.ibm.com/developerworks/cn/linux/l-rwlock_writing/index.html)
     */
    if (prwlock->PRWLOCK_uiOpCounter) {                                 /*  还有占用的线程              */
        if (prwlock->PRWLOCK_uiWPendCounter == 0) {                     /*  没有等待写的线程            */
            ulReleasNum = (ULONG)prwlock->PRWLOCK_uiRPendCounter;
            if (ulReleasNum) {
                API_SemaphoreCRelease(prwlock->PRWLOCK_ulRSemaphore,
                                      ulReleasNum,
                                      LW_NULL);                         /*  将所有的等待读线程解锁      */
            }
        }
    
    } else {                                                            /*  没有占用锁                  */
        if (prwlock->PRWLOCK_uiWPendCounter) {                          /*  如果有写等待的线程          */
            ulReleasNum = (ULONG)prwlock->PRWLOCK_uiWPendCounter;
            API_SemaphoreCRelease(prwlock->PRWLOCK_ulWSemaphore,
                                  ulReleasNum,
                                  LW_NULL);                             /*  将所有的等待写线程解锁      */
        
        } else if (prwlock->PRWLOCK_uiRPendCounter) {                   /*  如果有等待读的线程          */
            ulReleasNum = (ULONG)prwlock->PRWLOCK_uiRPendCounter;
            API_SemaphoreCRelease(prwlock->PRWLOCK_ulRSemaphore,
                                  ulReleasNum,
                                  LW_NULL);                             /*  将所有的等待读线程解锁      */
        }
    }
    __PX_RWLOCK_UNLOCK(prwlock);                                        /*  解锁读写锁                  */
    
    return  (ERROR_NONE);
}
示例#12
0
/*********************************************************************************************************
** 函数名称: pthread_rwlock_wrlock
** 功能描述: 等待一个读写锁可写 (带有超时的阻塞).
** 输 入  : prwlock        句柄
**           abs_timeout    绝对超时时间
** 输 出  : ERROR CODE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  pthread_rwlock_timedwrlock (pthread_rwlock_t *prwlock,
                                 const struct timespec *abs_timeout)
{
    ULONG               ulTimeout;
    ULONG               ulOrgKernelTime;
    ULONG               ulError = ERROR_NONE;
    struct timespec     tvNow;
    struct timespec     tvWait  = {0, 0};
    
    if (prwlock == LW_NULL) {
        errno = EINVAL;
        return  (EINVAL);
    }
    
    if ((abs_timeout == LW_NULL)    || 
        (abs_timeout->tv_nsec <  0) ||
        (abs_timeout->tv_nsec >= __TIMEVAL_NSEC_MAX)) {
        errno = EINVAL;
        return  (EINVAL);
    }
    
    __pthread_rwlock_init_invisible(prwlock);
    
    lib_clock_gettime(CLOCK_REALTIME, &tvNow);                          /*  获得当前系统时间            */
    if (__timespecLeftTime(&tvNow, abs_timeout)) {
        tvWait = *abs_timeout;
        __timespecSub(&tvWait, &tvNow);                                 /*  计算与当前等待的时间间隔    */
    }
    /*
     *  注意: 当 tvWait 超过ulong tick范围时, 将自然产生溢出, 导致超时时间不准确.
     */
    ulTimeout = __timespecToTick(&tvWait);                              /*  变换为 tick                 */
    
    __PX_RWLOCK_LOCK(prwlock);                                          /*  锁定读写锁                  */
    prwlock->PRWLOCK_uiWPendCounter++;                                  /*  等待写的数量++              */
    do {
        __KERNEL_TIME_GET(ulOrgKernelTime, ULONG);                      /*  记录系统时间                */
        
        if (prwlock->PRWLOCK_uiOpCounter == 0) {
            /*
             *  没有正在操作的线程
             */
            prwlock->PRWLOCK_uiOpCounter++;                             /*  正在操作的线程++            */
            prwlock->PRWLOCK_uiWPendCounter--;                          /*  退出等待状态                */
            prwlock->PRWLOCK_uiStatus = __PX_RWLOCK_STATUS_WRITING;     /*  转换为写模式                */
            break;
            
        } else {
            /*
             *  如果有等待写入的线程或者存在正在读取的线程.
             */
            __PX_RWLOCK_UNLOCK(prwlock);                                /*  解锁读写锁                  */
            ulError = API_SemaphoreCPend(prwlock->PRWLOCK_ulWSemaphore,
                                         ulTimeout);                    /*  等待读写锁状态变换          */
            __PX_RWLOCK_LOCK(prwlock);                                  /*  锁定读写锁                  */
            if (ulError) {
                break;                                                  /*  直接跳出                    */
            }
        }
        
        ulTimeout = _sigTimeoutRecalc(ulOrgKernelTime, ulTimeout);      /*  重新计算等待时间            */
    } while (1);
    
    if (ulError == ERROR_NONE) {
        prwlock->PRWLOCK_ulOwner = API_ThreadIdSelf();                  /*  读写锁拥有者                */
    }
    __PX_RWLOCK_UNLOCK(prwlock);                                        /*  解锁读写锁                  */
    
    if (ulError == ERROR_THREAD_WAIT_TIMEOUT) {
        ulError = ETIMEDOUT;
        errno   = ETIMEDOUT;
    }
    
    return  ((INT)ulError);
}
示例#13
0
/*********************************************************************************************************
** 函数名称: API_TShellExecBg
** 功能描述: ttiny shell 系统, 背景执行一条 shell 命令 (不过成功与否都会关闭需要关闭的文件)
** 输 入  : pcCommand    命令字符串
**           iFd[3]       标准文件
**           bClosed[3]   执行结束后是否关闭对应标准文件
**           bIsJoin      是否等待命令执行结束
**           pulSh        背景线程句柄, (仅当 bIsJoin = LW_FALSE 时返回)
** 输 出  : 命令返回值(当发生错误时, 返回值为负值)
** 全局变量: 
** 调用模块: 
** 注  意  : 当 shell 检测出命令字符串错误时, 将会返回负值, 此值取相反数后即为错误编号.
                                           API 函数
*********************************************************************************************************/
LW_API  
INT  API_TShellExecBg (CPCHAR  pcCommandExec, INT  iFd[3], BOOL  bClosed[3], 
                       BOOL  bIsJoin, LW_OBJECT_HANDLE *pulSh)
{
    INT  iRet;
    INT  iError;
    INT  iFdArray[3];
    BOOL bClosedArray[3];
    
    if (__PROC_GET_PID_CUR() != 0) {                                    /*  进程中创建                  */
        if (iFd == LW_NULL) {
            iFdArray[0] = dup2kernel(STD_IN);
            iFdArray[1] = dup2kernel(STD_OUT);
            iFdArray[2] = dup2kernel(STD_ERR);
        } else {
            iFdArray[0] = dup2kernel(iFd[0]);
            iFdArray[1] = dup2kernel(iFd[1]);
            iFdArray[2] = dup2kernel(iFd[2]);
        }
        /*
         *  由于相关文件已经 dup 到内核中, 所以这里可以关闭进程中的相关的文件
         */
        if (bClosed && iFd) {
            if (bClosed[0]) {
                close(iFd[0]);
            }
            if (bClosed[1]) {
                close(iFd[1]);
            }
            if (bClosed[2]) {
                close(iFd[2]);
            }
        }
        
        /*
         *  由于已经 dup 到内核中, 这里必须在运行结束后关闭这些文件
         */
        bClosedArray[0] = LW_TRUE;                                      /*  执行完毕后需要关闭这些       */
        bClosedArray[1] = LW_TRUE;
        bClosedArray[2] = LW_TRUE;
        
        iFd     = iFdArray;
        bClosed = bClosedArray;                                         /*  文件是 dup 出来的这里必须全关*/
    
    } else {                                                            /*  内核中调用                   */
        if (iFd == LW_NULL) {
            LW_OBJECT_HANDLE  ulMe = API_ThreadIdSelf();
            iFd = iFdArray;
            iFdArray[0] = API_IoTaskStdGet(ulMe, STD_IN);
            iFdArray[1] = API_IoTaskStdGet(ulMe, STD_OUT);
            iFdArray[2] = API_IoTaskStdGet(ulMe, STD_ERR);
        }
        if (bClosed == LW_NULL) {
            bClosed = bClosedArray;
            bClosedArray[0] = LW_FALSE;
            bClosedArray[1] = LW_FALSE;
            bClosedArray[2] = LW_FALSE;
        }
    }
    
    iError = __tshellBgCreateEx(iFd, bClosed, pcCommandExec, 0ul,
                                lib_strlen(pcCommandExec), bIsJoin, 0, pulSh, &iRet);
    if (iError < 0) {                                                   /*  背景创建失败                */
        /*
         *  运行失败, 则关闭内核中需要关闭的文件
         */
        __KERNEL_SPACE_ENTER();
        if (bClosed[0]) {
            close(iFd[0]);
        }
        if (bClosed[1]) {
            close(iFd[1]);
        }
        if (bClosed[2]) {
            close(iFd[2]);
        }
        __KERNEL_SPACE_EXIT();
    }                                                                   /*  如果运行成功, 则会自动关闭  */
    
    return  (iRet);
}
示例#14
0
文件: aio.c 项目: Ga-vin/libsylixos
/*********************************************************************************************************
** 函数名称: lio_listio
** 功能描述: 同时发起多个传输 mode 参数可以是 LIO_WAIT 或 LIO_NOWAIT。LIO_WAIT 会阻塞这个调用,
             直到所有的 I/O 都完成为止. 在操作进行排队之后,LIO_NOWAIT 就会返回. 
             sigevent 引用定义了在所有 I/O 操作都完成时产生信号的方法。
** 输 入  : mode              LIO_WAIT or LIO_NOWAIT。LIO_WAIT
**           list              aio 请求控制块数组 (如果其中有 NULL, 程序将忽略)
**           nent              数组元素个数
**           sig               所有 I/O 操作都完成时产生信号的方法
                               LIO_WAIT 将会忽略此参数!
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  lio_listio (int mode, struct aiocb * const list[], int nent, struct sigevent *sig)
{
    AIO_WAIT_CHAIN     *paiowc;
    struct aiowait     *paiowait;
    
    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            */
    
    if ((mode != LIO_WAIT) && (mode != LIO_NOWAIT)) {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    if ((nent <= 0) || (list == LW_NULL)) {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    if (mode == LIO_WAIT) {
        paiowc = __aioCreateWaitChain(nent, LW_TRUE);                   /*  创建等待队列                */
    } else {
        paiowc = __aioCreateWaitChain(nent, LW_FALSE);
    }
    if (paiowc == LW_NULL) {
        errno = ENOMEM;                                                 /*  should be EAGAIN ?          */
        return  (PX_ERROR);
    }
    
    if (sig) {
        paiowc->aiowc_sigevent = *sig;
    } else {
        paiowc->aiowc_sigevent.sigev_signo = 0;                         /*  无效信号不投递              */
    }
    
    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_lio_opcode != LIO_NOP) &&
                (list[iCnt]->aio_req.aioreq_error != EINPROGRESS)) {
                
                list[iCnt]->aio_sigevent.sigev_notify = SIGEV_NONE;     /*  不使用 aiocb 的 sigevent    */
                list[iCnt]->aio_req.aioreq_thread     = API_ThreadIdSelf();
                
                if (mode == LIO_WAIT) {
                    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;          /*  不需要代理线程释放          */
                
                } else {
                    paiowait[iWait].aiowt_pcond     = LW_NULL;
                    paiowait[iWait].aiowt_pcnt      = LW_NULL;
                    paiowait[iWait].aiowt_psigevent = &paiowc->aiowc_sigevent;
                    paiowait[iWait].aiowt_paiowc    = (void *)paiowc;
                }
                
                __aioAttachWaitNoCheck(list[iCnt], &paiowait[iWait]);   /*  aiocb and aiowait attach    */
                
                if (__aioEnqueue(list[iCnt]) == ERROR_NONE) {
                
                    _List_Line_Add_Tail(&paiowait[iWait].aiowt_line, 
                                        &paiowc->aiowc_pline);          /*  加入 wait 链表              */
                    iWait++;
                
                } else {
                    __aioDetachWait(LW_NULL, &paiowait[iWait]);         /*  删除关联关系                */
                    
                    iRet = PX_ERROR;
                }
            }
        }
    }
    
    if (iWait == 0) {                                                   /*  没有一个节点加入队列        */
        __aioDeleteWaitChain(paiowc);
        API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
        
        if (mode == LIO_NOWAIT) {
            if (sig && __issig(sig->sigev_signo)) {
                _doSigEvent(API_ThreadIdSelf(), sig, SI_ASYNCIO);
            }
        }
        return  (ERROR_NONE);
    
    } else if (mode == LIO_WAIT) {                                      /*  需要等待                    */
        
        __aioWaitChainSetCnt(paiowc, &iWait);                           /*  设置计数变量                */
        
        while (iWait > 0) {
            if (API_ThreadCondWait(&paiowc->aiowc_cond, 
                                   _G_aioqueue.aioq_mutex, 
                                   LW_OPTION_WAIT_INFINITE)) {          /*  等待所有请求执行完毕        */
                break;
            }
        }
        
        __aioDeleteWaitChain(paiowc);                                   /*  清除 wait 队列              */
        
    } else {                                                            /*  LIO_NOWAIT                  */
        paiowc->aiowc_icnt = iWait;                                     /*  必须使用全局变量            */
        
        __aioWaitChainSetCnt(paiowc, &paiowc->aiowc_icnt);              /*  设置计数变量                */
    }
    
    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
                
    return  (iRet);
}
示例#15
0
/*********************************************************************************************************
** 函数名称: syslog_r
** 功能描述: submits a message to the Syslog facility. It does this by writing to the file (支持不完整)
             LOG_DEFAULT_FILE
** 输 入  : priority      priority
**           data          syslog_data
**           message       message
             ...
** 输 出  : old mask
** 全局变量:
** 调用模块:
                                           API 函数
*********************************************************************************************************/
LW_API
void  syslog_r (int priority, struct syslog_data *data, const char *message, ...)
{
#define __PX_SYSLOG_TIMEFMT   "%s %2d %02d:%02d:%02d"

    CHAR            cBuffer[LOG_DEFAULT_SIZE];
    size_t          stLen;

    time_t          time;
    struct tm       tmBuf;

    va_list         valist;

    if (!data) {
        errno = EINVAL;
        return;
    }

    if (((unsigned)LOG_FAC(priority) >= LOG_NFACILITIES)  ||
            (LOG_MASK(LOG_PRI(priority)) == 0)                ||
            ((priority & ~(LOG_PRIMASK | LOG_FACMASK)) != 0)) {
        return;                                                         /*  不发送                      */
    }

    if ((data->log_file < 0) && (data->log_stat & LOG_ODELAY)) {        /*  是否需要执行一次打开操作    */
        openlog(data->log_tag, data->log_file, 0);
        data->log_file = _G_iSyslogUnix;
    }

    if ((priority & LOG_FACMASK) == 0) {
        priority |= data->log_fac;
    }

    time = lib_time(LW_NULL);
    lib_localtime_r(&time, &tmBuf);                                     /*  RFC3164 is the local time   */

    stLen = bnprintf(cBuffer, sizeof(cBuffer), 0, "<%d>", priority);    /*  打印 priority               */
    stLen = bnprintf(cBuffer, sizeof(cBuffer), stLen,
                     __PX_SYSLOG_TIMEFMT,
                     _G_cMonth[tmBuf.tm_mon],
                     tmBuf.tm_mday,
                     tmBuf.tm_hour,
                     tmBuf.tm_min,
                     tmBuf.tm_sec);                                     /*  打印 时间                   */

    if (data->log_tag) {
        stLen = bnprintf(cBuffer, sizeof(cBuffer), stLen, " %s", data->log_tag);
    }

    if (data->log_stat & LOG_PID) {
        if (sizeof(cBuffer) > stLen) {
            stLen = bnprintf(cBuffer, sizeof(cBuffer), stLen, "[%lx]:",
                             API_ThreadIdSelf());
        }
    }

    if (message) {
        if (sizeof(cBuffer) > stLen) {

#if __STDC__
            va_start(valist, message);
#else
            va_start(valist);
#endif
            stLen = vbnprintf(cBuffer, sizeof(cBuffer), stLen, message, valist);

            va_end(valist);
        }
    }

    if (data->log_file >= 0) {
        sendto(data->log_file, cBuffer, stLen, 0,
               (struct sockaddr *)&_G_sockaddrunLog, _G_sockelenLog);
    }

    if (data->log_stat & LOG_CONS) {
        write(STD_OUT, cBuffer, stLen);
    }

    if (data->log_stat & LOG_PERROR) {
        write(STD_ERR, cBuffer, stLen);
    }
}
示例#16
0
/*********************************************************************************************************
** 函数名称: raise
** 功能描述: 向自己发送信号
** 输 入  : iSigNo                  信号
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
INT  raise (INT  iSigNo)
{
    return  (kill(API_ThreadIdSelf(), iSigNo));
}
示例#17
0
static int  getpid ()
{
    long    l = (long)API_ThreadIdSelf();
    
    return  (int)((l & 0xffff));
}
示例#18
0
文件: sched.c 项目: Ga-vin/libsylixos
/*********************************************************************************************************
** 函数名称: sched_setscheduler
** 功能描述: 设置指定任务调度器
** 输 入  : pid           进程 / 线程 ID
**           iPolicy       调度策略
**           pschedparam   调度器参数
** 输 出  : ERROR or OK
** 全局变量:
** 调用模块:
                                           API 函数
*********************************************************************************************************/
LW_API
int  sched_setscheduler (pid_t                      pid,
                         int                        iPolicy,
                         const struct sched_param  *pschedparam)
{
    UINT8               ucPriority;
    UINT8               ucActivatedMode;
    LW_OBJECT_HANDLE    ulThread;

    if (pschedparam == LW_NULL) {
        errno = EINVAL;
        return  (PX_ERROR);
    }

    if ((iPolicy != LW_OPTION_SCHED_FIFO) &&
            (iPolicy != LW_OPTION_SCHED_RR)) {
        errno = EINVAL;
        return  (PX_ERROR);
    }

    if ((pschedparam->sched_priority < __PX_PRIORITY_MIN) ||
            (pschedparam->sched_priority > __PX_PRIORITY_MAX)) {
        errno = EINVAL;
        return  (PX_ERROR);
    }

    ucPriority= (UINT8)PX_PRIORITY_CONVERT(pschedparam->sched_priority);

#if LW_CFG_MODULELOADER_EN > 0
    if (pid == 0) {
        pid =  getpid();
    }
    if (pid == 0) {
        ulThread = API_ThreadIdSelf();
    } else {
        ulThread = vprocMainThread(pid);
    }
    if (ulThread == LW_OBJECT_HANDLE_INVALID) {
        errno = ESRCH;
        return  (PX_ERROR);
    }
#else
    ulThread = (LW_OBJECT_HANDLE)pid;
    PX_ID_VERIFY(ulThread, LW_OBJECT_HANDLE);
#endif                                                                  /*  LW_CFG_MODULELOADER_EN > 0  */

    if (API_ThreadGetSchedParam(ulThread,
                                LW_NULL,
                                &ucActivatedMode)) {
        errno = ESRCH;
        return  (PX_ERROR);
    }

    API_ThreadSetSchedParam(ulThread, (UINT8)iPolicy, ucActivatedMode);

    if (API_ThreadSetPriority(ulThread, ucPriority)) {
        errno = ESRCH;
        return  (PX_ERROR);
    } else {
        return  (ERROR_NONE);
    }
}
示例#19
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);
}
示例#20
0
/*********************************************************************************************************
** 函数名称: waitread
** 功能描述: select() 变种,等待单个文件可读.
** 输 入  : iFd               文件描述符
**           ptmvalTO          等待超时时间, LW_NULL 表示永远等待.
** 输 出  : 正常等待到的文件数, 为 1 表示文件可以读, 为 0 表示超时 ,错误返回 PX_ERROR.
**           errno == ERROR_IO_SELECT_UNSUPPORT_IN_DRIVER       驱动程序不支持
**           errno == ERROR_IO_SELECT_CONTEXT                   线程不存在 context
**           errno == ERROR_THREAD_WAIT_TIMEOUT                 等待超时
**           errno == ERROR_KERNEL_IN_ISR                       在中断中调用
**           errno == ERROR_IOS_INVALID_FILE_DESCRIPTOR         文件描述符无效.
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
INT     waitread (INT  iFd, struct timeval   *ptmvalTO)
{
    REGISTER INT                 iIsOk  = ERROR_NONE;                   /*  初始化为没有错误            */
    REGISTER INT                 iWidth = iFd + 1;                      /*  iFd + 1                     */
    REGISTER INT                 iWidthInBytes;                         /*  需要检测的位数占多少字节    */
    REGISTER ULONG               ulWaitTime;                            /*  等待时间                    */
    REGISTER LW_SEL_CONTEXT     *pselctx;
             PLW_CLASS_TCB       ptcbCur;
    
             fd_set              fdsetRead;
             LW_SEL_WAKEUPNODE   selwunNode;                            /*  生成的 NODE 模板            */
             ULONG               ulError;
    
    if (LW_CPU_GET_CUR_NESTING()) {
        _ErrorHandle(ERROR_KERNEL_IN_ISR);                              /*  不能在中断中调用            */
        return  (PX_ERROR);
    }
    
    if (iFd > (FD_SETSIZE - 1) || iFd < 0) {                            /*  文件号错误                  */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "file descriptor invalidate..\r\n");
        _ErrorHandle(ERROR_IOS_INVALID_FILE_DESCRIPTOR);                /*  文件描述符无效              */
        return  (PX_ERROR);
    }
    
    LW_TCB_GET_CUR_SAFE(ptcbCur);
    
    pselctx = ptcbCur->TCB_pselctxContext;
    
    if (!pselctx) {                                                     /*  没有 select context         */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "no select context.\r\n");
        _ErrorHandle(ERROR_IO_SELECT_CONTEXT);
        return  (PX_ERROR);
    }

    iWidthInBytes = __HOWMANY(iWidth, NFDBITS) * sizeof(fd_mask);       /*  需要检测的位数占多少字节    */
    
    FD_ZERO(&fdsetRead);                                                /*  清除文件集                  */
    FD_SET(iFd, &fdsetRead);                                            /*  指定文件置位                */
    
    __selFdsetInit(iWidthInBytes, &fdsetRead,                           /*  设置 OrigRead 文件位        */
                   LW_NULL, LW_NULL, pselctx);                          /*  __selTaskDeleteHook 使用    */
                   
    FD_CLR(iFd, &fdsetRead);                                            /*  清除文件集                  */

    if (!ptmvalTO) {                                                    /*  计算等待时间                */
        ulWaitTime = LW_OPTION_WAIT_INFINITE;                           /*  无限等待                    */
    } else {
        ulWaitTime = __timevalToTick(ptmvalTO);                         /*  计算超时时间                */
    }
    
    pselctx->SELCTX_pfdsetReadFds   = &fdsetRead;
    pselctx->SELCTX_pfdsetWriteFds  = LW_NULL;                          /*  保存用户参数地址            */
    pselctx->SELCTX_pfdsetExceptFds = LW_NULL;
    
    API_SemaphoreBClear(pselctx->SELCTX_hSembWakeup);                   /*  清除信号量                  */
    
    selwunNode.SELWUN_hThreadId  = API_ThreadIdSelf();
    selwunNode.SELWUN_seltypType = SELREAD;
    selwunNode.SELWUN_iFd        = iFd;
    
    pselctx->SELCTX_iWidth = iWidth;                                    /*  记录最大文件号              */
    pselctx->SELCTX_bPendedOnSelect = LW_TRUE;                          /*  需要 delete hook 清除 NODE  */
    
    iIsOk = ioctl(iFd, FIOSELECT, (LONG)&selwunNode);                   /*  FIOSELECT                   */
    if (iIsOk != ERROR_NONE) {
        ULONG   ulError = API_GetLastError();
        iIsOk  = ioctl(iFd, FIOUNSELECT, (LONG)&selwunNode);            /*  FIOUNSELECT                 */
        if (ulError == ERROR_IO_UNKNOWN_REQUEST) {
            _ErrorHandle(ERROR_IO_SELECT_UNSUPPORT_IN_DRIVER);          /*  驱动程序不支持              */
        }
        pselctx->SELCTX_bPendedOnSelect = LW_FALSE;                     /*  自行清理完毕                */
        return  (PX_ERROR);                                             /*  错误                        */
    }
    
    API_SemaphoreBPend(pselctx->SELCTX_hSembWakeup, ulWaitTime);        /*  开始等待                    */
    ulError = API_GetLastError();
    
    iIsOk = ioctl(iFd, FIOUNSELECT, (LONG)&selwunNode);                 /*  FIOUNSELECT                 */
    
    pselctx->SELCTX_bPendedOnSelect = LW_FALSE;                         /*  自行清理完毕                */
    
    if (iIsOk != ERROR_NONE) {
        return  (PX_ERROR);                                             /*  出现错误                    */
    } else {
        _ErrorHandle(ulError);
    }
    
    if (FD_ISSET(iFd, &fdsetRead)) {                                    /*  检查文件是否可读            */
        return  (1);
    } else {
        return  (0);
    }
}