source: rtems/cpukit/posix/src/key.c @ 390cfcd

4.115
Last change on this file since 390cfcd was 390cfcd, checked in by Sebastian Huber <sebastian.huber@…>, on 08/02/14 at 13:49:26

posix: Simplify key implementation

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief POSIX Keys Manager Initialization
5 * @ingroup POSIX_KEY Key
6 */
7
8/*
9 * Copyright (c) 2012 Zhongwei Yao.
10 * COPYRIGHT (c) 1989-2014.
11 * On-Line Applications Research Corporation (OAR).
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/config.h>
23
24#include <rtems/posix/keyimpl.h>
25#include <rtems/score/chainimpl.h>
26#include <rtems/score/objectimpl.h>
27#include <rtems/score/wkspace.h>
28
29RBTREE_DEFINE_EMPTY( _POSIX_Keys_Key_value_lookup_tree );
30
31/**
32 * @brief This routine compares the rbtree node by comparing POSIX key first
33 * and comparing thread id second.
34 *
35 * if either of the input nodes's thread_id member is 0, then it will only
36 * compare the pthread_key_t member. That is when we pass thread_id = 0 node
37 * as a search node, the search is done only by pthread_key_t.
38 *
39 * @param[in] node1 The node to be compared
40 * @param[in] node2 The node to be compared
41 * @retval positive if first node has higher key than second
42 * @retval negative if lower
43 * @retval 0 if equal,and for all the thread id is unique, then return 0 is
44 * impossible
45 */
46
47RBTree_Compare_result _POSIX_Keys_Key_value_compare(
48  const RBTree_Node *node1,
49  const RBTree_Node *node2
50)
51{
52  POSIX_Keys_Key_value_pair *n1;
53  POSIX_Keys_Key_value_pair *n2;
54  Thread_Control *thread1;
55  Thread_Control *thread2;
56  RBTree_Compare_result diff;
57
58  n1 = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( node1 );
59  n2 = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( node2 );
60
61  diff = n1->key - n2->key;
62  if ( diff )
63    return diff;
64
65  thread1 = n1->thread;
66  thread2 = n2->thread;
67
68  /*
69   * If thread1 or thread2 equals to NULL, only key1 and key2 is valued.  It
70   * enables us search node only by pthread_key_t type key.  Exploit that the
71   * thread control alignment is at least two to avoid integer overflows.
72   */
73  if ( thread1 != NULL && thread2 != NULL )
74    return (RBTree_Compare_result) ( (uintptr_t) thread1 >> 1 )
75      - (RBTree_Compare_result) ( (uintptr_t) thread2 >> 1 );
76
77  return 0;
78}
79
80static uint32_t _POSIX_Keys_Get_keypool_bump_count( void )
81{
82  uint32_t max = Configuration.maximum_key_value_pairs;
83
84  return _Objects_Is_unlimited( max ) ?
85    _Objects_Maximum_per_allocation( max ) : 0;
86}
87
88static uint32_t _POSIX_Keys_Get_initial_keypool_size( void )
89{
90  uint32_t max = Configuration.maximum_key_value_pairs;
91
92  return _Objects_Maximum_per_allocation( max );
93}
94
95static bool _POSIX_Keys_Keypool_extend( Freechain_Control *keypool )
96{
97  size_t bump_count = _POSIX_Keys_Get_keypool_bump_count();
98  bool ok = bump_count > 0;
99
100  if ( ok ) {
101    size_t size = bump_count * sizeof( POSIX_Keys_Key_value_pair );
102    POSIX_Keys_Key_value_pair *nodes = _Workspace_Allocate( size );
103
104    ok = nodes != NULL;
105
106    if ( ok ) {
107      _Chain_Initialize(
108        &keypool->Freechain,
109        nodes,
110        bump_count,
111        sizeof( *nodes )
112      );
113    }
114  }
115
116  return ok;
117}
118
119static void _POSIX_Keys_Initialize_keypool( void )
120{
121  Freechain_Control *keypool = &_POSIX_Keys_Keypool;
122  size_t initial_count = _POSIX_Keys_Get_initial_keypool_size();
123
124  _Freechain_Initialize( keypool, _POSIX_Keys_Keypool_extend );
125
126  if ( initial_count > 0 ) {
127    size_t size = initial_count * sizeof( POSIX_Keys_Key_value_pair );
128    POSIX_Keys_Key_value_pair *nodes =
129      _Workspace_Allocate_or_fatal_error( size );
130
131    _Chain_Initialize(
132      &keypool->Freechain,
133      nodes,
134      initial_count,
135      sizeof( *nodes )
136    );
137  }
138}
139
140/**
141 * @brief This routine performs the initialization necessary for this manager.
142 */
143void _POSIX_Key_Manager_initialization(void)
144{
145  _Objects_Initialize_information(
146    &_POSIX_Keys_Information,   /* object information table */
147    OBJECTS_POSIX_API,          /* object API */
148    OBJECTS_POSIX_KEYS,         /* object class */
149    Configuration.maximum_keys,
150                                /* maximum objects of this class */
151    sizeof( POSIX_Keys_Control ),
152                                /* size of this object's control block */
153    true,                       /* true if names for this object are strings */
154    _POSIX_PATH_MAX             /* maximum length of each object's name */
155#if defined(RTEMS_MULTIPROCESSING)
156    ,
157    false,                      /* true if this is a global object class */
158    NULL                        /* Proxy extraction support callout */
159#endif
160  );
161
162  _POSIX_Keys_Initialize_keypool();
163}
Note: See TracBrowser for help on using the repository browser.