1111#include <zephyr/posix/pthread.h>
1212#include <zephyr/sys/bitarray.h>
1313#include <zephyr/sys/__assert.h>
14+ #include <zephyr/sys/sem.h>
1415
1516struct pthread_key_data {
1617 sys_snode_t node ;
@@ -19,7 +20,7 @@ struct pthread_key_data {
1920
2021LOG_MODULE_REGISTER (pthread_key , CONFIG_PTHREAD_KEY_LOG_LEVEL );
2122
22- static struct k_spinlock pthread_key_lock ;
23+ static SYS_SEM_DEFINE ( pthread_key_lock , 1 , 1 ) ;
2324
2425/* This is non-standard (i.e. an implementation detail) */
2526#define PTHREAD_KEY_INITIALIZER (-1)
@@ -128,42 +129,40 @@ int pthread_key_create(pthread_key_t *key,
128129int pthread_key_delete (pthread_key_t key )
129130{
130131 size_t bit ;
131- __unused int ret ;
132- pthread_key_obj * key_obj ;
132+ int ret = EINVAL ;
133+ pthread_key_obj * key_obj = NULL ;
133134 struct pthread_key_data * key_data ;
134135 sys_snode_t * node_l , * next_node_l ;
135- k_spinlock_key_t key_key ;
136136
137- key_key = k_spin_lock (& pthread_key_lock );
137+ SYS_SEM_LOCK (& pthread_key_lock ) {
138+ key_obj = get_posix_key (key );
139+ if (key_obj == NULL ) {
140+ ret = EINVAL ;
141+ SYS_SEM_LOCK_BREAK ;
142+ }
138143
139- key_obj = get_posix_key (key );
140- if (key_obj == NULL ) {
141- k_spin_unlock (& pthread_key_lock , key_key );
142- return EINVAL ;
143- }
144+ /* Delete thread-specific elements associated with the key */
145+ SYS_SLIST_FOR_EACH_NODE_SAFE (& (key_obj -> key_data_l ), node_l , next_node_l ) {
144146
145- /* Delete thread-specific elements associated with the key */
146- SYS_SLIST_FOR_EACH_NODE_SAFE (& (key_obj -> key_data_l ),
147- node_l , next_node_l ) {
147+ /* Remove the object from the list key_data_l */
148+ key_data = (struct pthread_key_data * )sys_slist_get (& (key_obj -> key_data_l ));
148149
149- /* Remove the object from the list key_data_l */
150- key_data = (struct pthread_key_data * )
151- sys_slist_get (& (key_obj -> key_data_l ));
150+ /* Deallocate the object's memory */
151+ k_free ((void * )key_data );
152+ LOG_DBG ("Freed key data %p for key %x in thread %x" , key_data , key ,
153+ pthread_self ());
154+ }
152155
153- /* Deallocate the object's memory */
154- k_free (( void * ) key_data );
155- LOG_DBG ( "Freed key data %p for key %x in thread %x" , key_data , key , pthread_self () );
156+ bit = posix_key_to_offset ( key_obj );
157+ ret = sys_bitarray_free ( & posix_key_bitarray , 1 , bit );
158+ __ASSERT_NO_MSG ( ret == 0 );
156159 }
157160
158- bit = posix_key_to_offset (key_obj );
159- ret = sys_bitarray_free (& posix_key_bitarray , 1 , bit );
160- __ASSERT_NO_MSG (ret == 0 );
161-
162- k_spin_unlock (& pthread_key_lock , key_key );
163-
164- LOG_DBG ("Deleted key %p (%x)" , key_obj , key );
161+ if (ret == 0 ) {
162+ LOG_DBG ("Deleted key %p (%x)" , key_obj , key );
163+ }
165164
166- return 0 ;
165+ return ret ;
167166}
168167
169168/**
@@ -173,12 +172,10 @@ int pthread_key_delete(pthread_key_t key)
173172 */
174173int pthread_setspecific (pthread_key_t key , const void * value )
175174{
176- pthread_key_obj * key_obj ;
175+ pthread_key_obj * key_obj = NULL ;
177176 struct posix_thread * thread ;
178177 struct pthread_key_data * key_data ;
179- pthread_thread_data * thread_spec_data ;
180- k_spinlock_key_t key_key ;
181- sys_snode_t * node_l ;
178+ sys_snode_t * node_l = NULL ;
182179 int retval = 0 ;
183180
184181 thread = to_posix_thread (pthread_self ());
@@ -190,37 +187,38 @@ int pthread_setspecific(pthread_key_t key, const void *value)
190187 * If the key is already in the list, re-assign its value.
191188 * Else add the key to the thread's list.
192189 */
193- key_key = k_spin_lock (& pthread_key_lock );
194-
195- key_obj = get_posix_key (key );
196- if (key_obj == NULL ) {
197- k_spin_unlock (& pthread_key_lock , key_key );
198- return EINVAL ;
199- }
200-
201- SYS_SLIST_FOR_EACH_NODE (& (thread -> key_list ), node_l ) {
190+ SYS_SEM_LOCK (& pthread_key_lock ) {
191+ key_obj = get_posix_key (key );
192+ if (key_obj == NULL ) {
193+ retval = EINVAL ;
194+ SYS_SEM_LOCK_BREAK ;
195+ }
202196
203- thread_spec_data = (pthread_thread_data * )node_l ;
197+ SYS_SLIST_FOR_EACH_NODE (& (thread -> key_list ), node_l ) {
198+ pthread_thread_data * thread_spec_data = (pthread_thread_data * )node_l ;
204199
205- if (thread_spec_data -> key == key_obj ) {
200+ if (thread_spec_data -> key == key_obj ) {
201+ /* Key is already present so associate thread specific data */
202+ thread_spec_data -> spec_data = (void * )value ;
203+ LOG_DBG ("Paired key %x to value %p for thread %x" , key , value ,
204+ pthread_self ());
205+ break ;
206+ }
207+ }
206208
207- /* Key is already present so
208- * associate thread specific data
209- */
210- thread_spec_data -> spec_data = (void * )value ;
211- LOG_DBG ("Paired key %x to value %p for thread %x" , key , value ,
212- pthread_self ());
213- goto out ;
209+ retval = 0 ;
210+ if (node_l != NULL ) {
211+ /* Key is already present, so we are done */
212+ SYS_SEM_LOCK_BREAK ;
214213 }
215- }
216214
217- if ( node_l == NULL ) {
215+ /* Key and data need to be added */
218216 key_data = k_malloc (sizeof (struct pthread_key_data ));
219217
220218 if (key_data == NULL ) {
221219 LOG_DBG ("Failed to allocate key data for key %x" , key );
222220 retval = ENOMEM ;
223- goto out ;
221+ SYS_SEM_LOCK_BREAK ;
224222 }
225223
226224 LOG_DBG ("Allocated key data %p for key %x in thread %x" , key_data , key ,
@@ -239,9 +237,6 @@ int pthread_setspecific(pthread_key_t key, const void *value)
239237 LOG_DBG ("Paired key %x to value %p for thread %x" , key , value , pthread_self ());
240238 }
241239
242- out :
243- k_spin_unlock (& pthread_key_lock , key_key );
244-
245240 return retval ;
246241}
247242
@@ -257,33 +252,30 @@ void *pthread_getspecific(pthread_key_t key)
257252 pthread_thread_data * thread_spec_data ;
258253 void * value = NULL ;
259254 sys_snode_t * node_l ;
260- k_spinlock_key_t key_key ;
261255
262256 thread = to_posix_thread (pthread_self ());
263257 if (thread == NULL ) {
264258 return NULL ;
265259 }
266260
267- key_key = k_spin_lock (& pthread_key_lock );
268-
269- key_obj = get_posix_key (key );
270- if (key_obj == NULL ) {
271- k_spin_unlock (& pthread_key_lock , key_key );
272- return NULL ;
273- }
261+ SYS_SEM_LOCK (& pthread_key_lock ) {
262+ key_obj = get_posix_key (key );
263+ if (key_obj == NULL ) {
264+ value = NULL ;
265+ SYS_SEM_LOCK_BREAK ;
266+ }
274267
275- /* Traverse the list of keys set by the thread, looking for key */
268+ /* Traverse the list of keys set by the thread, looking for key */
276269
277- SYS_SLIST_FOR_EACH_NODE (& (thread -> key_list ), node_l ) {
278- thread_spec_data = (pthread_thread_data * )node_l ;
279- if (thread_spec_data -> key == key_obj ) {
280- /* Key is present, so get the set thread data */
281- value = thread_spec_data -> spec_data ;
282- break ;
270+ SYS_SLIST_FOR_EACH_NODE (& (thread -> key_list ), node_l ) {
271+ thread_spec_data = (pthread_thread_data * )node_l ;
272+ if (thread_spec_data -> key == key_obj ) {
273+ /* Key is present, so get the set thread data */
274+ value = thread_spec_data -> spec_data ;
275+ break ;
276+ }
283277 }
284278 }
285279
286- k_spin_unlock (& pthread_key_lock , key_key );
287-
288280 return value ;
289281}
0 commit comments