pthread_tls.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * File : pthread_tls.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2010-10-26 Bernard the first version
  23. */
  24. #include <pthread.h>
  25. #include "pthread_internal.h"
  26. _pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX];
  27. void pthread_key_system_init()
  28. {
  29. rt_memset(&_thread_keys[0], 0, sizeof(_thread_keys));
  30. }
  31. void *pthread_getspecific(pthread_key_t key)
  32. {
  33. struct _pthread_data* ptd;
  34. ptd = _pthread_get_data(rt_thread_self());
  35. RT_ASSERT(ptd != NULL);
  36. if (ptd->tls == NULL)
  37. return NULL;
  38. if ((key < PTHREAD_KEY_MAX) && (_thread_keys[key].is_used))
  39. return ptd->tls[key];
  40. return NULL;
  41. }
  42. RTM_EXPORT(pthread_getspecific);
  43. int pthread_setspecific(pthread_key_t key, const void *value)
  44. {
  45. struct _pthread_data* ptd;
  46. ptd = _pthread_get_data(rt_thread_self());
  47. RT_ASSERT(ptd != NULL);
  48. /* check tls area */
  49. if (ptd->tls == NULL)
  50. {
  51. ptd->tls = (void**)rt_malloc(sizeof(void*) * PTHREAD_KEY_MAX);
  52. }
  53. if ((key < PTHREAD_KEY_MAX) && _thread_keys[key].is_used)
  54. {
  55. ptd->tls[key] = (void *)value;
  56. return 0;
  57. }
  58. return EINVAL;
  59. }
  60. RTM_EXPORT(pthread_setspecific);
  61. int pthread_key_create(pthread_key_t *key, void (*destructor)(void*))
  62. {
  63. rt_uint32_t index;
  64. rt_enter_critical();
  65. for (index = 0; index < PTHREAD_KEY_MAX; index ++)
  66. {
  67. if (_thread_keys[index].is_used == 0)
  68. {
  69. _thread_keys[index].is_used = 1;
  70. _thread_keys[index].destructor = destructor;
  71. *key = index;
  72. rt_exit_critical();
  73. return 0;
  74. }
  75. }
  76. rt_exit_critical();
  77. return EAGAIN;
  78. }
  79. RTM_EXPORT(pthread_key_create);
  80. int pthread_key_delete(pthread_key_t key)
  81. {
  82. if (key >= PTHREAD_KEY_MAX)
  83. return EINVAL;
  84. rt_enter_critical();
  85. _thread_keys[key].is_used = 0;
  86. _thread_keys[key].destructor = 0;
  87. rt_exit_critical();
  88. return 0;
  89. }
  90. RTM_EXPORT(pthread_key_delete);