Exemplo n.º 1
0
void *pthread_getspecific(
  pthread_key_t  key
)
{
  register POSIX_Keys_Control *the_key;
  uint32_t                     api;
  uint32_t                     index;
  Objects_Locations            location;
  void                        *key_data;

  the_key = _POSIX_Keys_Get( key, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      api      = _Objects_Get_API( _Thread_Executing->Object.id );
      index    = _Objects_Get_index( _Thread_Executing->Object.id );
      key_data = (void *) the_key->Values[ api ][ index ];
      _Thread_Enable_dispatch();
      return key_data;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:   /* should never happen */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return NULL;
}
Exemplo n.º 2
0
/*
 *  17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167
 */
int pthread_key_delete(
  pthread_key_t  key
)
{
  POSIX_Keys_Control *the_key;
  Objects_Locations   location;

  _Objects_Allocator_lock();
  the_key = _POSIX_Keys_Get( key, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      _POSIX_Keys_Free_memory( the_key );

      /*
       *  NOTE:  The destructor is not called and it is the responsibility
       *         of the application to free the memory.
       */
      _POSIX_Keys_Free( the_key );
      _Objects_Put(&the_key->Object);
      _Objects_Allocator_unlock();
      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:   /* should never happen */
#endif
    case OBJECTS_ERROR:
      break;
  }

  _Objects_Allocator_unlock();

  return EINVAL;
}
Exemplo n.º 3
0
/*
 *  _POSIX_Keys_Run_destructors
 *
 *  17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
 *
 *  NOTE:  This is the routine executed when a thread exits to
 *         run through all the keys and do the destructor action.
 */
void _POSIX_Keys_Run_destructors(
  Thread_Control *thread
)
{
  Chain_Control *chain;
  POSIX_Keys_Key_value_pair *iter, *next;
  void *value;
  void (*destructor) (void *);
  POSIX_Keys_Control *the_key;
  Objects_Locations location;

  _Thread_Disable_dispatch();

  chain = &(
      (POSIX_API_Control *)thread->API_Extensions[ THREAD_API_POSIX ]
  )->Key_Chain;
  iter = (POSIX_Keys_Key_value_pair *) _Chain_First( chain );
  while ( !_Chain_Is_tail( chain, &iter->Key_values_per_thread_node ) ) {
    next = (POSIX_Keys_Key_value_pair *)
      _Chain_Next( &iter->Key_values_per_thread_node );

    /**
     * remove key from rbtree and chain.
     * here Chain_Node *iter can be convert to POSIX_Keys_Key_value_pair *,
     * because Chain_Node is the first member of POSIX_Keys_Key_value_pair
     * structure.
     */
    _RBTree_Extract(
        &_POSIX_Keys_Key_value_lookup_tree,
        &iter->Key_value_lookup_node
    );
    _Chain_Extract_unprotected( &iter->Key_values_per_thread_node );

    /**
     * run key value's destructor if destructor and value are both non-null.
     */
    the_key = _POSIX_Keys_Get( iter->key, &location );
    destructor = the_key->destructor;
    value = iter->value;
    if ( destructor != NULL && value != NULL )
      (*destructor)( value );

    _Objects_Put( &the_key->Object );

    _POSIX_Keys_Key_value_pair_free( iter );

    iter = next;
  }

  _Thread_Enable_dispatch();
}
Exemplo n.º 4
0
int pthread_setspecific(
  pthread_key_t  key,
  const void    *value
)
{
  POSIX_Keys_Control          *the_key;
  Objects_Locations            location;
  POSIX_Keys_Key_value_pair   *value_pair_ptr;
  RBTree_Node                 *p;
  POSIX_Keys_Key_value_pair    search_node;
  Thread_Control              *executing;

  the_key = _POSIX_Keys_Get( key, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      executing = _Thread_Executing;
      p = _POSIX_Keys_Find( key, executing, &search_node );
      if ( p != NULL ) {
        value_pair_ptr = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( p );
        value_pair_ptr->value = RTEMS_DECONST( void *, value );
      } else {
Exemplo n.º 5
0
void *pthread_getspecific(
  pthread_key_t  key
)
{
  POSIX_Keys_Control          *the_key;
  Objects_Locations            location;
  POSIX_Keys_Key_value_pair    search_node;
  RBTree_Node                 *p;
  void                        *key_data;
  POSIX_Keys_Key_value_pair   *value_pair_p;

  the_key = _POSIX_Keys_Get( key, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      p = _POSIX_Keys_Find( key, _Thread_Executing, &search_node );
      if ( p != NULL ) {
        value_pair_p = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( p );
        key_data = value_pair_p->value;
      } else {
        key_data = NULL;
      }

      _Objects_Put( &the_key->Object );

      return key_data;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:   /* should never happen */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return NULL;
}
Exemplo n.º 6
0
int pthread_key_delete(
  pthread_key_t  key
)
{
  register POSIX_Keys_Control *the_key;
  Objects_Locations            location;
  uint32_t                     the_api;

  the_key = _POSIX_Keys_Get( key, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      _Objects_Close( &_POSIX_Keys_Information, &the_key->Object );

      for ( the_api = 1; the_api <= OBJECTS_APIS_LAST; the_api++ )
        if ( the_key->Values[ the_api ] )
          _Workspace_Free( the_key->Values[ the_api ] );

      /*
       *  NOTE:  The destructor is not called and it is the responsibility
       *         of the application to free the memory.
       */

      _POSIX_Keys_Free( the_key );
      _Thread_Enable_dispatch();
      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:   /* should never happen */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return EINVAL;
}
Exemplo n.º 7
0
int pthread_setspecific(
  pthread_key_t  key,
  const void    *value
)
{
  POSIX_Keys_Control          *the_key;
  Objects_Locations            location;
  POSIX_Keys_Key_value_pair   *value_pair_ptr;
  RBTree_Node                 *p;
  POSIX_Keys_Key_value_pair    search_node;
  Thread_Control              *executing;

  the_key = _POSIX_Keys_Get( key, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      executing = _Thread_Executing;
      p = _POSIX_Keys_Find( key, executing, &search_node );
      if ( p != NULL ) {
        value_pair_ptr = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( p );
        value_pair_ptr->value = value;
      } else {
        value_pair_ptr = _POSIX_Keys_Key_value_pair_allocate();

        if ( !value_pair_ptr ) {
          _Objects_Put( &the_key->Object );

          return ENOMEM;
        }

        value_pair_ptr->key = key;
        value_pair_ptr->thread = executing;
        value_pair_ptr->value = value;
        /* The insert can only go wrong if the same node is already in a unique
         * tree. This has been already checked with the _RBTree_Find() */
        _RBTree_Insert(
          &_POSIX_Keys_Key_value_lookup_tree,
          &value_pair_ptr->Key_value_lookup_node,
          _POSIX_Keys_Key_value_compare,
          true
        );

        /** append rb_node to the thread API extension's chain */
        _Chain_Append_unprotected(
          &_Thread_Executing->Key_Chain,
          &value_pair_ptr->Key_values_per_thread_node
        );
      }

      _Objects_Put( &the_key->Object );

      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:   /* should never happen */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return EINVAL;
}