source: rtems/cpukit/posix/src/keycreate.c @ 21275b58

Last change on this file since 21275b58 was 21275b58, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 22, 2018 at 6:14:51 PM

score: Static Objects_Information initialization

Statically allocate the objects information together with the initial
set of objects either via <rtems/confdefs.h>. Provide default object
informations with zero objects via librtemscpu.a. This greatly
simplifies the workspace size estimate. RTEMS applications which do not
use the unlimited objects option are easier to debug since all objects
reside now in statically allocated objects of the right types.

Close #3621.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/**
2 * @file
3 *
4 * @brief Thread-Specific Data Key Create
5 * @ingroup POSIXAPI
6 */
7
8/*
9 * COPYRIGHT (c) 1989-2010.
10 * On-Line Applications Research Corporation (OAR).
11 * Copyright (c) 2016 embedded brains GmbH.
12 *
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.org/license/LICENSE.
16 */
17
18#if HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include <rtems/posix/keyimpl.h>
23#include <rtems/score/userextimpl.h>
24#include <rtems/score/wkspace.h>
25#include <rtems/sysinit.h>
26
27#include <errno.h>
28
29/**
30 *  17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
31 */
32int pthread_key_create(
33  pthread_key_t  *key,
34  void          (*destructor)( void * )
35)
36{
37  POSIX_Keys_Control  *the_key;
38
39  the_key = _POSIX_Keys_Allocate();
40
41  if ( !the_key ) {
42    _Objects_Allocator_unlock();
43    return EAGAIN;
44  }
45
46  the_key->destructor = destructor;
47  _Chain_Initialize_empty( &the_key->Key_value_pairs );
48  _Objects_Open_u32( &_POSIX_Keys_Information, &the_key->Object, 0 );
49  *key = the_key->Object.id;
50  _Objects_Allocator_unlock();
51  return 0;
52}
53
54Freechain_Control _POSIX_Keys_Keypool;
55
56static uint32_t _POSIX_Keys_Get_keypool_bump_count( void )
57{
58  uint32_t max;
59
60  max = _POSIX_Keys_Key_value_pair_maximum;
61  return _Objects_Is_unlimited( max ) ?
62    _Objects_Maximum_per_allocation( max ) : 0;
63}
64
65static uint32_t _POSIX_Keys_Get_initial_keypool_size( void )
66{
67  uint32_t max;
68
69  max = _POSIX_Keys_Key_value_pair_maximum;
70  return _Objects_Maximum_per_allocation( max );
71}
72
73static void _POSIX_Keys_Initialize_keypool( void )
74{
75  _Freechain_Initialize(
76    &_POSIX_Keys_Keypool,
77    _POSIX_Keys_Key_value_pairs,
78    _POSIX_Keys_Get_initial_keypool_size(),
79    sizeof( _POSIX_Keys_Key_value_pairs[ 0 ] )
80  );
81}
82
83POSIX_Keys_Key_value_pair * _POSIX_Keys_Key_value_allocate( void )
84{
85  return (POSIX_Keys_Key_value_pair *) _Freechain_Get(
86    &_POSIX_Keys_Keypool,
87    _Workspace_Allocate,
88    _POSIX_Keys_Get_keypool_bump_count(),
89    sizeof( POSIX_Keys_Key_value_pair )
90  );
91}
92
93static void _POSIX_Keys_Run_destructors( Thread_Control *the_thread )
94{
95  while ( true ) {
96    ISR_lock_Context  lock_context;
97    RBTree_Node      *node;
98
99    _Objects_Allocator_lock();
100    _POSIX_Keys_Key_value_acquire( the_thread, &lock_context );
101
102    node = _RBTree_Root( &the_thread->Keys.Key_value_pairs );
103    if ( node != NULL ) {
104      POSIX_Keys_Key_value_pair *key_value_pair;
105      pthread_key_t              key;
106      void                      *value;
107      POSIX_Keys_Control        *the_key;
108      void                    ( *destructor )( void * );
109
110      key_value_pair = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( node );
111      key = key_value_pair->key;
112      value = key_value_pair->value;
113      _RBTree_Extract(
114        &the_thread->Keys.Key_value_pairs,
115        &key_value_pair->Lookup_node
116      );
117
118      _POSIX_Keys_Key_value_release( the_thread, &lock_context );
119      _POSIX_Keys_Key_value_free( key_value_pair );
120
121      the_key = _POSIX_Keys_Get( key );
122      _Assert( the_key != NULL );
123      destructor = the_key->destructor;
124
125      _Objects_Allocator_unlock();
126
127      if ( destructor != NULL && value != NULL ) {
128        ( *destructor )( value );
129      }
130    } else {
131      _POSIX_Keys_Key_value_release( the_thread, &lock_context );
132      _Objects_Allocator_unlock();
133      break;
134    }
135  }
136}
137
138static void _POSIX_Keys_Restart_run_destructors(
139  Thread_Control *executing,
140  Thread_Control *the_thread
141)
142{
143  (void) executing;
144  _POSIX_Keys_Run_destructors( the_thread );
145}
146
147static User_extensions_Control _POSIX_Keys_Extensions = {
148  .Callouts = {
149    .thread_restart = _POSIX_Keys_Restart_run_destructors,
150    .thread_terminate = _POSIX_Keys_Run_destructors
151  }
152};
153
154/**
155 * @brief This routine performs the initialization necessary for this manager.
156 */
157static void _POSIX_Keys_Manager_initialization(void)
158{
159  _Objects_Initialize_information( &_POSIX_Keys_Information );
160  _POSIX_Keys_Initialize_keypool();
161  _User_extensions_Add_API_set( &_POSIX_Keys_Extensions );
162}
163
164RTEMS_SYSINIT_ITEM(
165  _POSIX_Keys_Manager_initialization,
166  RTEMS_SYSINIT_POSIX_KEYS,
167  RTEMS_SYSINIT_ORDER_MIDDLE
168);
Note: See TracBrowser for help on using the repository browser.