source: rtems/cpukit/posix/src/keysetspecific.c @ 77fbbd6

5
Last change on this file since 77fbbd6 was aaaf9610, checked in by Sebastian Huber <sebastian.huber@…>, on 08/08/16 at 06:44:51

score: Add debug support to red-black trees

This helps to detect double insert and extract errors.

  • Property mode set to 100644
File size: 3.6 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      _RBTree_Initialize_node( &key_value_pair->Lookup_node );
61
62      _Chain_Initialize_node( &key_value_pair->Key_node );
63      _Chain_Append_unprotected(
64        &the_key->Key_value_pairs,
65        &key_value_pair->Key_node
66      );
67
68      _POSIX_Keys_Key_value_acquire( executing, &lock_context );
69      _POSIX_Keys_Key_value_insert( key, key_value_pair, executing );
70      _POSIX_Keys_Key_value_release( executing, &lock_context );
71      eno = 0;
72    } else {
73      eno = ENOMEM;
74    }
75
76  } else {
77    eno = EINVAL;
78  }
79
80  _Objects_Allocator_unlock();
81
82  return eno;
83}
84
85static int _POSIX_Keys_Delete_value(
86  pthread_key_t   key,
87  Thread_Control *executing
88)
89{
90  POSIX_Keys_Control *the_key;
91  int                 eno;
92
93  _Objects_Allocator_lock();
94
95  the_key = _POSIX_Keys_Get( key );
96  if ( the_key != NULL ) {
97    POSIX_Keys_Key_value_pair *key_value_pair;
98    ISR_lock_Context           lock_context;
99
100    _POSIX_Keys_Key_value_acquire( executing, &lock_context );
101
102    key_value_pair = _POSIX_Keys_Key_value_find( key, executing );
103    if ( key_value_pair != NULL ) {
104      _RBTree_Extract(
105        &executing->Keys.Key_value_pairs,
106        &key_value_pair->Lookup_node
107      );
108
109      _POSIX_Keys_Key_value_release( executing, &lock_context );
110
111      _POSIX_Keys_Key_value_free( key_value_pair );
112    } else {
113      _POSIX_Keys_Key_value_release( executing, &lock_context );
114    }
115
116    eno = 0;
117  } else {
118    eno = EINVAL;
119  }
120
121  _Objects_Allocator_unlock();
122
123  return eno;
124}
125
126/*
127 *  17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
128 */
129
130int pthread_setspecific(
131  pthread_key_t  key,
132  const void    *value
133)
134{
135  Thread_Control   *executing;
136  int               eno;
137
138  executing = _Thread_Get_executing();
139
140  if ( value != NULL ) {
141    ISR_lock_Context           lock_context;
142    POSIX_Keys_Key_value_pair *key_value_pair;
143
144    _POSIX_Keys_Key_value_acquire( executing, &lock_context );
145
146    key_value_pair = _POSIX_Keys_Key_value_find( key, executing );
147    if ( key_value_pair != NULL ) {
148      eno = _POSIX_Keys_Set_value( key_value_pair, value );
149      _POSIX_Keys_Key_value_release( executing, &lock_context );
150    } else {
151      _POSIX_Keys_Key_value_release( executing, &lock_context );
152      eno = _POSIX_Keys_Create_value( key, value, executing );
153    }
154  } else {
155    eno = _POSIX_Keys_Delete_value( key, executing );
156  }
157
158  return eno;
159}
Note: See TracBrowser for help on using the repository browser.