1
/*****************************************************************************
3
Copyright (C) 1995, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
1
/******************************************************
21
2
The thread local storage
23
6
Created 10/5/1995 Heikki Tuuri
24
7
*******************************************************/
44
27
the thread local storage, just add it to struct thr_local_struct in the
47
/** Mutex protecting thr_local_hash */
30
/* Mutex protecting the local storage hash table */
48
31
static mutex_t thr_local_mutex;
50
/** The hash table. The module is not yet initialized when it is NULL. */
33
/* The hash table. The module is not yet initialized when it is NULL. */
51
34
static hash_table_t* thr_local_hash = NULL;
53
/** Thread local data */
54
typedef struct thr_local_struct thr_local_t;
57
/* Key to register the mutex with performance schema */
58
UNIV_INTERN mysql_pfs_key_t thr_local_mutex_key;
59
#endif /* UNIV_PFS_MUTEX */
61
/** @brief Thread local data.
62
The private data for each thread should be put to
36
/* The private data for each thread should be put to
63
37
the structure below and the accessor functions written
39
typedef struct thr_local_struct thr_local_t;
65
41
struct thr_local_struct{
66
os_thread_id_t id; /*!< id of the thread which owns this struct */
67
os_thread_t handle; /*!< operating system handle to the thread */
68
ulint slot_no;/*!< the index of the slot in the thread table
42
os_thread_id_t id; /* id of the thread which owns this struct */
43
os_thread_t handle; /* operating system handle to the thread */
44
ulint slot_no;/* the index of the slot in the thread table
70
ibool in_ibuf;/*!< TRUE if the the thread is doing an ibuf
46
ibool in_ibuf;/* TRUE if the the thread is doing an ibuf
72
hash_node_t hash; /*!< hash chain node */
73
ulint magic_n;/*!< magic number (THR_LOCAL_MAGIC_N) */
48
hash_node_t hash; /* hash chain node */
76
/** The value of thr_local_struct::magic_n */
77
52
#define THR_LOCAL_MAGIC_N 1231234
80
/*******************************************************************//**
81
Validates thread local data.
82
@return TRUE if valid */
87
const thr_local_t* local) /*!< in: data to validate */
89
ut_ad(local->magic_n == THR_LOCAL_MAGIC_N);
90
ut_ad(local->slot_no == ULINT_UNDEFINED
91
|| local->slot_no < OS_THREAD_MAX_N);
92
ut_ad(local->in_ibuf == FALSE || local->in_ibuf == TRUE);
95
#endif /* UNIV_DEBUG */
97
/*******************************************************************//**
98
Returns the local storage struct for a thread.
99
@return local storage */
54
/***********************************************************************
55
Returns the local storage struct for a thread. */
104
os_thread_id_t id) /*!< in: thread id of the thread */
60
/* out: local storage */
61
os_thread_id_t id) /* in: thread id of the thread */
106
63
thr_local_t* local;
116
73
HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
117
thr_local_t*, local, ut_ad(thr_local_validate(local)),
118
os_thread_eq(local->id, id));
74
thr_local_t*, local, os_thread_eq(local->id, id));
119
75
if (local == NULL) {
120
76
mutex_exit(&thr_local_mutex);
129
ut_ad(thr_local_validate(local));
85
ut_ad(local->magic_n == THR_LOCAL_MAGIC_N);
134
/*******************************************************************//**
135
Gets the slot number in the thread table of a thread.
136
@return slot number */
90
/***********************************************************************
91
Gets the slot number in the thread table of a thread. */
139
94
thr_local_get_slot_no(
140
95
/*==================*/
141
os_thread_id_t id) /*!< in: thread id of the thread */
96
/* out: slot number */
97
os_thread_id_t id) /* in: thread id of the thread */
144
100
thr_local_t* local;
157
/*******************************************************************//**
113
/***********************************************************************
158
114
Sets the slot number in the thread table of a thread. */
161
117
thr_local_set_slot_no(
162
118
/*==================*/
163
os_thread_id_t id, /*!< in: thread id of the thread */
164
ulint slot_no)/*!< in: slot number */
119
os_thread_id_t id, /* in: thread id of the thread */
120
ulint slot_no)/* in: slot number */
166
122
thr_local_t* local;
174
130
mutex_exit(&thr_local_mutex);
177
/*******************************************************************//**
133
/***********************************************************************
178
134
Returns pointer to the 'in_ibuf' field within the current thread local
180
@return pointer to the in_ibuf field */
183
138
thr_local_get_in_ibuf_field(void)
184
139
/*=============================*/
140
/* out: pointer to the in_ibuf field */
186
142
thr_local_t* local;
207
163
thr_local_init();
210
local = static_cast<thr_local_t *>(mem_alloc(sizeof(thr_local_t)));
166
local = mem_alloc(sizeof(thr_local_t));
212
168
local->id = os_thread_get_curr_id();
213
169
local->handle = os_thread_get_curr();
214
170
local->magic_n = THR_LOCAL_MAGIC_N;
215
local->slot_no = ULINT_UNDEFINED;
216
172
local->in_ibuf = FALSE;
218
174
mutex_enter(&thr_local_mutex);
224
180
mutex_exit(&thr_local_mutex);
227
/*******************************************************************//**
183
/***********************************************************************
228
184
Frees the local storage struct for the specified thread. */
233
os_thread_id_t id) /*!< in: thread id */
189
os_thread_id_t id) /* in: thread id */
235
191
thr_local_t* local;
239
195
/* Look for the local struct in the hash table */
241
197
HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
242
thr_local_t*, local, ut_ad(thr_local_validate(local)),
243
os_thread_eq(local->id, id));
198
thr_local_t*, local, os_thread_eq(local->id, id));
244
199
if (local == NULL) {
245
200
mutex_exit(&thr_local_mutex);
253
208
mutex_exit(&thr_local_mutex);
255
210
ut_a(local->magic_n == THR_LOCAL_MAGIC_N);
256
ut_ad(thr_local_validate(local));
261
/****************************************************************//**
215
/********************************************************************
262
216
Initializes the thread local storage module. */
271
225
thr_local_hash = hash_create(OS_THREAD_MAX_N + 100);
273
mutex_create(thr_local_mutex_key,
274
&thr_local_mutex, SYNC_THR_LOCAL);
277
/********************************************************************
278
Close the thread local storage module. */
281
thr_local_close(void)
282
/*=================*/
286
ut_a(thr_local_hash != NULL);
288
/* Free the hash elements. We don't remove them from the table
289
because we are going to destroy the table anyway. */
290
for (i = 0; i < hash_get_n_cells(thr_local_hash); i++) {
293
local = static_cast<thr_local_t *>(HASH_GET_FIRST(thr_local_hash, i));
296
thr_local_t* prev_local = local;
298
local = static_cast<thr_local_t *>(HASH_GET_NEXT(hash, prev_local));
299
ut_a(prev_local->magic_n == THR_LOCAL_MAGIC_N);
300
ut_ad(thr_local_validate(prev_local));
301
mem_free(prev_local);
305
hash_table_free(thr_local_hash);
306
thr_local_hash = NULL;
227
mutex_create(&thr_local_mutex, SYNC_THR_LOCAL);