pthread_tls.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include <pthread.h>
  2. #include "pthread_internal.h"
  3. struct _pthread_key_data
  4. {
  5. int is_used;
  6. void* (*destructor)(void* parameter);
  7. };
  8. typedef struct _pthread_key_data _pthread_key_data_t;
  9. static _pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX];
  10. void pthread_key_system_init()
  11. {
  12. rt_memset(&_thread_keys[0], 0, sizeof(_thread_keys));
  13. }
  14. void *pthread_getspecific(pthread_key_t key)
  15. {
  16. struct _pthread_data* ptd;
  17. ptd = _pthread_get_data(rt_thread_self());
  18. RT_ASSERT(ptd != NULL);
  19. if (ptd->tls == NULL) return NULL;
  20. if ((key < PTHREAD_KEY_MAX) && (_thread_keys[key].is_used))
  21. return ptd->tls[key];
  22. return NULL;
  23. }
  24. int pthread_setspecific(pthread_key_t key, const void *value)
  25. {
  26. struct _pthread_data* ptd;
  27. ptd = _pthread_get_data(rt_thread_self());
  28. RT_ASSERT(ptd != NULL);
  29. /* check tls area */
  30. if (ptd->tls == NULL) ptd->tls = rt_malloc(sizeof(void*) * PTHREAD_KEY_MAX);
  31. if ((key < PTHREAD_KEY_MAX) && _thread_keys[key].is_used)
  32. {
  33. ptd->tls[key] = (void *)value;
  34. return 0;
  35. }
  36. return EINVAL;
  37. }
  38. int pthread_key_create(pthread_key_t *key, void (*destructor)(void*))
  39. {
  40. rt_uint32_t index;
  41. rt_enter_critical();
  42. for (index = 0; index < PTHREAD_KEY_MAX; index ++)
  43. {
  44. if (_thread_keys[index].is_used == 0)
  45. {
  46. _thread_keys[index].is_used = 1;
  47. _thread_keys[index].destructor = destructor;
  48. *key = index;
  49. rt_exit_critical();
  50. return 0;
  51. }
  52. }
  53. rt_exit_critical();
  54. return EAGAIN;
  55. }
  56. int pthread_key_delete(pthread_key_t key)
  57. {
  58. if (key >= PTHREAD_KEY_MAX) return EINVAL;
  59. rt_enter_critical();
  60. _thread_keys[key].is_used = 0;
  61. _thread_keys[key].destructor = 0;
  62. rt_exit_critical();
  63. return 0;
  64. }