source: rtems/cpukit/posix/src/key.c @ b5c9064

4.115
Last change on this file since b5c9064 was b5c9064, checked in by Zhongwei Yao <ashi08104@…>, on Aug 5, 2013 at 1:20:45 PM

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.

  • Property mode set to 100644
File size: 4.9 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-2008.
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.com/license/LICENSE.
16 */
17
18#if HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include <errno.h>
23#include <limits.h>
24#include <pthread.h>
25#include <string.h>
26#include <limits.h>
27
28#include <rtems/system.h>
29#include <rtems/config.h>
30#include <rtems/score/thread.h>
31#include <rtems/score/wkspace.h>
32#include <rtems/posix/key.h>
33#include <rtems/score/rbtree.h>
34#include <rtems/score/chain.h>
35#include <rtems/score/freechain.h>
36
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.
44 *
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.
48 *
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
55 */
56
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 */
142void _POSIX_Key_Manager_initialization(void)
143{
144  _Objects_Initialize_information(
145    &_POSIX_Keys_Information,   /* object information table */
146    OBJECTS_POSIX_API,          /* object API */
147    OBJECTS_POSIX_KEYS,         /* object class */
148    Configuration_POSIX_API.maximum_keys,
149                                /* maximum objects of this class */
150    sizeof( POSIX_Keys_Control ),
151                                /* size of this object's control block */
152    true,                       /* true if names for this object are strings */
153    _POSIX_PATH_MAX             /* maximum length of each object's name */
154#if defined(RTEMS_MULTIPROCESSING)
155    ,
156    false,                      /* true if this is a global object class */
157    NULL                        /* Proxy extraction support callout */
158#endif
159  );
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();
168}
Note: See TracBrowser for help on using the repository browser.