~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/os/os0thread.cc

  • Committer: Mark Atwood
  • Date: 2008-10-03 01:39:40 UTC
  • mto: This revision was merged to the branch mainline in revision 437.
  • Revision ID: mark@fallenpegasus.com-20081003013940-mvefjo725dltz41h
rename logging_noop to logging_query

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (C) 1995, 2010, 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 os/os0thread.c
21
 
The interface to the operating system thread control primitives
22
 
 
23
 
Created 9/8/1995 Heikki Tuuri
24
 
*******************************************************/
25
 
 
26
 
#include "os0thread.h"
27
 
#ifdef UNIV_NONINL
28
 
#include "os0thread.ic"
29
 
#endif
30
 
 
31
 
#ifdef __WIN__
32
 
#include <windows.h>
33
 
#else
34
 
#include <sys/select.h>
35
 
#endif
36
 
 
37
 
#ifndef UNIV_HOTBACKUP
38
 
#include "srv0srv.h"
39
 
#include "os0sync.h"
40
 
 
41
 
/***************************************************************//**
42
 
Compares two thread ids for equality.
43
 
@return TRUE if equal */
44
 
UNIV_INTERN
45
 
ibool
46
 
os_thread_eq(
47
 
/*=========*/
48
 
        os_thread_id_t  a,      /*!< in: OS thread or thread id */
49
 
        os_thread_id_t  b)      /*!< in: OS thread or thread id */
50
 
{
51
 
#ifdef __WIN__
52
 
        if (a == b) {
53
 
                return(TRUE);
54
 
        }
55
 
 
56
 
        return(FALSE);
57
 
#else
58
 
        if (pthread_equal(a, b)) {
59
 
                return(TRUE);
60
 
        }
61
 
 
62
 
        return(FALSE);
63
 
#endif
64
 
}
65
 
 
66
 
/****************************************************************//**
67
 
Converts an OS thread id to a ulint. It is NOT guaranteed that the ulint is
68
 
unique for the thread though!
69
 
@return thread identifier as a number */
70
 
UNIV_INTERN
71
 
ulint
72
 
os_thread_pf(
73
 
/*=========*/
74
 
        os_thread_id_t  a)      /*!< in: OS thread identifier */
75
 
{
76
 
#ifdef UNIV_HPUX10
77
 
        /* In HP-UX-10.20 a pthread_t is a struct of 3 fields: field1, field2,
78
 
        field3. We do not know if field1 determines the thread uniquely. */
79
 
 
80
 
        return((ulint)(a.field1));
81
 
#else
82
 
        return((ulint)a);
83
 
#endif
84
 
}
85
 
 
86
 
/*****************************************************************//**
87
 
Returns the thread identifier of current thread. Currently the thread
88
 
identifier in Unix is the thread handle itself. Note that in HP-UX
89
 
pthread_t is a struct of 3 fields.
90
 
@return current thread identifier */
91
 
UNIV_INTERN
92
 
os_thread_id_t
93
 
os_thread_get_curr_id(void)
94
 
/*=======================*/
95
 
{
96
 
#ifdef __WIN__
97
 
        return(GetCurrentThreadId());
98
 
#else
99
 
        return(pthread_self());
100
 
#endif
101
 
}
102
 
 
103
 
/****************************************************************//**
104
 
Creates a new thread of execution. The execution starts from
105
 
the function given. The start function takes a void* parameter
106
 
and returns an ulint.
107
 
@return handle to the thread */
108
 
UNIV_INTERN
109
 
os_thread_t
110
 
os_thread_create(
111
 
/*=============*/
112
 
#ifndef __WIN__
113
 
        os_posix_f_t            start_f,
114
 
#else
115
 
        ulint (*start_f)(void*),                /*!< in: pointer to function
116
 
                                                from which to start */
117
 
#endif
118
 
        void*                   arg,            /*!< in: argument to start
119
 
                                                function */
120
 
        os_thread_id_t*         thread_id)      /*!< out: id of the created
121
 
                                                thread, or NULL */
122
 
