source: rtems/cpukit/posix/src/keysetspecific.c @ 9ea69dee

5
Last change on this file since 9ea69dee was 9ea69dee, checked in by Sebastian Huber <sebastian.huber@…>, on 04/04/16 at 06:18:07

score: Add node map to _RBTree_Find_inline()

  • Property mode set to 100644
File size: 3.5 KB
Line 
1/**
2 * @file
3 *
4 * @brief Set Specific Key
5 * @ingroup POSIXAPI
6 */
7
8/*
9 * Copyright (c) 2012 Zhongwei Yao.
10 * COPYRIGHT (c) 1989-2014.
11 * On-Line Applications Research Corporation (OAR).
12 * Copyright (c) 2016 embedded brains GmbH.
13 *
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.org/license/LICENSE.
17 */
18
19#if HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <rtems/posix/keyimpl.h>
24
25#include <errno.h>
26
27static int _POSIX_Keys_Set_value(
28  POSIX_Keys_Key_value_pair *key_value_pair,
29  const void                *value
30)
31{
32  key_value_pair->value = RTEMS_DECONST( void *, value );
33
34  return 0;
35}
36
37static int _POSIX_Keys_Create_value(
38  pthread_key_t       key,
39  const void         *value,
40  Thread_Control     *executing
41)
42{
43  POSIX_Keys_Control *the_key;
44  int                 eno;
45
46  _Objects_Allocator_lock();
47
48  the_key = _POSIX_Keys_Get( key );
49  if ( the_key != NULL ) {
50    POSIX_Keys_Key_value_pair *key_value_pair;
51
52    key_value_pair = _POSIX_Keys_Key_value_allocate();
53    if ( key_value_pair != NULL ) {
54      ISR_lock_Context lock_context;
55
56      key_value_pair->key = key;
57      key_value_pair->thread = executing;
58      key_value_pair->value = RTEMS_DECONST( void *, value );
59
60      _Chain_Append_unprotected(
61        &the_key->Key_value_pairs,
62        &key_value_pair->Key_node
63      );
64
65      _POSIX_Keys_Key_value_acquire( executing, &lock_context );
66      _POSIX_Keys_Key_value_insert( key, key_value_pair, executing );
67      _POSIX_Keys_Key_value_release( executing, &lock_context );
68      eno = 0;
69    } else {
70      eno = ENOMEM;
71    }
72
73  } else {
74    eno = EINVAL;
75  }
76
77  _Objects_Allocator_unlock();
78
79  return eno;
80}
81
82static int _POSIX_Keys_Delete_value(
83  pthread_key_t   key,
84  Thread_Control *executing
85)
86{
87  POSIX_Keys_Control *the_key;
88  int                 eno;
89
90  _Objects_Allocator_lock();
91
92  the_key = _POSIX_Keys_Get( key );
93  if ( the_key != NULL ) {
94    POSIX_Keys_Key_value_pair *key_value_pair;
95    ISR_lock_Context           lock_context;
96
97    _POSIX_Keys_Key_value_acquire( executing, &lock_context );
98
99    key_value_pair = _POSIX_Keys_Key_value_find( key, executing );
100    if ( key_value_pair != NULL ) {
101      _RBTree_Extract(
102        &executing->Keys.Key_value_pairs,
103        &key_value_pair->Lookup_node
104      );
105
106      _POSIX_Keys_Key_value_release( executing, &lock_context );
107
108      _POSIX_Keys_Key_value_free( key_value_pair );
109    } else {
110      _POSIX_Keys_Key_value_release( executing, &lock_context );
111    }
112
113    eno = 0;
114  } else {
115    eno = EINVAL;
116  }
117
118  _Objects_Allocator_unlock();
119
120  return eno;
121}
122
123/*
124 *  17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
125 */
126
127int pthread_setspecific(
128  pthread_key_t  key,
129  const void    *value
130)
131{
132  Thread_Control   *executing;
133  int               eno;
134
135  executing = _Thread_Get_executing();
136
137  if ( value != NULL ) {
138    ISR_lock_Context           lock_context;
139    POSIX_Keys_Key_value_pair *key_value_pair;
140
141    _POSIX_Keys_Key_value_acquire( executing, &lock_context );
142
143    key_value_pair = _POSIX_Keys_Key_value_find( key, executing );
144    if ( key_value_pair != NULL ) {
145      eno = _POSIX_Keys_Set_value( key_value_pair, value );
146      _POSIX_Keys_Key_value_release( executing, &lock_context );
147    } else {
148      _POSIX_Keys_Key_value_release( executing, &lock_context );
149      eno = _POSIX_Keys_Create_value( key, value, executing );
150    }
151  } else {
152    eno = _POSIX_Keys_Delete_value( key, executing );
153  }
154
155  return eno;
156}
Note: See TracBrowser for help on using the repository browser.