Changeset b5c9064 in rtems


Ignore:
Timestamp:
Aug 5, 2013, 1:20:45 PM (7 years ago)
Author:
Zhongwei Yao <ashi08104@…>
Branches:
4.11, 5, master
Children:
03a5a8a
Parents:
5a556e4e
git-author:
Zhongwei Yao <ashi08104@…> (08/05/13 13:20:45)
git-committer:
Sebastian Huber <sebastian.huber@…> (08/06/13 12:11:38)
Message:

Unlimited objects support for POSIX keys

This patch enables unlimited model in POSIX key manger and have a decent
runtime on POSIX key searching, adding and deleting operations. Memory
overhead is lower than current implementation when the size of key and key
value becomes big.

Files:
28 added
16 edited

Legend:

Unmodified
Added
Removed
  • cpukit/posix/include/rtems/posix/config.h

    r5a556e4e rb5c9064  
    5252  uint32_t                            maximum_condition_variables;
    5353  uint32_t                            maximum_keys;
     54  uint32_t                            maximum_key_value_pairs;
    5455  uint32_t                            maximum_timers;
    5556  uint32_t                            maximum_queued_signals;
  • cpukit/posix/include/rtems/posix/key.h

    r5a556e4e rb5c9064  
    11/**
    22 * @file
    3  * 
     3 *
    44 * @brief POSIX Key Private Support
    55 *
     
    99
    1010/*
    11  *  COPYRIGHT (c) 1989-2011.
    12  *  On-Line Applications Research Corporation (OAR).
     11 * Copyright (c) 2012 Zhongwei Yao.
     12 * COPYRIGHT (c) 1989-2011.
     13 * On-Line Applications Research Corporation (OAR).
    1314 *
    14  *  The license and distribution terms for this file may be
    15  *  found in the file LICENSE in this distribution or at
    16  *  http://www.rtems.com/license/LICENSE.
     15 * The license and distribution terms for this file may be
     16 * found in the file LICENSE in this distribution or at
     17 * http://www.rtems.com/license/LICENSE.
    1718 */
    1819
     
    2021#define _RTEMS_POSIX_KEY_H
    2122
     23#include <rtems/score/rbtree.h>
     24#include <rtems/score/chainimpl.h>
     25#include <rtems/score/freechain.h>
    2226#include <rtems/score/objectimpl.h>
    2327
     
    2630 *
    2731 * @ingroup POSIXAPI
    28  * 
     32 *
    2933 */
    3034/**@{**/
     
    3539
    3640/**
    37  * This is the data Structure used to manage a POSIX key.
    38  *
    39  * NOTE: The Values is a table indexed by the index portion of the
    40  *       ID of the currently executing thread.
     41 * @brief The rbtree node used to manage a POSIX key and value.
     42 */
     43typedef struct {
     44  /** This field is the chain node structure. */
     45  Chain_Node Key_values_per_thread_node;
     46  /** This field is the rbtree node structure. */
     47  RBTree_Node Key_value_lookup_node;
     48  /** This field is the POSIX key used as an rbtree key */
     49  pthread_key_t key;
     50  /** This field is the Thread id also used as an rbtree key */
     51  Objects_Id thread_id;
     52  /** This field points to the POSIX key value of specific thread */
     53  void *value;
     54}  POSIX_Keys_Key_value_pair;
     55
     56/**
     57 * @brief POSIX_Keys_Freechain is used in Freechain structure
     58 */
     59typedef struct {
     60    Freechain_Control super_fc;
     61    size_t bump_count;
     62} POSIX_Keys_Freechain;
     63
     64/**
     65 * @brief The data structure used to manage a POSIX key.
    4166 */
    4267typedef struct {
    4368   /** This field is the Object control structure. */
    4469   Objects_Control     Object;
    45    /** This field points to the optional destructor method. */
    46    void              (*destructor)( void * );
    47    /** This field points to the values per thread. */
    48    void              **Values[ OBJECTS_APIS_LAST + 1 ];
    49 }  POSIX_Keys_Control;
     70   /** This field is the data destructor. */
     71   void (*destructor) (void *);
     72 }  POSIX_Keys_Control;
    5073
    5174/**
    52  * The following defines the information control block used to manage
    53  * this class of objects.
     75 * @brief The information control block used to manage this class of objects.
    5476 */
    5577POSIX_EXTERN Objects_Information  _POSIX_Keys_Information;
    5678
    5779/**
    58  * @brief POSIX keys manager initialization.
     80 * @brief The rbtree control block used to manage all key values
     81 */
     82POSIX_EXTERN RBTree_Control _POSIX_Keys_Key_value_lookup_tree;
     83
     84/**
     85 * @brief This freechain is used as a memory pool for POSIX_Keys_Key_value_pair.
     86 */
     87POSIX_EXTERN POSIX_Keys_Freechain _POSIX_Keys_Keypool;
     88
     89/**
     90 * @brief POSIX key manager initialization.
    5991 *
    6092 * This routine performs the initialization necessary for this manager.
    6193 */
    6294void _POSIX_Key_Manager_initialization(void);
     95
     96/**
     97 * @brief POSIX key Freechain extend handle
     98 *
     99 * This routine extend freechain node, which is called in freechain_get
     100 * automatically.
     101 */
     102bool _POSIX_Keys_Freechain_extend(Freechain_Control *freechain);
     103
     104/**
     105 * @brief POSIX keys Red-Black tree node comparison.
     106 *
     107 * This routine compares the rbtree node
     108 */
     109int _POSIX_Keys_Key_value_lookup_tree_compare_function(
     110  const RBTree_Node *node1,
     111  const RBTree_Node *node2
     112);
    63113
    64114/**
     
    68118 * keys.  This function will execute until all values have been set to NULL.
    69119 *
    70  * @param[in] thread is a pointer to the thread whose keys should have 
     120 * @param[in] thread is a pointer to the thread whose keys should have
    71121 *            all their destructors run.
    72122 *
  • cpukit/posix/include/rtems/posix/threadsup.h

    r5a556e4e rb5c9064  
    8484  Chain_Control           Cancellation_Handlers;
    8585
     86  /**
     87   * This is the thread key value chain's control, which is used
     88   * to track all key value for specific thread, and when thread
     89   * exits, we can remove all key value for specific thread by
     90   * iterating this chain, or we have to search a whole rbtree,
     91   * which is inefficient.
     92   */
     93  Chain_Control           Key_Chain;
     94
    8695} POSIX_API_Control;
    8796
  • cpukit/posix/src/key.c

    r5a556e4e rb5c9064  
    77
    88/*
    9  *  COPYRIGHT (c) 1989-2008.
    10  *  On-Line Applications Research Corporation (OAR).
     9 * Copyright (c) 2012 Zhongwei Yao.
     10 * COPYRIGHT (c) 1989-2008.
     11 * On-Line Applications Research Corporation (OAR).
    1112 *
    12  *  The license and distribution terms for this file may be
    13  *  found in the file LICENSE in this distribution or at
    14  *  http://www.rtems.com/license/LICENSE.
     13 * The license and distribution terms for this file may be
     14 * found in the file LICENSE in this distribution or at
     15 * http://www.rtems.com/license/LICENSE.
    1516 */
    1617
     
    3031#include <rtems/score/wkspace.h>
    3132#include <rtems/posix/key.h>
     33#include <rtems/score/rbtree.h>
     34#include <rtems/score/chain.h>
     35#include <rtems/score/freechain.h>
    3236
    33 /*
    34  *  _POSIX_Key_Manager_initialization
     37/* forward declarations to avoid warnings */
     38void _POSIX_Keys_Keypool_init(void);
     39void _POSIX_Keys_Freechain_init(Freechain_Control *freechain);
     40
     41/**
     42 * @brief This routine compares the rbtree node by comparing POSIX key first
     43 * and comparing thread id second.
    3544 *
    36  *  DESCRIPTION:
     45 * if either of the input nodes's thread_id member is 0, then it will only
     46 * compare the pthread_key_t member. That is when we pass thread_id = 0 node
     47 * as a search node, the search is done only by pthread_key_t.
    3748 *
    38  *  This routine performs the initialization necessary for this manager.
    39  *
    40  *  Input parameters:   NONE
    41  *
    42  *  Output parameters:  NONE
     49 * @param[in] node1 The node to be compared
     50 * @param[in] node2 The node to be compared
     51 * @retval positive if first node has higher key than second
     52 * @retval negative if lower
     53 * @retval 0 if equal,and for all the thread id is unique, then return 0 is
     54 * impossible
    4355 */
    4456
     57int _POSIX_Keys_Key_value_lookup_tree_compare_function(
     58  const RBTree_Node *node1,
     59  const RBTree_Node *node2
     60)
     61{
     62  POSIX_Keys_Key_value_pair *n1;
     63  POSIX_Keys_Key_value_pair *n2;
     64  Objects_Id thread_id1, thread_id2;
     65  int diff;
     66
     67  n1 = _RBTree_Container_of( node1, POSIX_Keys_Key_value_pair, Key_value_lookup_node );
     68  n2 = _RBTree_Container_of( node2, POSIX_Keys_Key_value_pair, Key_value_lookup_node );
     69
     70  diff = n1->key - n2->key;
     71  if ( diff )
     72    return diff;
     73
     74  thread_id1 = n1->thread_id;
     75  thread_id2 = n2->thread_id;
     76
     77  /**
     78   * if thread_id1 or thread_id2 equals to 0, only key1 and key2 is valued.
     79   * it enables us search node only by pthread_key_t type key.
     80   */
     81  if ( thread_id1 && thread_id2 )
     82    return thread_id1 - thread_id2;
     83  return 0;
     84}
     85
     86/**
     87 * @brief This routine does keypool initialize, keypool contains all
     88 * POSIX_Keys_Key_value_pair
     89 */
     90
     91void _POSIX_Keys_Keypool_init(void)
     92{
     93  _Freechain_Initialize((Freechain_Control *)&_POSIX_Keys_Keypool,
     94                       &_POSIX_Keys_Freechain_extend);
     95
     96  _POSIX_Keys_Freechain_init((Freechain_Control *)&_POSIX_Keys_Keypool);
     97}
     98
     99/**
     100 * @brief This routine does user side freechain initialization
     101 */
     102void _POSIX_Keys_Freechain_init(Freechain_Control *freechain)
     103{
     104  POSIX_Keys_Freechain *psx_freechain_p = (POSIX_Keys_Freechain *)freechain;
     105  psx_freechain_p->bump_count =
     106    Configuration_POSIX_API.maximum_key_value_pairs & 0x7FFFFFFF;
     107  size_t size = psx_freechain_p->bump_count * sizeof(POSIX_Keys_Key_value_pair);
     108  POSIX_Keys_Key_value_pair *nodes = _Workspace_Allocate(size);
     109
     110  _Chain_Initialize(
     111                    &freechain->Freechain,
     112                    nodes,
     113                    psx_freechain_p->bump_count,
     114                    sizeof(POSIX_Keys_Key_value_pair)
     115                    );
     116}
     117
     118/**
     119 * @brief This routine is user defined freechain extension handle
     120 */
     121bool _POSIX_Keys_Freechain_extend(Freechain_Control *freechain)
     122{
     123  POSIX_Keys_Freechain *psx_freechain_p = (POSIX_Keys_Freechain *)freechain;
     124  size_t node_size = sizeof(POSIX_Keys_Key_value_pair);
     125  size_t size = psx_freechain_p->bump_count * node_size;
     126  int i;
     127  POSIX_Keys_Key_value_pair *nodes = _Workspace_Allocate(size);
     128
     129  if (!nodes)
     130    return false;
     131
     132  for ( i = 0; i < psx_freechain_p->bump_count; i++ ) {
     133      _Freechain_Put(freechain,
     134                     nodes + i);
     135  }
     136  return true;
     137}
     138
     139/**
     140 * @brief This routine performs the initialization necessary for this manager.
     141 */
    45142void _POSIX_Key_Manager_initialization(void)
    46143{
     
    61158#endif
    62159  );
     160
     161  _RBTree_Initialize_empty(
     162      &_POSIX_Keys_Key_value_lookup_tree,
     163      _POSIX_Keys_Key_value_lookup_tree_compare_function,
     164      true
     165  );
     166
     167  _POSIX_Keys_Keypool_init();
    63168}
  • cpukit/posix/src/keycreate.c

    r5a556e4e rb5c9064  
    11/**
    2  *  @file
     2 * @file
    33 *
    4  *  @brief Thread-Specific Data Key Create
    5  *  @ingroup POSIXAPI
     4 * @brief Thread-Specific Data Key Create
     5 * @ingroup POSIXAPI
    66 */
    77
    88/*
    9  *  COPYRIGHT (c) 1989-2010.
    10  *  On-Line Applications Research Corporation (OAR).
     9 * COPYRIGHT (c) 1989-2010.
     10 * On-Line Applications Research Corporation (OAR).
    1111 *
    12  *  The license and distribution terms for this file may be
    13  *  found in the file LICENSE in this distribution or at
    14  *  http://www.rtems.com/license/LICENSE.
     12 * The license and distribution terms for this file may be
     13 * found in the file LICENSE in this distribution or at
     14 * http://www.rtems.com/license/LICENSE.
    1515 */
    1616
     
    3838{
    3939  POSIX_Keys_Control  *the_key;
    40   void                *table;
    41   uint32_t             the_api;
    42   uint32_t             bytes_to_allocate;
    43 
    4440
    4541  _Thread_Disable_dispatch();
     
    5349
    5450  the_key->destructor = destructor;
    55 
    56   /*
    57    *  This is a bit more complex than one might initially expect because
    58    *  APIs are optional.
    59    *
    60    *  NOTE: Currently RTEMS Classic API tasks are always enabled.
    61    */
    62   for ( the_api = 1; the_api <= OBJECTS_APIS_LAST; the_api++ ) {
    63     the_key->Values[ the_api ] = NULL;
    64 
    65     #if defined(RTEMS_DEBUG)
    66       /*
    67        *  Since the removal of ITRON, this cannot occur.
    68        */
    69       if ( !_Objects_Information_table[ the_api ] )
    70         continue;
    71 
    72       /*
    73        * Currently all managers are installed if the API is installed.
    74        * This would be a horrible implementation error.
    75        */
    76       if (_Objects_Information_table[ the_api ][ 1 ] == NULL )
    77         _Internal_error_Occurred(
    78           INTERNAL_ERROR_CORE,
    79           true,
    80           INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY
    81         );
    82     #endif
    83 
    84     bytes_to_allocate = sizeof( void * ) *
    85       (_Objects_Information_table[ the_api ][ 1 ]->maximum + 1);
    86     table = _Workspace_Allocate( bytes_to_allocate );
    87     if ( !table ) {
    88       _POSIX_Keys_Free_memory( the_key );
    89 
    90       _POSIX_Keys_Free( the_key );
    91       _Thread_Enable_dispatch();
    92       return ENOMEM;
    93     }
    94 
    95     the_key->Values[ the_api ] = table;
    96     memset( table, '\0', bytes_to_allocate );
    97   }
    98 
    9951  _Objects_Open_u32( &_POSIX_Keys_Information, &the_key->Object, 0 );
    10052  *key = the_key->Object.id;
  • cpukit/posix/src/keydelete.c

    r5a556e4e rb5c9064  
    77
    88/*
    9  *  COPYRIGHT (c) 1989-2007.
    10  *  On-Line Applications Research Corporation (OAR).
     9 * COPYRIGHT (c) 1989-2007.
     10 * On-Line Applications Research Corporation (OAR).
    1111 *
    12  *  The license and distribution terms for this file may be
    13  *  found in the file LICENSE in this distribution or at
    14  *  http://www.rtems.com/license/LICENSE.
     12 * The license and distribution terms for this file may be
     13 * found in the file LICENSE in this distribution or at
     14 * http://www.rtems.com/license/LICENSE.
    1515 */
    1616
     
    4343
    4444    case OBJECTS_LOCAL:
    45       _Objects_Close( &_POSIX_Keys_Information, &the_key->Object );
    46 
    4745      _POSIX_Keys_Free_memory( the_key );
    4846
     
    5250       */
    5351      _POSIX_Keys_Free( the_key );
    54       _Objects_Put( &the_key->Object );
     52      _Objects_Put(&the_key->Object);
    5553      return 0;
    5654
  • cpukit/posix/src/keyfreememory.c

    r5a556e4e rb5c9064  
    22 * @file
    33 *
    4  * @brief POSIX Function Keys Free Memory 
     4 * @brief POSIX Function Keys Free Memory
    55 * @ingroup POSIXAPI
    66 */
    77
    88/*
    9  *  COPYRIGHT (c) 1989-2010.
    10  *  On-Line Applications Research Corporation (OAR).
     9 * Copyright (c) 2012 Zhongwei Yao.
     10 * COPYRIGHT (c) 1989-2010.
     11 * On-Line Applications Research Corporation (OAR).
    1112 *
    12  *  The license and distribution terms for this file may be
    13  *  found in the file LICENSE in this distribution or at
    14  *  http://www.rtems.com/license/LICENSE.
     13 * The license and distribution terms for this file may be
     14 * found in the file LICENSE in this distribution or at
     15 * http://www.rtems.com/license/LICENSE.
    1516 */
    1617
     
    2223#include <rtems/score/thread.h>
    2324#include <rtems/score/wkspace.h>
     25#include <rtems/score/rbtree.h>
    2426#include <rtems/posix/key.h>
    2527
     
    2830)
    2931{
    30   uint32_t            the_api;
     32  POSIX_Keys_Key_value_pair search_node;
     33  POSIX_Keys_Key_value_pair *p;
     34  RBTree_Node *iter, *next;
    3135
    32   for ( the_api = 1; the_api <= OBJECTS_APIS_LAST; the_api++ )
    33     _Workspace_Free( the_key->Values[ the_api ] );
     36  search_node.key = the_key->Object.id;
     37  search_node.thread_id = 0;
     38  iter = _RBTree_Find_unprotected( &_POSIX_Keys_Key_value_lookup_tree, &search_node.Key_value_lookup_node );
     39  if ( !iter )
     40    return;
     41  /**
     42   * find the smallest thread_id node in the rbtree.
     43   */
     44  next = _RBTree_Next_unprotected( iter, RBT_LEFT );
     45  p = _RBTree_Container_of( next, POSIX_Keys_Key_value_pair, Key_value_lookup_node );
     46  while ( p->key == the_key->Object.id) {
     47    iter = next;
     48    next = _RBTree_Next_unprotected( iter, RBT_LEFT );
     49    p = _RBTree_Container_of( next, POSIX_Keys_Key_value_pair, Key_value_lookup_node );
     50  }
     51
     52  /**
     53   * delete all nodes belongs to the_key from the rbtree and chain.
     54   */
     55  p = _RBTree_Container_of( iter, POSIX_Keys_Key_value_pair, Key_value_lookup_node );
     56  while ( p->key == the_key->Object.id ) {
     57    next = _RBTree_Next_unprotected( iter, RBT_RIGHT );
     58    _RBTree_Extract_unprotected( &_POSIX_Keys_Key_value_lookup_tree, iter );
     59    _Chain_Extract_unprotected( &p->Key_values_per_thread_node );
     60    /* append the node to _POSIX_Keys_Keypool */
     61    _Freechain_Put( &_POSIX_Keys_Keypool.super_fc,
     62                    ( void * )p);
     63    iter = next;
     64    p = _RBTree_Container_of( iter, POSIX_Keys_Key_value_pair, Key_value_lookup_node );
     65  }
    3466}
  • cpukit/posix/src/keygetspecific.c

    r5a556e4e rb5c9064  
    77
    88/*
    9  *  COPYRIGHT (c) 1989-2007.
    10  *  On-Line Applications Research Corporation (OAR).
     9 * Copyright (c) 2012 Zhongwei Yao.
     10 * COPYRIGHT (c) 1989-2007.
     11 * On-Line Applications Research Corporation (OAR).
    1112 *
    12  *  The license and distribution terms for this file may be
    13  *  found in the file LICENSE in this distribution or at
    14  *  http://www.rtems.com/license/LICENSE.
     13 * The license and distribution terms for this file may be
     14 * found in the file LICENSE in this distribution or at
     15 * http://www.rtems.com/license/LICENSE.
    1516 */
    1617
     
    2728#include <rtems/score/thread.h>
    2829#include <rtems/score/wkspace.h>
     30#include <rtems/score/rbtree.h>
    2931#include <rtems/posix/key.h>
    3032
     
    3739)
    3840{
    39   register POSIX_Keys_Control *the_key;
    40   uint32_t                     api;
    41   uint32_t                     index;
    4241  Objects_Locations            location;
     42  POSIX_Keys_Key_value_pair    search_node;
     43  RBTree_Node                 *p;
    4344  void                        *key_data;
     45  POSIX_Keys_Key_value_pair   *value_pair_p;
    4446
    45   the_key = _POSIX_Keys_Get( key, &location );
     47  _POSIX_Keys_Get( key, &location );
    4648  switch ( location ) {
    4749
    4850    case OBJECTS_LOCAL:
    49       api      = _Objects_Get_API( _Thread_Executing->Object.id );
    50       index    = _Objects_Get_index( _Thread_Executing->Object.id );
    51       key_data = (void *) the_key->Values[ api ][ index ];
    52       _Objects_Put( &the_key->Object );
     51      search_node.key = key;
     52      search_node.thread_id = _Thread_Executing->Object.id;
     53      p = _RBTree_Find_unprotected( &_POSIX_Keys_Key_value_lookup_tree,
     54                                    &search_node.Key_value_lookup_node );
     55      key_data = NULL;
     56      if ( p ) {
     57        value_pair_p = _RBTree_Container_of( p,
     58                                          POSIX_Keys_Key_value_pair,
     59                                          Key_value_lookup_node );
     60        /* key_data = _RBTree_Container_of( p, */
     61        /*                                  POSIX_Keys_Key_value_pair, */
     62        /*                                  Key_value_lookup_node )->value; */
     63        key_data = value_pair_p->value;
     64      }
     65      _Thread_Enable_dispatch();
    5366      return key_data;
    5467
  • cpukit/posix/src/keyrundestructors.c

    r5a556e4e rb5c9064  
    77
    88/*
    9  *  Copyright (c) 2010 embedded brains GmbH.
     9 * Copyright (c) 2012 Zhongwei Yao.
     10 * Copyright (c) 2010 embedded brains GmbH.
    1011 *
    11  *  COPYRIGHT (c) 1989-2007.
    12  *  On-Line Applications Research Corporation (OAR).
     12 * COPYRIGHT (c) 1989-2007.
     13 * On-Line Applications Research Corporation (OAR).
    1314 *
    14  *  The license and distribution terms for this file may be
    15  *  found in the file LICENSE in this distribution or at
    16  *  http://www.rtems.com/license/LICENSE.
     15 * The license and distribution terms for this file may be
     16 * found in the file LICENSE in this distribution or at
     17 * http://www.rtems.com/license/LICENSE.
    1718 */
    1819
     
    2324#include <rtems/system.h>
    2425#include <rtems/score/thread.h>
     26#include <rtems/score/wkspace.h>
     27#include <rtems/score/chain.h>
    2528#include <rtems/posix/key.h>
     29#include <rtems/posix/threadsup.h>
    2630
    2731/*
     
    3337 *         run through all the keys and do the destructor action.
    3438 */
    35 
    3639void _POSIX_Keys_Run_destructors(
    3740  Thread_Control *thread
    3841)
    3942{
    40   Objects_Maximum thread_index = _Objects_Get_index( thread->Object.id );
    41   Objects_APIs thread_api = _Objects_Get_API( thread->Object.id );
    42   bool done = false;
     43  Chain_Control *chain;
     44  Chain_Node *iter, *next;
     45  void *value;
     46  void (*destructor) (void *);
     47  POSIX_Keys_Control *the_key;
     48  Objects_Locations location;
    4349
    44   /*
    45    *  The standard allows one to avoid a potential infinite loop and limit the
    46    *  number of iterations.  An infinite loop may happen if destructors set
    47    *  thread specific data.  This can be considered dubious.
    48    *
    49    *  Reference: 17.1.1.2 P1003.1c/Draft 10, p. 163, line 99.
    50    */
    51   while ( !done ) {
    52     Objects_Maximum index = 0;
    53     Objects_Maximum max = _POSIX_Keys_Information.maximum;
     50  _Thread_Disable_dispatch();
    5451
    55     done = true;
     52  chain = &(
     53      (POSIX_API_Control *)thread->API_Extensions[ THREAD_API_POSIX ]
     54  )->Key_Chain;
     55  iter = _Chain_First( chain );
     56  while ( !_Chain_Is_tail( chain, iter ) ) {
     57    next = _Chain_Next( iter );
     58    /**
     59     * remove key from rbtree and chain.
     60     * here Chain_Node *iter can be convert to POSIX_Keys_Key_value_pair *,
     61     * because Chain_Node is the first member of POSIX_Keys_Key_value_pair
     62     * structure.
     63     */
     64    _RBTree_Extract_unprotected(
     65        &_POSIX_Keys_Key_value_lookup_tree,
     66        &((POSIX_Keys_Key_value_pair *)iter)->Key_value_lookup_node
     67    );
     68    _Chain_Extract_unprotected( iter );
    5669
    57     for ( index = 1 ; index <= max ; ++index ) {
    58       POSIX_Keys_Control *key = (POSIX_Keys_Control *)
    59         _POSIX_Keys_Information.local_table [ index ];
     70    /**
     71     * run key value's destructor if destructor and value are both non-null.
     72     */
     73    the_key = _POSIX_Keys_Get(
     74        ((POSIX_Keys_Key_value_pair *)iter)->key,
     75        &location
     76    );
     77    destructor = the_key->destructor;
     78    value = ((POSIX_Keys_Key_value_pair *)iter)->value;
     79    if ( destructor != NULL && value != NULL )
     80      (*destructor)( value );
     81    /**
     82     * disable dispatch is nested here
     83     */
     84    _Thread_Enable_dispatch();
    6085
    61       if ( key != NULL && key->destructor != NULL ) {
    62         void *value = key->Values [ thread_api ][ thread_index ];
     86    /**
     87     * put back this node to keypool
     88     */
     89    _Freechain_Put( &_POSIX_Keys_Keypool.super_fc,
     90                    (void *)iter );
    6391
    64         if ( value != NULL ) {
    65           key->Values [ thread_api ][ thread_index ] = NULL;
    66           (*key->destructor)( value );
    67           done = false;
    68         }
    69       }
    70     }
     92    iter = next;
    7193  }
     94  _Thread_Enable_dispatch();
    7295}
  • cpukit/posix/src/keysetspecific.c

    r5a556e4e rb5c9064  
    77
    88/*
    9  *  COPYRIGHT (c) 1989-2007.
    10  *  On-Line Applications Research Corporation (OAR).
     9 * Copyright (c) 2012 Zhongwei Yao.
     10 * COPYRIGHT (c) 1989-2007.
     11 * On-Line Applications Research Corporation (OAR).
    1112 *
    12  *  The license and distribution terms for this file may be
    13  *  found in the file LICENSE in this distribution or at
    14  *  http://www.rtems.com/license/LICENSE.
     13 * The license and distribution terms for this file may be
     14 * found in the file LICENSE in this distribution or at
     15 * http://www.rtems.com/license/LICENSE.
    1516 */
    1617
     
    2324#include <pthread.h>
    2425#include <string.h>
     26#include <stddef.h>
    2527
    2628#include <rtems/system.h>
    2729#include <rtems/score/thread.h>
    2830#include <rtems/score/wkspace.h>
     31#include <rtems/score/rbtree.h>
    2932#include <rtems/posix/key.h>
     33#include <rtems/posix/threadsup.h>
    3034
    3135/*
     
    3842)
    3943{
    40   register POSIX_Keys_Control *the_key;
    41   uint32_t                     api;
    42   uint32_t                     index;
    4344  Objects_Locations            location;
     45  POSIX_Keys_Key_value_pair   *value_pair_ptr;
     46  POSIX_API_Control           *api;
    4447
    45   the_key = _POSIX_Keys_Get( key, &location );
     48  _POSIX_Keys_Get( key, &location );
    4649  switch ( location ) {
    4750
    4851    case OBJECTS_LOCAL:
    49       api   = _Objects_Get_API( _Thread_Executing->Object.id );
    50       index = _Objects_Get_index( _Thread_Executing->Object.id );
    51       the_key->Values[ api ][ index ] = (void *) value;
    52       _Objects_Put( &the_key->Object );
     52      value_pair_ptr = ( POSIX_Keys_Key_value_pair * )
     53        _Freechain_Get( &_POSIX_Keys_Keypool.super_fc );
     54      if ( !value_pair_ptr ) {
     55        _Thread_Enable_dispatch();
     56        return ENOMEM;
     57      }
     58
     59      value_pair_ptr->key = key;
     60      value_pair_ptr->thread_id = _Thread_Executing->Object.id;
     61      value_pair_ptr->value = value;
     62      if ( _RBTree_Insert_unprotected( &_POSIX_Keys_Key_value_lookup_tree,
     63                                       &(value_pair_ptr->Key_value_lookup_node) ) ) {
     64        _Freechain_Put( (Freechain_Control *)&_POSIX_Keys_Keypool,
     65                        (void *) value_pair_ptr );
     66        _Thread_Enable_dispatch();
     67        return EAGAIN;
     68      }
     69
     70      /** append rb_node to the thread API extension's chain */
     71      api = (POSIX_API_Control *)\
     72       (_Thread_Executing->API_Extensions[THREAD_API_POSIX]);
     73      _Chain_Append_unprotected( &api->Key_Chain, &value_pair_ptr->Key_values_per_thread_node );
     74
     75      _Thread_Enable_dispatch();
    5376      return 0;
    5477
  • cpukit/posix/src/pthread.c

    r5a556e4e rb5c9064  
    237237  );
    238238
     239  /** initialize thread's key vaule node chain */
     240  _Chain_Initialize_empty( &api->Key_Chain );
     241
    239242  return true;
    240243}
  • cpukit/sapi/include/confdefs.h

    r5a556e4e rb5c9064  
    17291729  #ifndef CONFIGURE_MAXIMUM_POSIX_KEYS
    17301730    #define CONFIGURE_MAXIMUM_POSIX_KEYS           0
    1731     #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys) 0
    1732   #else
    1733     #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys) \
     1731    #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS      0
     1732    #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys, _key_value_pairs) 0
     1733  #else
     1734    #ifndef CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS
     1735      #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS \
     1736        CONFIGURE_MAXIMUM_POSIX_KEYS \
     1737        * (CONFIGURE_MAXIMUM_POSIX_THREADS + CONFIGURE_MAXIMUM_TASKS)
     1738    #endif
     1739  #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys, _key_value_pairs)       \
    17341740      (_Configure_Object_RAM(_keys, sizeof(POSIX_Keys_Control) ) \
    1735         + (_keys) * 3 * _Configure_From_workspace(sizeof(void *) * 2))
     1741  + _Configure_From_workspace(_key_value_pairs * sizeof(POSIX_Keys_Key_value_pair)))
    17361742  #endif
    17371743
     
    18551861          CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES + \
    18561862          CONFIGURE_MAXIMUM_GO_CHANNELS + CONFIGURE_GO_INIT_CONDITION_VARIABLES) + \
    1857       CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS ) + \
     1863      CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS, \
     1864                                       CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS ) + \
    18581865      CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS( \
    18591866          CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS ) + \
     
    23042311        CONFIGURE_GO_INIT_CONDITION_VARIABLES + CONFIGURE_MAXIMUM_GO_CHANNELS,
    23052312      CONFIGURE_MAXIMUM_POSIX_KEYS,
     2313      CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS,
    23062314      CONFIGURE_MAXIMUM_POSIX_TIMERS,
    23072315      CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS,
     
    25462554      CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES +
    25472555      CONFIGURE_MAXIMUM_GO_CHANNELS + CONFIGURE_GO_INIT_CONDITION_VARIABLES),
    2548     CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS ),
     2556    CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS, \
     2557                                     CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS ),
    25492558    CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS(
    25502559      CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS ),
     
    26172626       (CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES != 0) || \
    26182627       (CONFIGURE_MAXIMUM_POSIX_KEYS != 0) || \
     2628       (CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS != 0) || \
    26192629       (CONFIGURE_MAXIMUM_POSIX_TIMERS != 0) || \
    26202630       (CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS != 0) || \
     
    26982708#endif
    26992709
     2710/*
     2711 * POSIX Key pair shouldn't be less than POSIX Key, which is highly
     2712 * likely to be error.
     2713 */
     2714#if defined(RTEMS_POSIX_API)
     2715    #if (CONFIGURE_MAXIMUM_POSIX_KEYS != 0) && \
     2716      (CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS != 0)
     2717      #if (CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS < \
     2718        CONFIGURE_MAXIMUM_POSIX_KEYS)
     2719      #error "Fewer POSIX Key pairs than POSIX Key!"
     2720      #endif
     2721    #endif
     2722#endif
     2723
    27002724#endif
    27012725/* end of include file */
  • testsuites/psxtests/Makefile.am

    r5a556e4e rb5c9064  
    88    psxalarm01 psxautoinit01 psxautoinit02 psxbarrier01 \
    99    psxcancel psxcancel01 psxclassic01 psxcleanup psxcleanup01 \
    10     psxcond01 psxconfig01 psxenosys psxkey01 psxkey02 psxkey03 \
     10    psxcond01 psxconfig01 psxenosys psxkey01 psxkey02 psxkey03 psxkey04 \
     11    psxkey05 psxkey06 psxkey07 psxkey08 psxkey09 psxkey10 \
    1112    psxitimer psxmsgq01 psxmsgq02 psxmsgq03 psxmsgq04 \
    1213    psxmutexattr01 psxobj01 psxrwlock01 psxsem01 psxsignal01 psxsignal02 \
  • testsuites/psxtests/configure.ac

    r5a556e4e rb5c9064  
    123123psxkey02/Makefile
    124124psxkey03/Makefile
     125psxkey04/Makefile
     126psxkey05/Makefile
     127psxkey06/Makefile
     128psxkey07/Makefile
     129psxkey08/Makefile
     130psxkey09/Makefile
     131psxkey10/Makefile
    125132psxmount/Makefile
    126133psxmsgq01/Makefile
  • testsuites/psxtests/psxkey01/init.c

    r5a556e4e rb5c9064  
    4444  rtems_workspace_greedy_allocate( NULL, 0 );
    4545
    46   puts("Init: pthread_key_create - ENOMEM (Workspace not available)");
     46  puts("Init: pthread_key_create - OK");
    4747  empty_line();
    4848  status = pthread_key_create( &Key_id[0], Key_destructor );
    49   fatal_directive_check_status_only( status, ENOMEM, "no workspace available" );
     49  fatal_directive_check_status_only( status, 0, "OK" );
    5050
    5151  puts( "*** END OF POSIX KEY 01 TEST ***" );
  • testsuites/psxtests/psxkey01/psxkey01.scn

    r5a556e4e rb5c9064  
    11*** POSIX KEY 01 TEST ***
    22Init's ID is 0x0b010001
    3 Allocate_majority_of_workspace:
    4 Init: pthread_key_create - ENOMEM (Workspace not available)
     3Init: pthread_key_create - OK
     4
    55*** END OF POSIX KEY 01 TEST ***
Note: See TracChangeset for help on using the changeset viewer.