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
|