1
/******************************************************
2
The interface to the operating system
3
synchronization primitives.
7
Created 9/6/1995 Heikki Tuuri
8
*******************************************************/
17
#define os_fast_mutex_t CRITICAL_SECTION
19
typedef HANDLE os_native_event_t;
21
typedef struct os_event_struct os_event_struct_t;
22
typedef os_event_struct_t* os_event_t;
24
struct os_event_struct {
25
os_native_event_t handle;
27
UT_LIST_NODE_T(os_event_struct_t) os_event_list;
28
/* list of all created events */
31
typedef pthread_mutex_t os_fast_mutex_t;
33
typedef struct os_event_struct os_event_struct_t;
34
typedef os_event_struct_t* os_event_t;
36
struct os_event_struct {
37
os_fast_mutex_t os_mutex; /* this mutex protects the next
39
ibool is_set; /* this is TRUE when the event is
40
in the signaled state, i.e., a thread
41
does not stop if it tries to wait for
43
ib_int64_t signal_count; /* this is incremented each time
44
the event becomes signaled */
45
pthread_cond_t cond_var; /* condition variable is used in
46
waiting for the event */
47
UT_LIST_NODE_T(os_event_struct_t) os_event_list;
48
/* list of all created events */
52
typedef struct os_mutex_struct os_mutex_str_t;
53
typedef os_mutex_str_t* os_mutex_t;
55
#define OS_SYNC_INFINITE_TIME ((ulint)(-1))
57
#define OS_SYNC_TIME_EXCEEDED 1
59
/* Mutex protecting counts and the event and OS 'slow' mutex lists */
60
extern os_mutex_t os_sync_mutex;
62
/* This is incremented by 1 in os_thread_create and decremented by 1 in
64
extern ulint os_thread_count;
66
extern ulint os_event_count;
67
extern ulint os_mutex_count;
68
extern ulint os_fast_mutex_count;
70
/*************************************************************
71
Initializes global event and OS 'slow' mutex lists. */
76
/*************************************************************
77
Frees created events and OS 'slow' mutexes. */
82
/*************************************************************
83
Creates an event semaphore, i.e., a semaphore which may just have two states:
84
signaled and nonsignaled. The created event is manual reset: it must be reset
85
explicitly by calling sync_os_reset_event. */
90
/* out: the event handle */
91
const char* name); /* in: the name of the event, if NULL
92
the event is created without a name */
94
/*************************************************************
95
Creates an auto-reset event semaphore, i.e., an event which is automatically
96
reset when a single thread is released. Works only in Windows. */
100
/*=================*/
101
/* out: the event handle */
102
const char* name); /* in: the name of the event, if NULL
103
the event is created without a name */
105
/**************************************************************
106
Sets an event semaphore to the signaled state: lets waiting threads
112
os_event_t event); /* in: event to set */
113
/**************************************************************
114
Resets an event semaphore to the nonsignaled state. Waiting threads will
115
stop to wait for the event.
116
The return value should be passed to os_even_wait_low() if it is desired
117
that this thread should not wait in case of an intervening call to
118
os_event_set() between this os_event_reset() and the
119
os_event_wait_low() call. See comments for os_event_wait_low(). */
124
os_event_t event); /* in: event to reset */
125
/**************************************************************
126
Frees an event object. */
131
os_event_t event); /* in: event to free */
133
/**************************************************************
134
Waits for an event object until it is in the signaled state. If
135
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
136
waiting thread when the event becomes signaled (or immediately if the
137
event is already in the signaled state).
139
Typically, if the event has been signalled after the os_event_reset()
140
we'll return immediately because event->is_set == TRUE.
141
There are, however, situations (e.g.: sync_array code) where we may
142
lose this information. For example:
144
thread A calls os_event_reset()
145
thread B calls os_event_set() [event->is_set == TRUE]
146
thread C calls os_event_reset() [event->is_set == FALSE]
147
thread A calls os_event_wait() [infinite wait!]
148
thread C calls os_event_wait() [infinite wait!]
150
Where such a scenario is possible, to avoid infinite wait, the
151
value returned by os_event_reset() should be passed in as
157
os_event_t event, /* in: event to wait */
158
ib_int64_t reset_sig_count);/* in: zero or the value
159
returned by previous call of
162
#define os_event_wait(event) os_event_wait_low(event, 0)
164
/**************************************************************
165
Waits for an event object until it is in the signaled state or
166
a timeout is exceeded. In Unix the timeout is always infinite. */
171
/* out: 0 if success,
172
OS_SYNC_TIME_EXCEEDED if timeout
174
os_event_t event, /* in: event to wait */
175
ulint time); /* in: timeout in microseconds, or
176
OS_SYNC_INFINITE_TIME */
178
/**************************************************************
179
Waits for any event in an OS native event array. Returns if even a single
180
one is signaled or becomes signaled. */
183
os_event_wait_multiple(
184
/*===================*/
185
/* out: index of the event
186
which was signaled */
187
ulint n, /* in: number of events in the
189
os_native_event_t* native_event_array);
190
/* in: pointer to an array of event
193
/*************************************************************
194
Creates an operating system mutex semaphore. Because these are slow, the
195
mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */
200
/* out: the mutex handle */
201
const char* name); /* in: the name of the mutex, if NULL
202
the mutex is created without a name */
203
/**************************************************************
204
Acquires ownership of a mutex semaphore. */
209
os_mutex_t mutex); /* in: mutex to acquire */
210
/**************************************************************
211
Releases ownership of a mutex. */
216
os_mutex_t mutex); /* in: mutex to release */
217
/**************************************************************
218
Frees an mutex object. */
223
os_mutex_t mutex); /* in: mutex to free */
224
/**************************************************************
225
Acquires ownership of a fast mutex. Currently in Windows this is the same
226
as os_fast_mutex_lock! */
229
os_fast_mutex_trylock(
230
/*==================*/
231
/* out: 0 if success, != 0 if
232
was reserved by another
234
os_fast_mutex_t* fast_mutex); /* in: mutex to acquire */
235
/**************************************************************
236
Releases ownership of a fast mutex. */
239
os_fast_mutex_unlock(
240
/*=================*/
241
os_fast_mutex_t* fast_mutex); /* in: mutex to release */
242
/*************************************************************
243
Initializes an operating system fast mutex semaphore. */
248
os_fast_mutex_t* fast_mutex); /* in: fast mutex */
249
/**************************************************************
250
Acquires ownership of a fast mutex. */
255
os_fast_mutex_t* fast_mutex); /* in: mutex to acquire */
256
/**************************************************************
257
Frees an mutex object. */
262
os_fast_mutex_t* fast_mutex); /* in: mutex to free */
265
#include "os0sync.ic"