thr0loc.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. The thread local storage
  3. (c) 1995 Innobase Oy
  4. Created 10/5/1995 Heikki Tuuri
  5. *******************************************************/
  6. #include "thr0loc.h"
  7. #ifdef UNIV_NONINL
  8. #include "thr0loc.ic"
  9. #endif
  10. #include "sync0sync.h"
  11. #include "hash0hash.h"
  12. #include "mem0mem.h"
  13. /*
  14. IMPLEMENTATION OF THREAD LOCAL STORAGE
  15. ======================================
  16. The threads sometimes need private data which depends on the thread id.
  17. This is implemented as a hash table, where the hash value is calculated
  18. from the thread id, to prepare for a large number of threads. The hash table
  19. is protected by a mutex. If you need modify the program and put new data to
  20. the thread local storage, just add it to struct thr_local_struct in the
  21. header file. */
  22. /* Mutex protecting the local storage hash table */
  23. mutex_t thr_local_mutex;
  24. /* The hash table. The module is not yet initialized when it is NULL. */
  25. hash_table_t* thr_local_hash = NULL;
  26. /* The private data for each thread should be put to
  27. the structure below and the accessor functions written
  28. for the field. */
  29. typedef struct thr_local_struct thr_local_t;
  30. struct thr_local_struct{
  31. os_thread_id_t id; /* id of the thread which owns this struct */
  32. os_thread_t handle; /* operating system handle to the thread */
  33. ulint slot_no;/* the index of the slot in the thread table
  34. for this thread */
  35. ibool in_ibuf;/* TRUE if the the thread is doing an ibuf
  36. operation */
  37. hash_node_t hash; /* hash chain node */
  38. ulint magic_n;
  39. };
  40. #define THR_LOCAL_MAGIC_N 1231234
  41. /***********************************************************************
  42. Returns the local storage struct for a thread. */
  43. static
  44. thr_local_t*
  45. thr_local_get(
  46. /*==========*/
  47. /* out: local storage */
  48. os_thread_id_t id) /* in: thread id of the thread */
  49. {
  50. thr_local_t* local;
  51. try_again:
  52. ut_ad(thr_local_hash);
  53. ut_ad(mutex_own(&thr_local_mutex));
  54. /* Look for the local struct in the hash table */
  55. local = NULL;
  56. HASH_SEARCH(hash, thr_local_hash, os_thread_conv_id_to_ulint(id),
  57. local, local->id == id);
  58. if (local == NULL) {
  59. mutex_exit(&thr_local_mutex);
  60. thr_local_create();
  61. mutex_enter(&thr_local_mutex);
  62. goto try_again;
  63. }
  64. ut_ad(local->magic_n == THR_LOCAL_MAGIC_N);
  65. return(local);
  66. }
  67. /***********************************************************************
  68. Gets the slot number in the thread table of a thread. */
  69. ulint
  70. thr_local_get_slot_no(
  71. /*==================*/
  72. /* out: slot number */
  73. os_thread_id_t id) /* in: thread id of the thread */
  74. {
  75. ulint slot_no;
  76. thr_local_t* local;
  77. mutex_enter(&thr_local_mutex);
  78. local = thr_local_get(id);
  79. slot_no = local->slot_no;
  80. mutex_exit(&thr_local_mutex);
  81. return(slot_no);
  82. }
  83. /***********************************************************************
  84. Sets the slot number in the thread table of a thread. */
  85. void
  86. thr_local_set_slot_no(
  87. /*==================*/
  88. os_thread_id_t id, /* in: thread id of the thread */
  89. ulint slot_no)/* in: slot number */
  90. {
  91. thr_local_t* local;
  92. mutex_enter(&thr_local_mutex);
  93. local = thr_local_get(id);
  94. local->slot_no = slot_no;
  95. mutex_exit(&thr_local_mutex);
  96. }
  97. /***********************************************************************
  98. Returns pointer to the 'in_ibuf' field within the current thread local
  99. storage. */
  100. ibool*
  101. thr_local_get_in_ibuf_field(void)
  102. /*=============================*/
  103. /* out: pointer to the in_ibuf field */
  104. {
  105. thr_local_t* local;
  106. mutex_enter(&thr_local_mutex);
  107. local = thr_local_get(os_thread_get_curr_id());
  108. mutex_exit(&thr_local_mutex);
  109. return(&(local->in_ibuf));
  110. }
  111. /***********************************************************************
  112. Creates a local storage struct for the calling new thread. */
  113. void
  114. thr_local_create(void)
  115. /*==================*/
  116. {
  117. thr_local_t* local;
  118. if (thr_local_hash == NULL) {
  119. thr_local_init();
  120. }
  121. local = mem_alloc(sizeof(thr_local_t));
  122. local->id = os_thread_get_curr_id();
  123. local->handle = os_thread_get_curr();
  124. local->magic_n = THR_LOCAL_MAGIC_N;
  125.   local->in_ibuf = FALSE;
  126. mutex_enter(&thr_local_mutex);
  127. HASH_INSERT(thr_local_t, hash, thr_local_hash,
  128. os_thread_conv_id_to_ulint(os_thread_get_curr_id()),
  129. local);
  130. mutex_exit(&thr_local_mutex);
  131. }
  132. /***********************************************************************
  133. Frees the local storage struct for the specified thread. */
  134. void
  135. thr_local_free(
  136. /*===========*/
  137. os_thread_id_t id) /* in: thread id */
  138. {
  139. thr_local_t* local;
  140. mutex_enter(&thr_local_mutex);
  141. /* Look for the local struct in the hash table */
  142. HASH_SEARCH(hash, thr_local_hash, os_thread_conv_id_to_ulint(id),
  143. local, local->id == id);
  144. if (local == NULL) {
  145. mutex_exit(&thr_local_mutex);
  146. return;
  147. }
  148. HASH_DELETE(thr_local_t, hash, thr_local_hash,
  149. os_thread_conv_id_to_ulint(id), local);
  150. mutex_exit(&thr_local_mutex);
  151. ut_a(local->magic_n == THR_LOCAL_MAGIC_N);
  152. mem_free(local);
  153. }
  154. /********************************************************************
  155. Initializes the thread local storage module. */
  156. void
  157. thr_local_init(void)
  158. /*================*/
  159. {
  160. ut_a(thr_local_hash == NULL);
  161. thr_local_hash = hash_create(OS_THREAD_MAX_N + 100);
  162. mutex_create(&thr_local_mutex);
  163. mutex_set_level(&thr_local_mutex, SYNC_ANY_LATCH);
  164. }