pthread_tls.c 2.2 KB

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