~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/include/os0sync.h

  • Committer: Monty Taylor
  • Date: 2011-02-13 17:26:39 UTC
  • mfrom: (2157.2.2 give-in-to-pkg-config)
  • mto: This revision was merged to the branch mainline in revision 2166.
  • Revision ID: mordred@inaugust.com-20110213172639-nhy7i72sfhoq13ms
Merged in pkg-config fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
 
Copyright (c) 2008, Google Inc.
 
3
Copyright (C) 1995, 2009, Innobase Oy. All Rights Reserved.
 
4
Copyright (C) 2008, Google Inc.
5
5
 
6
6
Portions of this file contain modifications contributed and copyrighted by
7
7
Google, Inc. Those modifications are gratefully acknowledged and are described
18
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19
19
 
20
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
 
21
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
 
22
St, Fifth Floor, Boston, MA 02110-1301 USA
23
23
 
24
24
*****************************************************************************/
25
25
 
38
38
#include "ut0lst.h"
39
39
 
40
40
#ifdef __WIN__
41
 
 
 
41
/** Native event (slow)*/
 
42
typedef HANDLE                  os_native_event_t;
42
43
/** Native mutex */
43
 
#define os_fast_mutex_t CRITICAL_SECTION
44
 
 
45
 
/** Native event */
46
 
typedef HANDLE          os_native_event_t;
47
 
 
48
 
/** Operating system event */
49
 
typedef struct os_event_struct  os_event_struct_t;
50
 
/** Operating system event handle */
51
 
typedef os_event_struct_t*      os_event_t;
52
 
 
53
 
/** An asynchronous signal sent between threads */
54
 
struct os_event_struct {
55
 
        os_native_event_t                 handle;
56
 
                                        /*!< Windows event */
57
 
        UT_LIST_NODE_T(os_event_struct_t) os_event_list;
58
 
                                        /*!< list of all created events */
59
 
};
 
44
typedef CRITICAL_SECTION        os_fast_mutex_t;
 
45
/** Native condition variable. */
 
46
typedef CONDITION_VARIABLE      os_cond_t;
60
47
#else
61
48
/** Native mutex */
62
 
typedef pthread_mutex_t os_fast_mutex_t;
 
49
typedef pthread_mutex_t         os_fast_mutex_t;
 
50
/** Native condition variable */
 
51
typedef pthread_cond_t          os_cond_t;
 
52
#endif
63
53
 
64
54
/** Operating system event */
65
55
typedef struct os_event_struct  os_event_struct_t;
68
58
 
69
59
/** An asynchronous signal sent between threads */
70
60
struct os_event_struct {
 
61
#ifdef __WIN__
 
62
        HANDLE          handle;         /*!< kernel event object, slow,
 
63
                                        used on older Windows */
 
64
#endif
71
65
        os_fast_mutex_t os_mutex;       /*!< this mutex protects the next
72
66
                                        fields */
73
67
        ibool           is_set;         /*!< this is TRUE when the event is
76
70
                                        this event */
77
71
        ib_int64_t      signal_count;   /*!< this is incremented each time
78
72
                                        the event becomes signaled */
79
 
        pthread_cond_t  cond_var;       /*!< condition variable is used in
 
73
        os_cond_t       cond_var;       /*!< condition variable is used in
80
74
                                        waiting for the event */
81
75
        UT_LIST_NODE_T(os_event_struct_t) os_event_list;
82
76
                                        /*!< list of all created events */
83
77
};
84
 
#endif
 
78
 
 
79
/** Denotes an infinite delay for os_event_wait_time() */
 
80
#define OS_SYNC_INFINITE_TIME   ULINT_UNDEFINED
 
81
 
 
82
/** Return value of os_event_wait_time() when the time is exceeded */
 
83
#define OS_SYNC_TIME_EXCEEDED   1
85
84
 
86
85
/** Operating system mutex */
87
86
typedef struct os_mutex_struct  os_mutex_str_t;
88
87
/** Operating system mutex handle */
89
88
typedef os_mutex_str_t*         os_mutex_t;
90
89
 
91
 
/** Denotes an infinite delay for os_event_wait_time() */
92
 
#define OS_SYNC_INFINITE_TIME   ((ulint)(-1))
93
 
 
94
 
/** Return value of os_event_wait_time() when the time is exceeded */
95
 
#define OS_SYNC_TIME_EXCEEDED   1
96
 
 
97
90
/** Mutex protecting counts and the event and OS 'slow' mutex lists */
98
91
extern os_mutex_t       os_sync_mutex;
99
92
 
186
179
                                        os_event_reset(). */
187
180
 
188
181
#define os_event_wait(event) os_event_wait_low(event, 0)
 
