File indexing completed on 2025-05-11 08:24:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041
0042 #include <rtems/posix/keyimpl.h>
0043 #include <rtems/score/userextimpl.h>
0044 #include <rtems/score/wkspace.h>
0045 #include <rtems/sysinit.h>
0046
0047 #include <errno.h>
0048
0049
0050
0051
0052 int pthread_key_create(
0053 pthread_key_t *key,
0054 void (*destructor)( void * )
0055 )
0056 {
0057 POSIX_Keys_Control *the_key;
0058
0059 the_key = _POSIX_Keys_Allocate();
0060
0061 if ( !the_key ) {
0062 _Objects_Allocator_unlock();
0063 return EAGAIN;
0064 }
0065
0066 the_key->destructor = destructor;
0067 _Chain_Initialize_empty( &the_key->Key_value_pairs );
0068 _Objects_Open_u32( &_POSIX_Keys_Information, &the_key->Object, 0 );
0069 *key = the_key->Object.id;
0070 _Objects_Allocator_unlock();
0071 return 0;
0072 }
0073
0074 Freechain_Control _POSIX_Keys_Keypool;
0075
0076 static uint32_t _POSIX_Keys_Get_keypool_bump_count( void )
0077 {
0078 uint32_t max;
0079
0080 max = _POSIX_Keys_Key_value_pair_maximum;
0081 return _Objects_Is_unlimited( max ) ?
0082 _Objects_Maximum_per_allocation( max ) : 0;
0083 }
0084
0085 static uint32_t _POSIX_Keys_Get_initial_keypool_size( void )
0086 {
0087 uint32_t max;
0088
0089 max = _POSIX_Keys_Key_value_pair_maximum;
0090 return _Objects_Maximum_per_allocation( max );
0091 }
0092
0093 static void _POSIX_Keys_Initialize_keypool( void )
0094 {
0095 _Freechain_Initialize(
0096 &_POSIX_Keys_Keypool,
0097 _POSIX_Keys_Key_value_pairs,
0098 _POSIX_Keys_Get_initial_keypool_size(),
0099 sizeof( _POSIX_Keys_Key_value_pairs[ 0 ] )
0100 );
0101 }
0102
0103 POSIX_Keys_Key_value_pair * _POSIX_Keys_Key_value_allocate( void )
0104 {
0105 return (POSIX_Keys_Key_value_pair *) _Freechain_Get(
0106 &_POSIX_Keys_Keypool,
0107 _Workspace_Allocate,
0108 _POSIX_Keys_Get_keypool_bump_count(),
0109 sizeof( POSIX_Keys_Key_value_pair )
0110 );
0111 }
0112
0113 static void _POSIX_Keys_Run_destructors( Thread_Control *the_thread )
0114 {
0115 while ( true ) {
0116 ISR_lock_Context lock_context;
0117 RBTree_Node *node;
0118
0119 _Objects_Allocator_lock();
0120 _POSIX_Keys_Key_value_acquire( the_thread, &lock_context );
0121
0122 node = _RBTree_Root( &the_thread->Keys.Key_value_pairs );
0123 if ( node != NULL ) {
0124 POSIX_Keys_Key_value_pair *key_value_pair;
0125 pthread_key_t key;
0126 void *value;
0127 POSIX_Keys_Control *the_key;
0128 void ( *destructor )( void * );
0129
0130 key_value_pair = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( node );
0131 key = key_value_pair->key;
0132 value = key_value_pair->value;
0133 _RBTree_Extract(
0134 &the_thread->Keys.Key_value_pairs,
0135 &key_value_pair->Lookup_node
0136 );
0137
0138 _POSIX_Keys_Key_value_release( the_thread, &lock_context );
0139 _POSIX_Keys_Key_value_free( key_value_pair );
0140
0141 the_key = _POSIX_Keys_Get( key );
0142 _Assert( the_key != NULL );
0143 destructor = the_key->destructor;
0144
0145 _Objects_Allocator_unlock();
0146
0147 if ( destructor != NULL && value != NULL ) {
0148 ( *destructor )( value );
0149 }
0150 } else {
0151 _POSIX_Keys_Key_value_release( the_thread, &lock_context );
0152 _Objects_Allocator_unlock();
0153 break;
0154 }
0155 }
0156 }
0157
0158 static void _POSIX_Keys_Restart_run_destructors(
0159 Thread_Control *executing,
0160 Thread_Control *the_thread
0161 )
0162 {
0163 (void) executing;
0164 _POSIX_Keys_Run_destructors( the_thread );
0165 }
0166
0167 static User_extensions_Control _POSIX_Keys_Extensions = {
0168 .Callouts = {
0169 .thread_restart = _POSIX_Keys_Restart_run_destructors,
0170 .thread_terminate = _POSIX_Keys_Run_destructors
0171 }
0172 };
0173
0174
0175
0176
0177 static void _POSIX_Keys_Manager_initialization(void)
0178 {
0179 _Objects_Initialize_information( &_POSIX_Keys_Information );
0180 _POSIX_Keys_Initialize_keypool();
0181 _User_extensions_Add_API_set( &_POSIX_Keys_Extensions );
0182 }
0183
0184 RTEMS_SYSINIT_ITEM(
0185 _POSIX_Keys_Manager_initialization,
0186 RTEMS_SYSINIT_POSIX_KEYS,
0187 RTEMS_SYSINIT_ORDER_MIDDLE
0188 );