~drizzle-trunk/drizzle/development

641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
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., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 USA
16
17
*****************************************************************************/
18
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
19
/**************************************************//**
20
@file os/os0thread.c
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
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>
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
33
#else
34
#include <sys/select.h>
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
35
#endif
36
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
37
#ifndef UNIV_HOTBACKUP
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
38
#include "srv0srv.h"
39
#include "os0sync.h"
40
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
41
/***************************************************************//**
42
Compares two thread ids for equality.
43
@return	TRUE if equal */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
44
UNIV_INTERN
45
ibool
46
os_thread_eq(
47
/*=========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
48
	os_thread_id_t	a,	/*!< in: OS thread or thread id */
49
	os_thread_id_t	b)	/*!< in: OS thread or thread id */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
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
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
66
/****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
67
Converts an OS thread id to a ulint. It is NOT guaranteed that the ulint is
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
68
unique for the thread though!
69
@return	thread identifier as a number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
70
UNIV_INTERN
71
ulint
72
os_thread_pf(
73
/*=========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
74
	os_thread_id_t	a)	/*!< in: OS thread identifier */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
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
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
86
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
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
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
89
pthread_t is a struct of 3 fields.
90
@return	current thread identifier */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
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
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
103
/****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
104
Creates a new thread of execution. The execution starts from
105
the function given. The start function takes a void* parameter
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
106
and returns an ulint.
107
@return	handle to the thread */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
108
UNIV_INTERN
109
os_thread_t
110
os_thread_create(
111
/*=============*/
112
#ifndef __WIN__
113
	os_posix_f_t		start_f,
114
#else
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
115
	ulint (*start_f)(void*),		/*!< in: pointer to function
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
116
						from which to start */
117
#endif
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
118
	void*			arg,		/*!< in: argument to start
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
119
						function */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
120
	os_thread_id_t*		thread_id)	/*!< out: id of the created
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
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 (srv_set_thread_priorities) {
139
140
		/* Set created thread priority the same as a normal query
141
		in MYSQL: we try to prevent starvation of threads by
142
		assigning same priority QUERY_PRIOR to all */
143
144
		ut_a(SetThreadPriority(thread, srv_query_thread_priority));
145
	}
146
147
	if (thread_id) {
148
		*thread_id = win_thread_id;
149
	}
150
151
	return(thread);
152
#else
153
	int		ret;
154
	os_thread_t	pthread;
155
	pthread_attr_t	attr;
156
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
157
#ifndef UNIV_HPUX10
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
158
	pthread_attr_init(&attr);
159
#endif
160
161
#ifdef UNIV_AIX
162
	/* We must make sure a thread stack is at least 32 kB, otherwise
163
	InnoDB might crash; we do not know if the default stack size on
164
	AIX is always big enough. An empirical test on AIX-4.3 suggested
165
	the size was 96 kB, though. */
166
167
	ret = pthread_attr_setstacksize(&attr,
168
					(size_t)(PTHREAD_STACK_MIN
169
						 + 32 * 1024));
170
	if (ret) {
171
		fprintf(stderr,
172
			"InnoDB: Error: pthread_attr_setstacksize"
173
			" returned %d\n", ret);
174
		exit(1);
175
	}
176
#endif
177
#ifdef __NETWARE__
178
	ret = pthread_attr_setstacksize(&attr,
179
					(size_t) NW_THD_STACKSIZE);
180
	if (ret) {
181
		fprintf(stderr,
182
			"InnoDB: Error: pthread_attr_setstacksize"
183
			" returned %d\n", ret);
184
		exit(1);
185
	}
186
#endif
187
	os_mutex_enter(os_sync_mutex);
188
	os_thread_count++;
189
	os_mutex_exit(os_sync_mutex);
190
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
191
#ifdef UNIV_HPUX10
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
192
	ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
193
#else
194
	ret = pthread_create(&pthread, &attr, start_f, arg);
195
#endif
196
	if (ret) {
197
		fprintf(stderr,
198
			"InnoDB: Error: pthread_create returned %d\n", ret);
199
		exit(1);
200
	}
201
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
202
#ifndef UNIV_HPUX10
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
203
	pthread_attr_destroy(&attr);
204
#endif
205
	if (srv_set_thread_priorities) {
206
641.1.4 by Monty Taylor
Merged in InnoDB changes.
207
                  struct sched_param tmp_sched_param;
208
209
                  memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
210
                  tmp_sched_param.sched_priority= srv_query_thread_priority;
211
                  (void)pthread_setschedparam(pthread, SCHED_OTHER, &tmp_sched_param);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
212
	}
213
214
	if (thread_id) {
215
		*thread_id = pthread;
216
	}
217
218
	return(pthread);