182
#define os_event_wait_time(e, t) os_event_wait_time_low(event, t, 0)
189
183
 
190
184
/**********************************************************//**
191
185
Waits for an event object until it is in the signaled state or
193
187
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
194
188
UNIV_INTERN
195
189
ulint
196
 
os_event_wait_time(
197
 
/*===============*/
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
 
@return index of the event which was signaled */
206
 
UNIV_INTERN
207
 
ulint
208
 
os_event_wait_multiple(
 
190
os_event_wait_time_low(
209
191
/*===================*/
210
 
        ulint                   n,      /*!< in: number of events in the
211
 
                                        array */
212
 
        os_native_event_t*      native_event_array);
213
 
                                        /*!< in: pointer to an array of event
214
 
                                        handles */
215
 
#endif
 
192
        os_event_t      event,                  /*!< in: event to wait */
 
193
        ulint           time_in_usec,           /*!< in: timeout in
 
194
                                                microseconds, or
 
195
                                                OS_SYNC_INFINITE_TIME */
 
196
        ib_int64_t      reset_sig_count);       /*!< in: zero or the value
 
197
                                                returned by previous call of
 
198
                                                os_event_reset(). */
216
199
/*********************************************************//**
217
200
Creates an operating system mutex semaphore. Because these are slow, the
218
201
mutex semaphore of InnoDB itself (mutex_t) should be used where possible.
219
202
@return the mutex handle */
220
203
UNIV_INTERN
221
204
os_mutex_t
222
 
os_mutex_create(
223
 
/*============*/
224
 
        const char*     name);  /*!< in: the name of the mutex, if NULL
225
 
                                the mutex is created without a name */
 
205
os_mutex_create(void);
 
206
/*=================*/
226
207
/**********************************************************//**
227
208
Acquires ownership of a mutex semaphore. */
228
209
UNIV_INTERN
285
266
/**********************************************************//**
286
267
Atomic compare-and-swap and increment for InnoDB. */
287
268
 
288
 
#ifdef HAVE_GCC_ATOMIC_BUILTINS
 
269
#if defined(HAVE_GCC_ATOMIC_BUILTINS)
 
270
 
 
271
#define HAVE_ATOMIC_BUILTINS
 
272
 
289
273
/**********************************************************//**
290
274
Returns true if swapped, ptr is pointer to target, old_val is value to
291
275
compare to, new_val is the value to swap in. */
 
276
 
292
277
# define os_compare_and_swap(ptr, old_val, new_val) \
293
278
        __sync_bool_compare_and_swap(ptr, old_val, new_val)
 
279
 
294
280
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
295
281
        os_compare_and_swap(ptr, old_val, new_val)
 
282
 
296
283
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
297
284
        os_compare_and_swap(ptr, old_val, new_val)
298
 
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
 
285
 
 
286
# ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
 
287
#  define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
299
288
        os_compare_and_swap(ptr, old_val, new_val)
 
289
#  define INNODB_RW_LOCKS_USE_ATOMICS
 
290
#  define IB_ATOMICS_STARTUP_MSG \
 
291
        "Mutexes and rw_locks use GCC atomic builtins"
 
292
# else /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
 
293
#  define IB_ATOMICS_STARTUP_MSG \
 
294
        "Mutexes use GCC atomic builtins, rw_locks do not"
 
295
# endif /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
 
296
 
300
297
/**********************************************************//**
301
298
Returns the resulting value, ptr is pointer to target, amount is the
302
299
amount of increment. */
 
300
 
303
301
# define os_atomic_increment(ptr, amount) \
304
302
        __sync_add_and_fetch(ptr, amount)
 
303
 
305
304
# define os_atomic_increment_lint(ptr, amount) \
306
305
        os_atomic_increment(ptr, amount)
 
306
 
307
307
# define os_atomic_increment_ulint(ptr, amount) \
308
308
        os_atomic_increment(ptr, amount)
 
309
 
309
310
/**********************************************************//**
310
311
Returns the old value of *ptr, atomically sets *ptr to new_val */
 
312
 
311
313
# define os_atomic_test_and_set_byte(ptr, new_val) \
312
 
        __sync_lock_test_and_set(ptr, new_val)
 
314
        __sync_lock_test_and_set(ptr, (byte) new_val)
 
315
 
 
316
#elif defined(HAVE_SOLARIS_ATOMICS)
 
317
 
 
318
#define HAVE_ATOMIC_BUILTINS
 
319
 
313
320
/* If not compiling with GCC or GCC doesn't support the atomic
314
321
intrinsics and running on Solaris >= 10 use Solaris atomics */
315
 
#elif defined(HAVE_SOLARIS_ATOMICS)
 
322
 
316
323
#include <atomic.h>
 
324
 
