Chinaunix首页 | 论坛 | 博客
  • 博客访问: 10405
  • 博文数量: 7
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 80
  • 用 户 组: 普通用户
  • 注册时间: 2017-10-31 17:54
文章分类
文章存档

2018年(5)

2017年(2)

我的朋友

分类: C/C++

2018-06-25 10:53:25

1 问题描述

在移植中间件过程中,在SylixOS下调用pthread_join时,如果线程在pthread_join等待之前结束,则线程返回无效线程错误值。在Linux下这种调用会正常返回。两种实现是有差别的,实现的原理分别如下。

2 pthread_join函数的实现机制

2.1 SylixOS实现机制

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);

}

2.2 Linux实现机制

Linux下如果在调用pthread_join前线程已经退出,则返回正常值。在中间件移植过程中针对pthread_join的测试用例会可能出现问题,此时如果线程结束后调用pthread_joinSylixOS下会出现问题,而在Linux是正常,需要屏蔽该类型的用例。

阅读(302) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~