disable thread dispatch problem

Joel Sherrill joel.sherrill at OARcorp.com
Fri Jul 6 13:19:33 UTC 2012


On 07/06/2012 04:49 AM, Ashi wrote:
> Hi, all.
> I've a problem of _Thread_Disable_dispatch() function in below code. 
> It's my implementation of _POSIX_Keys_Run_destructors() function. I 
> come across the problem when I run the psxkey03 test:if 
> _Thread_Disable_dispatch() was commented out, psxkey03 can run without 
> problem. when _Thread_Disable_dispatch() added at line 1(as below), 
> psxkey03 will fail. I debug it in sparc-rtems4.11-gdb, and find 
> psxkey03 runs into _Internal_error_Occurred() function then stop. I 
> know _POSIX_Keys_Get()(at line 12) will also disable thread 
> dispatch--does this lead to the problem? However, can't figure out 
> where exactly the problem exists, could anyone explain it? Thanks!

This call chain goes back to score/src/threadclose.c and this section of 
code.

   /*
    *  We assume the Allocator Mutex is locked when we get here.
    *  This provides sufficient protection to let the user extensions
    *  run but as soon as we get back, we will make the thread
    *  disappear and set a transient state on it.  So we temporarily
    *  unnest dispatching.
    */
   _Thread_Unnest_dispatch();

   _User_extensions_Thread_delete( the_thread );

  **** you are called in this state ***
   - mutex allocator locked
   - dispatching disabled (level = 1)

>
>   1 _Thread_Disable_dispatch();
>
>   2 chain = &((POSIX_API_Control *)thread->API_Extensions[ 
> THREAD_API_POSIX ])->the_chain;
>   3 iter = _Chain_First( chain );
>   4 while ( !_Chain_Is_tail( chain, iter ) ) {
>   5 next = _Chain_Next( iter );
>   6  /**
>   7   * here Chain_Node *iter can be convert to POSIX_Keys_Rbtree_node *,
>   8   * because Chain_Node is the first member of 
> POSIX_Keys_Rbtree_node structure.
>   9   */
>   10  _RBTree_Extract_unprotected( &_POSIX_Keys_Rbtree, 
> &((POSIX_Keys_Rbtree_node *)iter)->rb_node );
>   11 _Chain_Extract_unprotected( iter );
>
Thread dispatching is disabled here to level 1.
>   12  the_key = _POSIX_Keys_Get( ((POSIX_Keys_Rbtree_node 
> *)iter)->key, &location);
This nests the dispatching level to 2.

I would move your code below the _POSIX_Keys_Get() call. There are logically
two actions: key removal from rbtree and run the destructor. Put comments
above each block of code indicating what is happening LOGICALLY. Everyone
can read the code.

If order is important between the two blocks, document it. I am assuming 
your
block will move between lines 12 and 13.
>   13  destructor = the_key->destructor;
>   14  value = ((POSIX_Keys_Rbtree_node *)iter)->value;
>   15  if ( destructor != NULL && value != NULL )
>   16    (*destructor)( value );
>
>   17  _Workspace_Free( (POSIX_Keys_Rbtree_node *)iter );
>   18  iter = next;
>   19}
>
>   20_Thread_Enable_dispatch();
>
> ---
> Best regards!
> Zhongwei Yao
>


-- 
Joel Sherrill, Ph.D.             Director of Research&   Development
joel.sherrill at OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
     Support Available             (256) 722-9985





More information about the devel mailing list