~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/thr/thr0loc.c

  • Committer: Brian Aker
  • Date: 2009-07-11 19:23:04 UTC
  • mfrom: (1089.1.14 merge)
  • Revision ID: brian@gaz-20090711192304-ootijyl5yf9jq9kd
Merge Brian

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/******************************************************
2
 
The thread local storage
3
 
 
4
 
(c) 1995 Innobase Oy
5
 
 
6
 
Created 10/5/1995 Heikki Tuuri
7
 
*******************************************************/
8
 
 
9
 
#include "thr0loc.h"
10
 
#ifdef UNIV_NONINL
11
 
#include "thr0loc.ic"
12
 
#endif
13
 
 
14
 
#include "sync0sync.h"
15
 
#include "hash0hash.h"
16
 
#include "mem0mem.h"
17
 
#include "srv0srv.h"
18
 
 
19
 
/*
20
 
        IMPLEMENTATION OF THREAD LOCAL STORAGE
21
 
        ======================================
22
 
 
23
 
The threads sometimes need private data which depends on the thread id.
24
 
This is implemented as a hash table, where the hash value is calculated
25
 
from the thread id, to prepare for a large number of threads. The hash table
26
 
is protected by a mutex. If you need modify the program and put new data to
27
 
the thread local storage, just add it to struct thr_local_struct in the
28
 
header file. */
29
 
 
30
 
/* Mutex protecting the local storage hash table */
31
 
mutex_t thr_local_mutex;
32
 
 
33
 
/* The hash table. The module is not yet initialized when it is NULL. */
34
 
hash_table_t*   thr_local_hash  = NULL;
35
 
 
36
 
/* The private data for each thread should be put to
37
 
the structure below and the accessor functions written
38
 
for the field. */
39
 
typedef struct thr_local_struct thr_local_t;
40
 
 
41
 
struct thr_local_struct{
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
45
 
                                for this thread */
46
 
        ibool           in_ibuf;/* TRUE if the the thread is doing an ibuf
47
 
                                operation */
48
 
        hash_node_t     hash;   /* hash chain node */
49
 
        ulint           magic_n;
50
 
};
51
 
 
52
 
#define THR_LOCAL_MAGIC_N       1231234
53
 
 
54
 
/***********************************************************************
55
 
Returns the local storage struct for a thread. */
56
 
static
57
 
thr_local_t*
58
 
thr_local_get(
59
 
/*==========*/
60
 
                                /* out: local storage */
61
 
        os_thread_id_t  id)     /* in: thread id of the thread */
62
 
{
63
 
        thr_local_t*    local;
64
 
 
65
 
try_again:
66
 
        ut_ad(thr_local_hash);
67
 
        ut_ad(mutex_own(&thr_local_mutex));
68
 
 
69
 
        /* Look for the local struct in the hash table */
70
 
 
71
 
        local = NULL;
72
 
 
73
 
        HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
74
 
                    local, os_thread_eq(local->id, id));
75
 
        if (local == NULL) {
76
 
                mutex_exit(&thr_local_mutex);
77
 
 
78
 
                thr_local_create();
79
 
 
80
 
                mutex_enter(&thr_local_mutex);
81
 
 
82
 
                goto try_again;
83
 
        }
84
 
 
85
 
        ut_ad(local->magic_n == THR_LOCAL_MAGIC_N);
86
 
 
87
 
        return(local);
88
 
}
89
 
 
90
 
/***********************************************************************
91
 
Gets the slot number in the thread table of a thread. */
92
 
 
93
 
ulint
94
 
thr_local_get_slot_no(
95
 
/*==================*/
96
 
                                /* out: slot number */
97
 
        os_thread_id_t  id)     /* in: thread id of the thread */
98
 
{
99
 
        ulint           slot_no;
100
 
        thr_local_t*    local;
101
 
 
102
 
        mutex_enter(&thr_local_mutex);
103
 
 
104
 
        local = thr_local_get(id);
105
 
 
106
 
        slot_no = local->slot_no;
107
 
 
108
 
        mutex_exit(&thr_local_mutex);
109
 
 
110
 
        return(slot_no);
111
 
}
112
 
 
113
 
