~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
Copyright (c) 2008, Google Inc.
5
6
Portions of this file contain modifications contributed and copyrighted by
7
Google, Inc. Those modifications are gratefully acknowledged and are described
8
briefly in the InnoDB documentation. The contributions by Google are
9
incorporated with their permission, and subject to the conditions contained in
10
the file COPYING.Google.
11
12
This program is free software; you can redistribute it and/or modify it under
13
the terms of the GNU General Public License as published by the Free Software
14
Foundation; version 2 of the License.
15
16
This program is distributed in the hope that it will be useful, but WITHOUT
17
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19
20
You should have received a copy of the GNU General Public License along with
21
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22
Place, Suite 330, Boston, MA 02111-1307 USA
23
24
*****************************************************************************/
25
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
26
/******************************************************
27
The interface to the operating system
28
synchronization primitives.
29
30
Created 9/6/1995 Heikki Tuuri
31
*******************************************************/
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
32
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
33
#ifndef os0sync_h
34
#define os0sync_h
35
36
#include "univ.i"
37
#include "ut0lst.h"
38
39
#ifdef __WIN__
40
41
#define os_fast_mutex_t CRITICAL_SECTION
42
43
typedef HANDLE		os_native_event_t;
44
45
typedef struct os_event_struct	os_event_struct_t;
46
typedef os_event_struct_t*	os_event_t;
47
48
struct os_event_struct {
49
	os_native_event_t		  handle;
50
					/* Windows event */
51
	UT_LIST_NODE_T(os_event_struct_t) os_event_list;
52
					/* list of all created events */
53
};
54
#else
55
typedef pthread_mutex_t	os_fast_mutex_t;
56
57
typedef struct os_event_struct	os_event_struct_t;
58
typedef os_event_struct_t*	os_event_t;
59
60
struct os_event_struct {
61
	os_fast_mutex_t	os_mutex;	/* this mutex protects the next
62
					fields */
63
	ibool		is_set;		/* this is TRUE when the event is
64
					in the signaled state, i.e., a thread
65
					does not stop if it tries to wait for
66
					this event */
67
	ib_int64_t	signal_count;	/* this is incremented each time
68
					the event becomes signaled */
69
	pthread_cond_t	cond_var;	/* condition variable is used in
70
					waiting for the event */
71
	UT_LIST_NODE_T(os_event_struct_t) os_event_list;
72
					/* list of all created events */
73
};
74
#endif
75
76
typedef struct os_mutex_struct	os_mutex_str_t;
77
typedef os_mutex_str_t*		os_mutex_t;
78
79
#define OS_SYNC_INFINITE_TIME	((ulint)(-1))
80
81
#define OS_SYNC_TIME_EXCEEDED	1
82
83
/* Mutex protecting counts and the event and OS 'slow' mutex lists */
84
extern os_mutex_t	os_sync_mutex;
85
86
/* This is incremented by 1 in os_thread_create and decremented by 1 in
87
os_thread_exit */
88
extern ulint		os_thread_count;
89
90
extern ulint		os_event_count;
91
extern ulint		os_mutex_count;
92
extern ulint		os_fast_mutex_count;
93
94
/*************************************************************
95
Initializes global event and OS 'slow' mutex lists. */
96
UNIV_INTERN
97
void
98
os_sync_init(void);
99
/*==============*/
100
/*************************************************************
101
Frees created events and OS 'slow' mutexes. */
102
UNIV_INTERN
103
void
104
os_sync_free(void);
105
/*==============*/
106
/*************************************************************
107
Creates an event semaphore, i.e., a semaphore which may just have two states:
108
signaled and nonsignaled. The created event is manual reset: it must be reset
109
explicitly by calling sync_os_reset_event. */
110
UNIV_INTERN
111
os_event_t
112
os_event_create(
113
/*============*/
114
				/* out: the event handle */
115
	const char*	name);	/* in: the name of the event, if NULL
116
				the event is created without a name */
117
#ifdef __WIN__
118
/*************************************************************
119
Creates an auto-reset event semaphore, i.e., an event which is automatically
120
reset when a single thread is released. Works only in Windows. */
121
UNIV_INTERN
122
os_event_t
123
os_event_create_auto(
124
/*=================*/
125
				/* out: the event handle */
126
	const char*	name);	/* in: the name of the event, if NULL
127
				the event is created without a name */
128
#endif
129
/**************************************************************
130
Sets an event semaphore to the signaled state: lets waiting threads
131
proceed. */
132
UNIV_INTERN
133
void
134
os_event_set(
135
/*=========*/
136
	os_event_t	event);	/* in: event to set */
137
/**************************************************************
138
Resets an event semaphore to the nonsignaled state. Waiting threads will
139
stop to wait for the event.
140
The return value should be passed to os_even_wait_low() if it is desired
141
that this thread should not wait in case of an intervening call to
142
os_event_set() between this os_event_reset() and the
143
os_event_wait_low() call. See comments for os_event_wait_low(). */
144
UNIV_INTERN
145
ib_int64_t
146
os_event_reset(
147
/*===========*/
148
	os_event_t	event);	/* in: event to reset */
149
/**************************************************************
150
Frees an event object. */
151
UNIV_INTERN
152
void
153
os_event_free(
154
/*==========*/
155
	os_event_t	event);	/* in: event to free */
