pthread_tls.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. ptd = _pthread_get_data(rt_thread_self());
  21. RT_ASSERT(ptd != NULL);
  22. if (ptd->tls == NULL)
  23. return NULL;
  24. if ((key < PTHREAD_KEY_MAX) && (_thread_keys[key].is_used))
  25. return ptd->tls[key];
  26. return NULL;
  27. }
  28. RTM_EXPORT(pthread_getspecific);
  29. int pthread_setspecific(pthread_key_t key, const void *value)
  30. {
  31. struct _pthread_data* ptd;
  32. ptd = _pthread_get_data(rt_thread_self());
  33. RT_ASSERT(ptd != NULL);
  34. /* check tls area */
  35. if (ptd->tls == NULL)
  36. {
  37. ptd->tls = (void**)rt_malloc(sizeof(void*) * PTHREAD_KEY_MAX);
  38. }
  39. if ((key < PTHREAD_KEY_MAX) && _thread_keys[key].is_used)
  40. {
  41. ptd->tls[key] = (void *)value;
  42. return 0;
  43. }
  44. return EINVAL;
  45. }
  46. RTM_EXPORT(pthread_setspecific);
  47. int pthread_key_create(pthread_key_t *key, void (*destructor)(void*))
  48. {
  49. rt_uint32_t index;
  50. rt_enter_critical();
  51. for (index = 0; index < PTHREAD_KEY_MAX; index ++)
  52. {
  53. if (_thread_keys[index].is_used == 0)
  54. {
  55. _thread_keys[index].is_used = 1;
  56. _thread_keys[index].destructor = destructor;
  57. *key = index;
  58. rt_exit_critical();
  59. return 0;
  60. }
  61. }
  62. rt_exit_critical();
  63. return EAGAIN;
  64. }
  65. RTM_EXPORT(pthread_key_create);
  66. int pthread_key_delete(pthread_key_t key)
  67. {
  68. if (key >= PTHREAD_KEY_MAX)
  69. return EINVAL;
  70. rt_enter_critical();
  71. _thread_keys[key].is_used = 0;
  72. _thread_keys[key].destructor = 0;
  73. rt_exit_critical();
  74. return 0;
  75. }
  76. RTM_EXPORT(pthread_key_delete);