{
123
 
#ifdef __WIN__
124
 
        os_thread_t     thread;
125
 
        DWORD           win_thread_id;
126
 
 
127
 
        os_mutex_enter(os_sync_mutex);
128
 
        os_thread_count++;
129
 
        os_mutex_exit(os_sync_mutex);
130
 
 
131
 
        thread = CreateThread(NULL,     /* no security attributes */
132
 
                              0,        /* default size stack */
133
 
                              (LPTHREAD_START_ROUTINE)start_f,
134
 
                              arg,
135
 
                              0,        /* thread runs immediately */
136
 
                              &win_thread_id);
137
 
 
138
 
        if (thread_id) {
139
 
                *thread_id = win_thread_id;
140
 
        }
141
 
 
142
 
        return(thread);
143
 
#else
144
 
        int             ret;
145
 
        os_thread_t     pthread;
146
 
        pthread_attr_t  attr;
147
 
 
148
 
#ifndef UNIV_HPUX10
149
 
        pthread_attr_init(&attr);
150
 
#endif
151
 
 
152
 
#ifdef UNIV_AIX
153
 
        /* We must make sure a thread stack is at least 32 kB, otherwise
154
 
        InnoDB might crash; we do not know if the default stack size on
155
 
        AIX is always big enough. An empirical test on AIX-4.3 suggested
156
 
        the size was 96 kB, though. */
157
 
 
158
 
        ret = pthread_attr_setstacksize(&attr,
159
 
                                        (size_t)(PTHREAD_STACK_MIN
160
 
                                                 + 32 * 1024));
161
 
        if (ret) {
162
 
                fprintf(stderr,
163
 
                        "InnoDB: Error: pthread_attr_setstacksize"
164
 
                        " returned %d\n", ret);
165
 
                exit(1);
166
 
        }
167
 
#endif
168
 
        os_mutex_enter(os_sync_mutex);
169
 
        os_thread_count++;
170
 
        os_mutex_exit(os_sync_mutex);
171
 
 
172
 
#ifdef UNIV_HPUX10
173
 
        ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
174
 
#else
175
 
        ret = pthread_create(&pthread, &attr, start_f, arg);
176
 
#endif
177
 
        if (ret) {
178
 
                fprintf(stderr,
179
 
                        "InnoDB: Error: pthread_create returned %d\n", ret);
180
 
                exit(1);
181
 
        }
182
 
 
183
 
#ifndef UNIV_HPUX10
184
 
        pthread_attr_destroy(&attr);
185
 
#endif
186
 
 
187
 
        if (thread_id) {
188
 
                *thread_id = pthread;
189
 
        }
190
 
 
191
 
        return(pthread);
192
 
#endif
193
 
}
194
 
 
195
 
/*****************************************************************//**
196
 
Exits the current thread. */
197
 
UNIV_INTERN
198
 
void
199
 
os_thread_exit(
200
 
/*===========*/
201
 
        void*   exit_value)     /*!< in: exit value; in Windows this void*
202
 
                                is cast as a DWORD */
203
 
{
204
 
#ifdef UNIV_DEBUG_THREAD_CREATION
205
 
        fprintf(stderr, "Thread exits, id %lu\n",
206
 
                os_thread_pf(os_thread_get_curr_id()));
207
 
#endif
208
 
 
209
 
#ifdef UNIV_PFS_THREAD
210
 
        pfs_delete_thread();
211
 
#endif
212
 
 
213
 
        os_mutex_enter(os_sync_mutex);
214
 
        os_thread_count--;
215
 
        os_mutex_exit(os_sync_mutex);
216
 
 
217
 
#ifdef __WIN__
218
 
        ExitThread((DWORD)exit_value);
219
 
#else
220
 
        pthread_detach(pthread_self());
221
 
        pthread_exit(exit_value);
222
 
#endif
223
 
}
224
 
 
225
 
/*****************************************************************//**
226
 
Returns handle to the current thread.
227
 
@return current thread handle */
228
 
UNIV_INTERN
229
 
os_thread_t
230
 
os_thread_get_curr(void)
231
 
/*====================*/
232
 
{
233
 
#ifdef __WIN__
234
 
        return(GetCurrentThread());
235
 
#else
236
 
        return(pthread_self());
237
 
#endif
238
 
}
239
 
 
240
 
/*****************************************************************//**
241
 
Advises the os to give up remainder of the thread's time slice. */
242
 
UNIV_INTERN
243
 
void
244
 
os_thread_yield(void)
245
 
/*=================*/
246
 
