1
0

pthread_tls.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Copyright (c) 2006-2021, 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. #include <pthread.h>
  11. #include "pthread_internal.h"
  12. _pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX];
  13. /* initialize key area */
  14. static int pthread_key_system_init(void)
  15. {
  16. rt_memset(&_thread_keys[0], 0, sizeof(_thread_keys));
  17. return 0;
  18. }
  19. INIT_COMPONENT_EXPORT(pthread_key_system_init);
  20. void *pthread_getspecific(pthread_key_t key)
  21. {
  22. struct _pthread_data* ptd;
  23. if (rt_thread_self() == NULL) return NULL;
  24. /* get pthread data from user data of thread */
  25. ptd = (_pthread_data_t *)rt_thread_self()->pthread_data;
  26. RT_ASSERT(ptd != NULL);
  27. if (ptd->tls == NULL)
  28. return NULL;
  29. if ((key < PTHREAD_KEY_MAX) && (_thread_keys[key].is_used))
  30. return ptd->tls[key];
  31. return NULL;
  32. }
  33. RTM_EXPORT(pthread_getspecific);
  34. int pthread_setspecific(pthread_key_t key, const void *value)
  35. {
  36. struct _pthread_data* ptd;
  37. if (rt_thread_self() == NULL) return EINVAL;
  38. /* get pthread data from user data of thread */
  39. ptd = (_pthread_data_t *)rt_thread_self()->pthread_data;
  40. RT_ASSERT(ptd != NULL);
  41. /* check tls area */
  42. if (ptd->tls == NULL)
  43. {
  44. ptd->tls = (void**)rt_malloc(sizeof(void*) * PTHREAD_KEY_MAX);
  45. }
  46. if ((key < PTHREAD_KEY_MAX) && _thread_keys[key].is_used)
  47. {
  48. ptd->tls[key] = (void *)value;
  49. return 0;
  50. }
  51. return EINVAL;
  52. }
  53. RTM_EXPORT(pthread_setspecific);
  54. int pthread_key_create(pthread_key_t *key, void (*destructor)(void*))
  55. {
  56. rt_uint32_t index;
  57. rt_enter_critical();
  58. for (index = 0; index < PTHREAD_KEY_MAX; index ++)
  59. {
  60. if (_thread_keys[index].is_used == 0)
  61. {
  62. _thread_keys[index].is_used = 1;
  63. _thread_keys[index].destructor = destructor;
  64. *key = index;
  65. rt_exit_critical();
  66. return 0;
  67. }
  68. }
  69. rt_exit_critical();
  70. return EAGAIN;
  71. }
  72. RTM_EXPORT(pthread_key_create);
  73. int pthread_key_delete(pthread_key_t key)
  74. {
  75. if (key >= PTHREAD_KEY_MAX)
  76. return EINVAL;
  77. rt_enter_critical();
  78. _thread_keys[key].is_used = 0;
  79. _thread_keys[key].destructor = 0;
  80. rt_exit_critical();
  81. return 0;
  82. }
  83. RTM_EXPORT(pthread_key_delete);