219
#endif
220
}
221
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
222
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
223
Exits the current thread. */
224
UNIV_INTERN
225
void
226
os_thread_exit(
227
/*===========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
228
	void*	exit_value)	/*!< in: exit value; in Windows this void*
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
229
				is cast as a DWORD */
230
{
231
#ifdef UNIV_DEBUG_THREAD_CREATION
232
	fprintf(stderr, "Thread exits, id %lu\n",
233
		os_thread_pf(os_thread_get_curr_id()));
234
#endif
235
	os_mutex_enter(os_sync_mutex);
236
	os_thread_count--;
237
	os_mutex_exit(os_sync_mutex);
238
239
#ifdef __WIN__
240
	ExitThread((DWORD)exit_value);
241
#else
242
	pthread_exit(exit_value);
243
#endif
244
}
245
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
246
/*****************************************************************//**
247
Returns handle to the current thread.
248
@return	current thread handle */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
249
UNIV_INTERN
250
os_thread_t
251
os_thread_get_curr(void)
252
/*====================*/
253
{
254
#ifdef __WIN__
255
	return(GetCurrentThread());
256
#else
257
	return(pthread_self());
258
#endif
259
}
260
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
261
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
262
Advises the os to give up remainder of the thread's time slice. */
263
UNIV_INTERN
264
void
265
os_thread_yield(void)
266
/*=================*/
267
{
268
#if defined(__WIN__)
269
	Sleep(0);
270
#elif (defined(HAVE_SCHED_YIELD) && defined(HAVE_SCHED_H))
271
	sched_yield();
272
#elif defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
273
	pthread_yield();
274
#elif defined(HAVE_PTHREAD_YIELD_ONE_ARG)
275
	pthread_yield(0);
276
#else
277
	os_thread_sleep(0);
278
#endif
279
}
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
280
#endif /* !UNIV_HOTBACKUP */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
281
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
282
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
283
The thread sleeps at least the time given in microseconds. */
284
UNIV_INTERN
285
void
286
os_thread_sleep(
287
/*============*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
288
	ulint	tm)	/*!< in: time in microseconds */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
289
{
290
#ifdef __WIN__
291
	Sleep((DWORD) tm / 1000);
292
#elif defined(__NETWARE__)
293
	delay(tm / 1000);
294
#else
295
	struct timeval	t;
296
297
	t.tv_sec = tm / 1000000;
298
	t.tv_usec = tm % 1000000;
299
300
	select(0, NULL, NULL, NULL, &t);
301
#endif
302
}
303
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
304
#ifndef UNIV_HOTBACKUP
305
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
306
Sets a thread priority. */
307
UNIV_INTERN
308
void
309
os_thread_set_priority(
310
/*===================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
311
	os_thread_t	handle,	/*!< in: OS handle to the thread */
312
	ulint		pri)	/*!< in: priority */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
313
{
314
#ifdef __WIN__
315
	int	os_pri;
316
317
	if (pri == OS_THREAD_PRIORITY_BACKGROUND) {
318
		os_pri = THREAD_PRIORITY_BELOW_NORMAL;
319
	} else if (pri == OS_THREAD_PRIORITY_NORMAL) {
320
		os_pri = THREAD_PRIORITY_NORMAL;
321
	} else if (pri == OS_THREAD_PRIORITY_ABOVE_NORMAL) {
322
		os_pri = THREAD_PRIORITY_HIGHEST;
323
	} else {
324
		ut_error;
325
	}
326
327
	ut_a(SetThreadPriority(handle, os_pri));
328
#else
329
	UT_NOT_USED(handle);
330
	UT_NOT_USED(pri);
331
#endif
332
}
333
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
334
/******************************************************************//**
335
Gets a thread priority.
336
@return	priority */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
337
UNIV_INTERN
338
ulint
339
os_thread_get_priority(
340
/*===================*/
341
	os_thread_t	handle __attribute__((unused)))
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
342
				/*!< in: OS handle to the thread */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
343
{
344
#ifdef __WIN__
345
	int	os_pri;
346
	ulint	pri;
347
348
	os_pri = GetThreadPriority(handle);
349
350
	if (os_pri == THREAD_PRIORITY_BELOW_NORMAL) {
351
		pri = OS_THREAD_PRIORITY_BACKGROUND;
352
	} else if (os_pri == THREAD_PRIORITY_NORMAL) {
353
		pri = OS_THREAD_PRIORITY_NORMAL;
354
	} else if (os_pri == THREAD_PRIORITY_HIGHEST) {
355
		pri = OS_THREAD_PRIORITY_ABOVE_NORMAL;
356
	} else {
357
		ut_error;
358
	}
359
360
	return(pri);
361
#else
362
	return(0);
363
#endif
364
}
365
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
366
/******************************************************************//**
367
Gets the last operating system error code for the calling thread.
368
@return	last error on Windows, 0 otherwise */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
369
UNIV_INTERN
370
ulint
371
os_thread_get_last_error(void)
372
/*==========================*/
373
{
374
#ifdef __WIN__
375
	return(GetLastError());
376
#else
377
	return(0);
378
#endif
379
}
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
380
#endif /* !UNIV_HOTBACKUP */