317
325
/**********************************************************//**
318
326
Returns true if swapped, ptr is pointer to target, old_val is value to
319
327
compare to, new_val is the value to swap in. */
 
328
 
320
329
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
321
330
        (atomic_cas_ulong(ptr, old_val, new_val) == old_val)
 
331
 
322
332
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
323
333
        ((lint)atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val)
324
 
# ifdef INNODB_RW_LOCKS_USE_ATOMICS
325
 
#  if   SIZEOF_PTHREAD_T == 4
 
334
 
 
335
# ifdef HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS
 
336
#  if SIZEOF_PTHREAD_T == 4
326
337
#   define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
327
338
        ((pthread_t)atomic_cas_32(ptr, old_val, new_val) == old_val)
328
339
#  elif SIZEOF_PTHREAD_T == 8
331
342
#  else
332
343
#   error "SIZEOF_PTHREAD_T != 4 or 8"
333
344
#  endif /* SIZEOF_PTHREAD_T CHECK */
334
 
# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
 
345
#  define INNODB_RW_LOCKS_USE_ATOMICS
 
346
#  define IB_ATOMICS_STARTUP_MSG \
 
347
        "Mutexes and rw_locks use Solaris atomic functions"
 
348
# else /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
 
349
#  define IB_ATOMICS_STARTUP_MSG \
 
350
        "Mutexes use Solaris atomic functions, rw_locks do not"
 
351
# endif /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
335
352
 
336
353
/**********************************************************//**
337
354
Returns the resulting value, ptr is pointer to target, amount is the
338
355
amount of increment. */
 
356
 
339
357
# define os_atomic_increment_lint(ptr, amount) \
340
358
        atomic_add_long_nv((ulong_t*) ptr, amount)
 
359
 
341
360
# define os_atomic_increment_ulint(ptr, amount) \
342
361
        atomic_add_long_nv(ptr, amount)
 
362
 
343
363
/**********************************************************//**
344
364
Returns the old value of *ptr, atomically sets *ptr to new_val */
 
365
 
345
366
# define os_atomic_test_and_set_byte(ptr, new_val) \
346
367
        atomic_swap_uchar(ptr, new_val)
 
368
 
 
369
#elif defined(HAVE_WINDOWS_ATOMICS)
 
370
 
 
371
#define HAVE_ATOMIC_BUILTINS
 
372
 
347
373
/* On Windows, use Windows atomics / interlocked */
348
 
#elif defined(HAVE_WINDOWS_ATOMICS)
349
374
# ifdef _WIN64
350
375
#  define win_cmp_and_xchg InterlockedCompareExchange64
351
376
#  define win_xchg_and_add InterlockedExchangeAdd64
353
378
#  define win_cmp_and_xchg InterlockedCompareExchange
354
379
#  define win_xchg_and_add InterlockedExchangeAdd
355
380
# endif
 
381
 
356
382
/**********************************************************//**
357
383
Returns true if swapped, ptr is pointer to target, old_val is value to
358
384
compare to, new_val is the value to swap in. */
 
385
 
359
386
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
360
387
        (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
 
388
 
361
389
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
362
390
        (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
363
 
# ifdef INNODB_RW_LOCKS_USE_ATOMICS
364
 
#  define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
 
391
 
 
392
/* windows thread objects can always be passed to windows atomic functions */
 
393
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
365
394
        (InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
366
 
# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
 
395
# define INNODB_RW_LOCKS_USE_ATOMICS
 
396
# define IB_ATOMICS_STARTUP_MSG \
 
397
        "Mutexes and rw_locks use Windows interlocked functions"
 
398
 
367
399
/**********************************************************//**
368
400
Returns the resulting value, ptr is pointer to target, amount is the
369
401
amount of increment. */
 
402
 
370
403
# define os_atomic_increment_lint(ptr, amount) \
371
404
        (win_xchg_and_add(ptr, amount) + amount)
 
405
 
372
406
# define os_atomic_increment_ulint(ptr, amount) \
373
407
        ((ulint) (win_xchg_and_add(ptr, amount) + amount))
 
408
 
374
409
/**********************************************************//**
375
410
Returns the old value of *ptr, atomically sets *ptr to new_val.
376
411
InterlockedExchange() operates on LONG, and the LONG will be
377
412
clobbered */
 
413
 
378
414
# define os_atomic_test_and_set_byte(ptr, new_val) \
379
415
        ((byte) InterlockedExchange(ptr, new_val))
380
 
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
 
416
 
 
417
#else
 
418
# define IB_ATOMICS_STARTUP_MSG \
 
419
        "Mutexes and rw_locks use InnoDB's own implementation"
 
420
#endif
381
421
 
382
422
#ifndef UNIV_NONINL
383
423
#include "os0sync.ic"