~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Lee Bieber
  • Date: 2010-08-21 22:42:44 UTC
  • mto: (1727.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1728.
  • Revision ID: lbieber@kalebral-2.local-20100821224244-kh3gmsvi45dlbuu1
For the feature request (https://blueprints.launchpad.net/drizzle/+spec/limit-maximum-sort-size) 
that is requesting the ability to cap various buffers, we first tried setting the join buffer to 
1 to see how that would affect the test results and expose test results that need to 
sorted (by adding --sorted_result). 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
 
 
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.
8
 
 
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.
12
 
 
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
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/**************************************************//**
20
 
@file thr/thr0loc.c
21
 
The thread local storage
22
 
 
23
 
Created 10/5/1995 Heikki Tuuri
24
 
*******************************************************/
25
 
 
26
 
#include "thr0loc.h"
27
 
#ifdef UNIV_NONINL
28
 
#include "thr0loc.ic"
29
 
#endif
30
 
 
31
 
#include "sync0sync.h"
32
 
#include "hash0hash.h"
33
 
#include "mem0mem.h"
34
 
#include "srv0srv.h"
35
 
 
36
 
/*
37
 
        IMPLEMENTATION OF THREAD LOCAL STORAGE
38
 
        ======================================
39
 
 
40
 
The threads sometimes need private data which depends on the thread id.
41
 
This is implemented as a hash table, where the hash value is calculated
42
 
from the thread id, to prepare for a large number of threads. The hash table
43
 
is protected by a mutex. If you need modify the program and put new data to
44
 
the thread local storage, just add it to struct thr_local_struct in the
45
 
header file. */
46
 
 
47
 
/** Mutex protecting thr_local_hash */
48
 
static mutex_t          thr_local_mutex;
49
 
 
50
 
/** The hash table. The module is not yet initialized when it is NULL. */
51
 
static hash_table_t*    thr_local_hash  = NULL;
52
 
 
53
 
/** Thread local data */
54
 
typedef struct thr_local_struct thr_local_t;
55
 
 
56
 
#ifdef UNIV_PFS_MUTEX
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 */
60
 
 
61
 
/** @brief Thread local data.
62
 
The private data for each thread should be put to
63
 
the structure below and the accessor functions written
64
 
for the field. */
65
 
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
69
 
                                for this thread */
70
 
        ibool           in_ibuf;/*!< TRUE if the the thread is doing an ibuf
71
 
                                operation */
72
 
        hash_node_t     hash;   /*!< hash chain node */
73
 
        ulint           magic_n;/*!< magic number (THR_LOCAL_MAGIC_N) */
74
 
};
75
 
 
76
 
/** The value of thr_local_struct::magic_n */
77
 
#define THR_LOCAL_MAGIC_N       1231234
78
 
 
79
 
/*******************************************************************//**
80
 
Returns the local storage struct for a thread.
81
 
@return local storage */
82
 
static
83
 
thr_local_t*
84
 
thr_local_get(
85
 
/*==========*/
86
 
        os_thread_id_t  id)     /*!< in: thread id of the thread */
87
 
{
88
 
        thr_local_t*    local;
89
 
 
90
 
try_again:
91
 
        ut_ad(thr_local_hash);
92
 
        ut_ad(mutex_own(&thr_local_mutex));
93
 
 
94
 
        /* Look for the local struct in the hash table */
95
 
 
96
 
        local = NULL;
97
 
 
98
 
        HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
99
 
                    thr_local_t*, local,, os_thread_eq(local->id, id));
100
 
        if (local == NULL) {
101
 
                mutex_exit(&thr_local_mutex);
102
 
 
103
 
                thr_local_create();
104
 
 
105
 
                mutex_enter(&thr_local_mutex);
106
 
 
107
 
                goto try_again;
108
 
        }
109
 
 
110
 
        ut_ad(local->magic_n == THR_LOCAL_MAGIC_N);
111
 
 
112
 
        return(local);
113
 
}
114
 
 
115
 
/*******************************************************************//**
116
 
Gets the slot number in the thread table of a thread.
117
 
@return slot number */
118
 
UNIV_INTERN
119
 
ulint
120
 
thr_local_get_slot_no(
121
 
/*==================*/
122
 
        os_thread_id_t  id)     /*!< in: thread id of the thread */
123
 
{
124
 
        ulint           slot_no;
125
 
        thr_local_t*    local;
126
 
 
127
 
        mutex_enter(&thr_local_mutex);
128
 
 
129
 
        local = thr_local_get(id);
130
 
 
131
 
        slot_no = local->slot_no;
132
 
 
133
 
        mutex_exit(&thr_local_mutex);
134
 
 
135
 
        return(slot_no);
136
 
}
137
 
 
138
 
/*******************************************************************//**
139
 
Sets the slot number in the thread table of a thread. */
140
 
UNIV_INTERN
141
 
void
142
 
thr_local_set_slot_no(
143
 
/*==================*/
144
 
        os_thread_id_t  id,     /*!< in: thread id of the thread */
145
 
        ulint           slot_no)/*!< in: slot number */
