/********************************************************************************************************* ** 函数名称: sched_yield ** 功能描述: 将当前任务插入到同优先级调度器链表的最后, 主动让出一次 CPU 调度. ** 输 入 : NONE ** 输 出 : ERROR_NONE ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API int sched_yield (void) { API_ThreadYield(API_ThreadIdSelf()); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __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); }
/********************************************************************************************************* ** 函数名称: 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); } }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: API_HotplugContext ** 功能描述: 是否在 hotplug 处理线程中 ** 输 入 : ** 输 出 : ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API BOOL API_HotplugContext (VOID) { if (API_ThreadIdSelf() == _G_hHotplug) { return (LW_TRUE); } else { return (LW_FALSE); } }
/********************************************************************************************************* ** 函数名称: 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); /* 退出内核同时打开中断 */ }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: 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); } }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: 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); } }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: 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); } }
/********************************************************************************************************* ** 函数名称: raise ** 功能描述: 向自己发送信号 ** 输 入 : iSigNo 信号 ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT raise (INT iSigNo) { return (kill(API_ThreadIdSelf(), iSigNo)); }
static int getpid () { long l = (long)API_ThreadIdSelf(); return (int)((l & 0xffff)); }
/********************************************************************************************************* ** 函数名称: 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); } }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: 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); } }