156
157
/**************************************************************
158
Waits for an event object until it is in the signaled state. If
159
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
160
waiting thread when the event becomes signaled (or immediately if the
161
event is already in the signaled state).
162
163
Typically, if the event has been signalled after the os_event_reset()
164
we'll return immediately because event->is_set == TRUE.
165
There are, however, situations (e.g.: sync_array code) where we may
166
lose this information. For example:
167
168
thread A calls os_event_reset()
169
thread B calls os_event_set()   [event->is_set == TRUE]
170
thread C calls os_event_reset() [event->is_set == FALSE]
171
thread A calls os_event_wait()  [infinite wait!]
172
thread C calls os_event_wait()  [infinite wait!]
173
174
Where such a scenario is possible, to avoid infinite wait, the
175
value returned by os_event_reset() should be passed in as
176
reset_sig_count. */
177
UNIV_INTERN
178
void
179
os_event_wait_low(
180
/*==============*/
181
	os_event_t	event,		/* in: event to wait */
182
	ib_int64_t	reset_sig_count);/* in: zero or the value
183
					returned by previous call of
184
					os_event_reset(). */
185
186
#define os_event_wait(event) os_event_wait_low(event, 0)
187
188
/**************************************************************
189
Waits for an event object until it is in the signaled state or
190
a timeout is exceeded. In Unix the timeout is always infinite. */
191
UNIV_INTERN
192
ulint
193
os_event_wait_time(
194
/*===============*/
195
				/* out: 0 if success,
196
				OS_SYNC_TIME_EXCEEDED if timeout
197
				was exceeded */
198
	os_event_t	event,	/* in: event to wait */
199
	ulint		time);	/* in: timeout in microseconds, or
200
				OS_SYNC_INFINITE_TIME */
201
#ifdef __WIN__
202
/**************************************************************
203
Waits for any event in an OS native event array. Returns if even a single
204
one is signaled or becomes signaled. */
205
UNIV_INTERN
206
ulint
207
os_event_wait_multiple(
208
/*===================*/
209
					/* out: index of the event
210
					which was signaled */
211
	ulint			n,	/* in: number of events in the
212
					array */
213
	os_native_event_t*	native_event_array);
214
					/* in: pointer to an array of event
215
					handles */
216
#endif
217
/*************************************************************
218
Creates an operating system mutex semaphore. Because these are slow, the
219
mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */
220
UNIV_INTERN
221
os_mutex_t
222
os_mutex_create(
223
/*============*/
224
				/* out: the mutex handle */
225
	const char*	name);	/* in: the name of the mutex, if NULL
226
				the mutex is created without a name */
227
/**************************************************************
228
Acquires ownership of a mutex semaphore. */
229
UNIV_INTERN
230
void
231
os_mutex_enter(
232
/*===========*/
233
	os_mutex_t	mutex);	/* in: mutex to acquire */
234
/**************************************************************
235
Releases ownership of a mutex. */
236
UNIV_INTERN
237
void
238
os_mutex_exit(
239
/*==========*/
240
	os_mutex_t	mutex);	/* in: mutex to release */
241
/**************************************************************
242
Frees an mutex object. */
243
UNIV_INTERN
244
void
245
os_mutex_free(
246
/*==========*/
247
	os_mutex_t	mutex);	/* in: mutex to free */
248
/**************************************************************
249
Acquires ownership of a fast mutex. Currently in Windows this is the same
250
as os_fast_mutex_lock! */
251
UNIV_INLINE
252
ulint
253
os_fast_mutex_trylock(
254
/*==================*/
255
						/* out: 0 if success, != 0 if
256
						was reserved by another
257
						thread */
258
	os_fast_mutex_t*	fast_mutex);	/* in: mutex to acquire */
259
/**************************************************************
260
Releases ownership of a fast mutex. */
261
UNIV_INTERN
262
void
263
os_fast_mutex_unlock(
264
/*=================*/
265
	os_fast_mutex_t*	fast_mutex);	/* in: mutex to release */
266
/*************************************************************
267
Initializes an operating system fast mutex semaphore. */
268
UNIV_INTERN
269
void
270
os_fast_mutex_init(
271
/*===============*/
272
	os_fast_mutex_t*	fast_mutex);	/* in: fast mutex */
273
/**************************************************************
274
Acquires ownership of a fast mutex. */
275
UNIV_INTERN
276
void
277
os_fast_mutex_lock(
278
/*===============*/
279
	os_fast_mutex_t*	fast_mutex);	/* in: mutex to acquire */
280
/**************************************************************
281
Frees an mutex object. */
282
UNIV_INTERN
283
void
284
os_fast_mutex_free(
285
/*===============*/
286
	os_fast_mutex_t*	fast_mutex);	/* in: mutex to free */
287
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
288
#ifdef HAVE_GCC_ATOMIC_BUILTINS
289
/**************************************************************
290
Atomic compare-and-swap for InnoDB. Currently requires GCC atomic builtins.
291
Returns true if swapped, ptr is pointer to target, old_val is value to
292
compare to, new_val is the value to swap in. */
293
#define os_compare_and_swap(ptr, old_val, new_val) \
294
	__sync_bool_compare_and_swap(ptr, old_val, new_val)
295
296
/**************************************************************
297
Atomic increment for InnoDB. Currently requires GCC atomic builtins.
298
Returns the resulting value, ptr is pointer to target, amount is the
299
amount of increment. */
300
#define os_atomic_increment(ptr, amount) \
301
	__sync_add_and_fetch(ptr, amount)
302
303
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
304
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
305
#ifndef UNIV_NONINL
306
#include "os0sync.ic"
307
#endif
308
309
#endif