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