{
247
 
#if defined(__WIN__)
248
 
        SwitchToThread();
249
 
#elif (defined(HAVE_SCHED_YIELD) && defined(HAVE_SCHED_H))
250
 
        sched_yield();
251
 
#elif defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
252
 
        pthread_yield();
253
 
#elif defined(HAVE_PTHREAD_YIELD_ONE_ARG)
254
 
        pthread_yield(0);
255
 
#else
256
 
        os_thread_sleep(0);
257
 
#endif
258
 
}
259
 
#endif /* !UNIV_HOTBACKUP */
260
 
 
261
 
/*****************************************************************//**
262
 
The thread sleeps at least the time given in microseconds. */
263
 
UNIV_INTERN
264
 
void
265
 
os_thread_sleep(
266
 
/*============*/
267
 
        ulint   tm)     /*!< in: time in microseconds */
268
 
{
269
 
#ifdef __WIN__
270
 
        Sleep((DWORD) tm / 1000);
271
 
#else
272
 
        struct timeval  t;
273
 
 
274
 
        t.tv_sec = tm / 1000000;
275
 
        t.tv_usec = tm % 1000000;
276
 
 
277
 
        select(0, NULL, NULL, NULL, &t);
278
 
#endif
279
 
}
280
 
 
281
 
#ifndef UNIV_HOTBACKUP
282
 
/******************************************************************//**
283
 
Sets a thread priority. */
284
 
UNIV_INTERN
285
 
void
286
 
os_thread_set_priority(
287
 
/*===================*/
288
 
        os_thread_t     handle, /*!< in: OS handle to the thread */
289
 
        ulint           pri)    /*!< in: priority */
290
 
{
291
 
#ifdef __WIN__
292
 
        int     os_pri;
293
 
 
294
 
        if (pri == OS_THREAD_PRIORITY_BACKGROUND) {
295
 
                os_pri = THREAD_PRIORITY_BELOW_NORMAL;
296
 
        } else if (pri == OS_THREAD_PRIORITY_NORMAL) {
297
 
                os_pri = THREAD_PRIORITY_NORMAL;
298
 
        } else if (pri == OS_THREAD_PRIORITY_ABOVE_NORMAL) {
299
 
                os_pri = THREAD_PRIORITY_HIGHEST;
300
 
        } else {
301
 
                ut_error;
302
 
        }
303
 
 
304
 
        ut_a(SetThreadPriority(handle, os_pri));
305
 
#else
306
 
        UT_NOT_USED(handle);
307
 
        UT_NOT_USED(pri);
308
 
#endif
309
 
}
310
 
 
311
 
/******************************************************************//**
312
 
Gets a thread priority.
313
 
@return priority */
314
 
UNIV_INTERN
315
 
ulint
316
 
os_thread_get_priority(
317
 
/*===================*/
318
 
        os_thread_t     /*handle __attribute__((unused))*/)
319
 
                                /*!< in: OS handle to the thread */
320
 
{
321
 
#ifdef __WIN__
322
 
        int     os_pri;
323
 
        ulint   pri;
324
 
 
325
 
        os_pri = GetThreadPriority(handle);
326
 
 
327
 
        if (os_pri == THREAD_PRIORITY_BELOW_NORMAL) {
328
 
                pri = OS_THREAD_PRIORITY_BACKGROUND;
329
 
        } else if (os_pri == THREAD_PRIORITY_NORMAL) {
330
 
                pri = OS_THREAD_PRIORITY_NORMAL;
331
 
        } else if (os_pri == THREAD_PRIORITY_HIGHEST) {
332
 
                pri = OS_THREAD_PRIORITY_ABOVE_NORMAL;
333
 
        } else {
334
 
                ut_error;
335
 
        }
336
 
 
337
 
        return(pri);
338
 
#else
339
 
        return(0);
340
 
#endif
341
 
}
342
 
 
343
 
/******************************************************************//**
344
 
Gets the last operating system error code for the calling thread.
345
 
@return last error on Windows, 0 otherwise */
346
 
UNIV_INTERN
347
 
ulint
348
 
os_thread_get_last_error(void)
349
 
/*==========================*/
350
 
{
351
 
#ifdef __WIN__
352
 
        return(GetLastError());
353
 
#else
354
 
        return(0);
355
 
#endif
356
 
}
357
 
#endif /* !UNIV_HOTBACKUP */