/***********************************************************************
114
 
Sets the slot number in the thread table of a thread. */
115
 
 
116
 
void
117
 
thr_local_set_slot_no(
118
 
/*==================*/
119
 
        os_thread_id_t  id,     /* in: thread id of the thread */
120
 
        ulint           slot_no)/* in: slot number */
121
 
{
122
 
        thr_local_t*    local;
123
 
 
124
 
        mutex_enter(&thr_local_mutex);
125
 
 
126
 
        local = thr_local_get(id);
127
 
 
128
 
        local->slot_no = slot_no;
129
 
 
130
 
        mutex_exit(&thr_local_mutex);
131
 
}
132
 
 
133
 
/***********************************************************************
134
 
Returns pointer to the 'in_ibuf' field within the current thread local
135
 
storage. */
136
 
 
137
 
ibool*
138
 
thr_local_get_in_ibuf_field(void)
139
 
/*=============================*/
140
 
                        /* out: pointer to the in_ibuf field */
141
 
{
142
 
        thr_local_t*    local;
143
 
 
144
 
        mutex_enter(&thr_local_mutex);
145
 
 
146
 
        local = thr_local_get(os_thread_get_curr_id());
147
 
 
148
 
        mutex_exit(&thr_local_mutex);
149
 
 
150
 
        return(&(local->in_ibuf));
151
 
}
152
 
 
153
 
/***********************************************************************
154
 
Creates a local storage struct for the calling new thread. */
155
 
 
156
 
void
157
 
thr_local_create(void)
158
 
/*==================*/
159
 
{
160
 
        thr_local_t*    local;
161
 
 
162
 
        if (thr_local_hash == NULL) {
163
 
                thr_local_init();
164
 
        }
165
 
 
166
 
        local = mem_alloc(sizeof(thr_local_t));
167
 
 
168
 
        local->id = os_thread_get_curr_id();
169
 
        local->handle = os_thread_get_curr();
170
 
        local->magic_n = THR_LOCAL_MAGIC_N;
171
 
 
172
 
        local->in_ibuf = FALSE;
173
 
 
174
 
        mutex_enter(&thr_local_mutex);
175
 
 
176
 
        HASH_INSERT(thr_local_t, hash, thr_local_hash,
177
 
                    os_thread_pf(os_thread_get_curr_id()),
178
 
                    local);
179
 
 
180
 
        mutex_exit(&thr_local_mutex);
181
 
}
182
 
 
183
 
/***********************************************************************
184
 
Frees the local storage struct for the specified thread. */
185
 
 
186
 
void
187
 
thr_local_free(
188
 
/*===========*/
189
 
        os_thread_id_t  id)     /* in: thread id */
190
 
{
191
 
        thr_local_t*    local;
192
 
 
193
 
        mutex_enter(&thr_local_mutex);
194
 
 
195
 
        /* Look for the local struct in the hash table */
196
 
 
197
 
        HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
198
 
                    local, os_thread_eq(local->id, id));
199
 
        if (local == NULL) {
200
 
                mutex_exit(&thr_local_mutex);
201
 
 
202
 
                return;
203
 
        }
204
 
 
205
 
        HASH_DELETE(thr_local_t, hash, thr_local_hash,
206
 
                    os_thread_pf(id), local);
207
 
 
208
 
        mutex_exit(&thr_local_mutex);
209
 
 
210
 
        ut_a(local->magic_n == THR_LOCAL_MAGIC_N);
211
 
 
212
 
        mem_free(local);
213
 
}
214
 
 
215
 
/********************************************************************
216
 
Initializes the thread local storage module. */
217
 
 
218
 
void
219
 
thr_local_init(void)
220
 
/*================*/
221
 
{
222
 
 
223
 
        ut_a(thr_local_hash == NULL);
224
 
 
225
 
        thr_local_hash = hash_create(OS_THREAD_MAX_N + 100);
226
 
 
227
 
        mutex_create(&thr_local_mutex, SYNC_THR_LOCAL);
228
 
}