分类: C/C++
2018-06-25 10:53:25
在移植中间件过程中,在SylixOS下调用pthread_join时,如果线程在pthread_join等待之前结束,则线程返回无效线程错误值。在Linux下这种调用会正常返回。两种实现是有差别的,实现的原理分别如下。
在SylixOS下调用pthread_join时,如果线程在pthread_join等待之前结束,线程返回无效线程错误标志,具体实现如程序清单 2.1所示。函数在实现中会先检测线程是否有效,如果线程无效则直接返回线程无效的错误。
程序清单 2.1 SylixOS pthread_join实现机制
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); } |
在Linux下如果在调用pthread_join前线程已经退出,则返回正常值。在中间件移植过程中针对pthread_join的测试用例会可能出现问题,此时如果线程结束后调用pthread_join在SylixOS下会出现问题,而在Linux是正常,需要屏蔽该类型的用例。