1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2010-10-26 Bernard the first version 9 */ 10 11 #include <pthread.h> 12 #include "pthread_internal.h" 13 14 _pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX]; 15 pthread_key_system_init()16void pthread_key_system_init() 17 { 18 rt_memset(&_thread_keys[0], 0, sizeof(_thread_keys)); 19 } 20 pthread_getspecific(pthread_key_t key)21void *pthread_getspecific(pthread_key_t key) 22 { 23 struct _pthread_data* ptd; 24 25 ptd = _pthread_get_data(rt_thread_self()); 26 RT_ASSERT(ptd != NULL); 27 28 if (ptd->tls == NULL) 29 return NULL; 30 31 if ((key < PTHREAD_KEY_MAX) && (_thread_keys[key].is_used)) 32 return ptd->tls[key]; 33 34 return NULL; 35 } 36 RTM_EXPORT(pthread_getspecific); 37 pthread_setspecific(pthread_key_t key,const void * value)38int pthread_setspecific(pthread_key_t key, const void *value) 39 { 40 struct _pthread_data* ptd; 41 42 ptd = _pthread_get_data(rt_thread_self()); 43 RT_ASSERT(ptd != NULL); 44 45 /* check tls area */ 46 if (ptd->tls == NULL) 47 { 48 ptd->tls = (void**)rt_malloc(sizeof(void*) * PTHREAD_KEY_MAX); 49 } 50 51 if ((key < PTHREAD_KEY_MAX) && _thread_keys[key].is_used) 52 { 53 ptd->tls[key] = (void *)value; 54 55 return 0; 56 } 57 58 return EINVAL; 59 } 60 RTM_EXPORT(pthread_setspecific); 61 pthread_key_create(pthread_key_t * key,void (* destructor)(void *))62int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)) 63 { 64 rt_uint32_t index; 65 66 rt_enter_critical(); 67 for (index = 0; index < PTHREAD_KEY_MAX; index ++) 68 { 69 if (_thread_keys[index].is_used == 0) 70 { 71 _thread_keys[index].is_used = 1; 72 _thread_keys[index].destructor = destructor; 73 74 *key = index; 75 76 rt_exit_critical(); 77 78 return 0; 79 } 80 } 81 82 rt_exit_critical(); 83 84 return EAGAIN; 85 } 86 RTM_EXPORT(pthread_key_create); 87 pthread_key_delete(pthread_key_t key)88int pthread_key_delete(pthread_key_t key) 89 { 90 if (key >= PTHREAD_KEY_MAX) 91 return EINVAL; 92 93 rt_enter_critical(); 94 _thread_keys[key].is_used = 0; 95 _thread_keys[key].destructor = 0; 96 rt_exit_critical(); 97 98 return 0; 99 } 100 RTM_EXPORT(pthread_key_delete); 101 102