146
 
{
147
 
        thr_local_t*    local;
148
 
 
149
 
        mutex_enter(&thr_local_mutex);
150
 
 
151
 
        local = thr_local_get(id);
152
 
 
153
 
        local->slot_no = slot_no;
154
 
 
155
 
        mutex_exit(&thr_local_mutex);
156
 
}
157
 
 
158
 
/*******************************************************************//**
159
 
Returns pointer to the 'in_ibuf' field within the current thread local
160
 
storage.
161
 
@return pointer to the in_ibuf field */
162
 
UNIV_INTERN
163
 
ibool*
164
 
thr_local_get_in_ibuf_field(void)
165
 
/*=============================*/
166
 
{
167
 
        thr_local_t*    local;
168
 
 
169
 
        mutex_enter(&thr_local_mutex);
170
 
 
171
 
        local = thr_local_get(os_thread_get_curr_id());
172
 
 
173
 
        mutex_exit(&thr_local_mutex);
174
 
 
175
 
        return(&(local->in_ibuf));
176
 
}
177
 
 
178
 
/*******************************************************************//**
179
 
Creates a local storage struct for the calling new thread. */
180
 
UNIV_INTERN
181
 
void
182
 
thr_local_create(void)
183
 
/*==================*/
184
 
{
185
 
        thr_local_t*    local;
186
 
 
187
 
        if (thr_local_hash == NULL) {
188
 
                thr_local_init();
189
 
        }
190
 
 
191
 
        local = mem_alloc(sizeof(thr_local_t));
192
 
 
193
 
        local->id = os_thread_get_curr_id();
194
 
        local->handle = os_thread_get_curr();
195
 
        local->magic_n = THR_LOCAL_MAGIC_N;
196
 
 
197
 
        local->in_ibuf = FALSE;
198
 
 
199
 
        mutex_enter(&thr_local_mutex);
200
 
 
201
 
        HASH_INSERT(thr_local_t, hash, thr_local_hash,
202
 
                    os_thread_pf(os_thread_get_curr_id()),
203
 
                    local);
204
 
 
205
 
        mutex_exit(&thr_local_mutex);
206
 
}
207
 
 
208
 
/*******************************************************************//**
209
 
Frees the local storage struct for the specified thread. */
210
 
UNIV_INTERN
211
 
void
212
 
thr_local_free(
213
 
/*===========*/
214
 
        os_thread_id_t  id)     /*!< in: thread id */
215
 
{
216
 
        thr_local_t*    local;
217
 
 
218
 
        mutex_enter(&thr_local_mutex);
219
 
 
220
 
        /* Look for the local struct in the hash table */
221
 
 
222
 
        HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
223
 
                    thr_local_t*, local,, os_thread_eq(local->id, id));
224
 
        if (local == NULL) {
225
 
                mutex_exit(&thr_local_mutex);
226
 
 
227
 
                return;
228
 
        }
229
 
 
230
 
        HASH_DELETE(thr_local_t, hash, thr_local_hash,
231
 
                    os_thread_pf(id), local);
232
 
 
233
 
        mutex_exit(&thr_local_mutex);
234
 
 
235
 
        ut_a(local->magic_n == THR_LOCAL_MAGIC_N);
236
 
 
237
 
        mem_free(local);
238
 
}
239
 
 
240
 
/****************************************************************//**
241
 
Initializes the thread local storage module. */
242
 
UNIV_INTERN
243
 
void
244
 
thr_local_init(void)
245
 
/*================*/
246
 
{
247
 
 
248
 
        ut_a(thr_local_hash == NULL);
249
 
 
250
 
        thr_local_hash = hash_create(OS_THREAD_MAX_N + 100);
251
 
 
252
 
        mutex_create(thr_local_mutex_key,
253
 
                     &thr_local_mutex, SYNC_THR_LOCAL);
254
 
}
255
 
 
256
 
/********************************************************************
257
 
Close the thread local storage module. */
258
 
UNIV_INTERN
259
 
void
260
 
thr_local_close(void)
261
 
/*=================*/
262
 
{
263
 
        ulint           i;
264
 
 
265
 
        ut_a(thr_local_hash != NULL);
266
 
 
267
 
        /* Free the hash elements. We don't remove them from the table
268
 
        because we are going to destroy the table anyway. */
269
 
        for (i = 0; i < hash_get_n_cells(thr_local_hash); i++) {
270
 
                thr_local_t*    local;
271
 
 
272
 
                local = HASH_GET_FIRST(thr_local_hash, i);
273
 
 
274
 
                while (local) {
275
 
                        thr_local_t*    prev_local = local;
276
 
 
277
 
                        local = HASH_GET_NEXT(hash, prev_local);
278
 
                        ut_a(prev_local->magic_n == THR_LOCAL_MAGIC_N);
279
 
                        mem_free(prev_local);
280
 
                }
281
 
        }
282
 
 
283
 
        hash_table_free(thr_local_hash);
284
 
        thr_local_hash = NULL;
285
 
}