thr0loc.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:5k
- /******************************************************
- The thread local storage
- (c) 1995 Innobase Oy
- Created 10/5/1995 Heikki Tuuri
- *******************************************************/
- #include "thr0loc.h"
- #ifdef UNIV_NONINL
- #include "thr0loc.ic"
- #endif
- #include "sync0sync.h"
- #include "hash0hash.h"
- #include "mem0mem.h"
- /*
- IMPLEMENTATION OF THREAD LOCAL STORAGE
- ======================================
- The threads sometimes need private data which depends on the thread id.
- This is implemented as a hash table, where the hash value is calculated
- from the thread id, to prepare for a large number of threads. The hash table
- is protected by a mutex. If you need modify the program and put new data to
- the thread local storage, just add it to struct thr_local_struct in the
- header file. */
- /* Mutex protecting the local storage hash table */
- mutex_t thr_local_mutex;
- /* The hash table. The module is not yet initialized when it is NULL. */
- hash_table_t* thr_local_hash = NULL;
- /* The private data for each thread should be put to
- the structure below and the accessor functions written
- for the field. */
- typedef struct thr_local_struct thr_local_t;
- struct thr_local_struct{
- os_thread_id_t id; /* id of the thread which owns this struct */
- os_thread_t handle; /* operating system handle to the thread */
- ulint slot_no;/* the index of the slot in the thread table
- for this thread */
- ibool in_ibuf;/* TRUE if the the thread is doing an ibuf
- operation */
- hash_node_t hash; /* hash chain node */
- ulint magic_n;
- };
- #define THR_LOCAL_MAGIC_N 1231234
- /***********************************************************************
- Returns the local storage struct for a thread. */
- static
- thr_local_t*
- thr_local_get(
- /*==========*/
- /* out: local storage */
- os_thread_id_t id) /* in: thread id of the thread */
- {
- thr_local_t* local;
-
- try_again:
- ut_ad(thr_local_hash);
- ut_ad(mutex_own(&thr_local_mutex));
- /* Look for the local struct in the hash table */
- local = NULL;
-
- HASH_SEARCH(hash, thr_local_hash, os_thread_conv_id_to_ulint(id),
- local, local->id == id);
- if (local == NULL) {
- mutex_exit(&thr_local_mutex);
-
- thr_local_create();
-
- mutex_enter(&thr_local_mutex);
- goto try_again;
- }
- ut_ad(local->magic_n == THR_LOCAL_MAGIC_N);
-
- return(local);
- }
- /***********************************************************************
- Gets the slot number in the thread table of a thread. */
- ulint
- thr_local_get_slot_no(
- /*==================*/
- /* out: slot number */
- os_thread_id_t id) /* in: thread id of the thread */
- {
- ulint slot_no;
- thr_local_t* local;
- mutex_enter(&thr_local_mutex);
-
- local = thr_local_get(id);
- slot_no = local->slot_no;
-
- mutex_exit(&thr_local_mutex);
- return(slot_no);
- }
- /***********************************************************************
- Sets the slot number in the thread table of a thread. */
- void
- thr_local_set_slot_no(
- /*==================*/
- os_thread_id_t id, /* in: thread id of the thread */
- ulint slot_no)/* in: slot number */
- {
- thr_local_t* local;
- mutex_enter(&thr_local_mutex);
-
- local = thr_local_get(id);
- local->slot_no = slot_no;
-
- mutex_exit(&thr_local_mutex);
- }
- /***********************************************************************
- Returns pointer to the 'in_ibuf' field within the current thread local
- storage. */
- ibool*
- thr_local_get_in_ibuf_field(void)
- /*=============================*/
- /* out: pointer to the in_ibuf field */
- {
- thr_local_t* local;
- mutex_enter(&thr_local_mutex);
-
- local = thr_local_get(os_thread_get_curr_id());
-
- mutex_exit(&thr_local_mutex);
- return(&(local->in_ibuf));
- }
- /***********************************************************************
- Creates a local storage struct for the calling new thread. */
- void
- thr_local_create(void)
- /*==================*/
- {
- thr_local_t* local;
- if (thr_local_hash == NULL) {
- thr_local_init();
- }
-
- local = mem_alloc(sizeof(thr_local_t));
- local->id = os_thread_get_curr_id();
- local->handle = os_thread_get_curr();
- local->magic_n = THR_LOCAL_MAGIC_N;
- local->in_ibuf = FALSE;
-
- mutex_enter(&thr_local_mutex);
- HASH_INSERT(thr_local_t, hash, thr_local_hash,
- os_thread_conv_id_to_ulint(os_thread_get_curr_id()),
- local);
-
- mutex_exit(&thr_local_mutex);
- }
- /***********************************************************************
- Frees the local storage struct for the specified thread. */
- void
- thr_local_free(
- /*===========*/
- os_thread_id_t id) /* in: thread id */
- {
- thr_local_t* local;
-
- mutex_enter(&thr_local_mutex);
- /* Look for the local struct in the hash table */
- HASH_SEARCH(hash, thr_local_hash, os_thread_conv_id_to_ulint(id),
- local, local->id == id);
- if (local == NULL) {
- mutex_exit(&thr_local_mutex);
- return;
- }
-
- HASH_DELETE(thr_local_t, hash, thr_local_hash,
- os_thread_conv_id_to_ulint(id), local);
- mutex_exit(&thr_local_mutex);
-
- ut_a(local->magic_n == THR_LOCAL_MAGIC_N);
-
- mem_free(local);
- }
- /********************************************************************
- Initializes the thread local storage module. */
- void
- thr_local_init(void)
- /*================*/
- {
- ut_a(thr_local_hash == NULL);
- thr_local_hash = hash_create(OS_THREAD_MAX_N + 100);
- mutex_create(&thr_local_mutex);
- mutex_set_level(&thr_local_mutex, SYNC_ANY_LATCH);
- }