00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00034 #pragma once
00035 #ifndef os0sync_h
00036 #define os0sync_h
00037
00038 #include "univ.i"
00039 #include "ut0lst.h"
00040
00041 #ifdef __WIN__
00042
00043 typedef HANDLE os_native_event_t;
00045 typedef CRITICAL_SECTION os_fast_mutex_t;
00047 typedef CONDITION_VARIABLE os_cond_t;
00048 #else
00049
00050 typedef pthread_mutex_t os_fast_mutex_t;
00052 typedef pthread_cond_t os_cond_t;
00053 #endif
00054
00056 typedef struct os_event_struct os_event_struct_t;
00058 typedef os_event_struct_t* os_event_t;
00059
00061 struct os_event_struct {
00062 #ifdef __WIN__
00063 HANDLE handle;
00065 #endif
00066 os_fast_mutex_t os_mutex;
00068 ibool is_set;
00072 ib_int64_t signal_count;
00074 os_cond_t cond_var;
00076 UT_LIST_NODE_T(os_event_struct_t) os_event_list;
00078 };
00079
00081 #define OS_SYNC_INFINITE_TIME ULINT_UNDEFINED
00082
00084 #define OS_SYNC_TIME_EXCEEDED 1
00085
00087 typedef struct os_mutex_struct os_mutex_str_t;
00089 typedef os_mutex_str_t* os_mutex_t;
00090
00092 extern os_mutex_t os_sync_mutex;
00093
00096 extern ulint os_thread_count;
00097
00098 extern ulint os_event_count;
00099 extern ulint os_mutex_count;
00100 extern ulint os_fast_mutex_count;
00101
00102
00104 UNIV_INTERN
00105 void
00106 os_sync_init(void);
00107
00108
00110 UNIV_INTERN
00111 void
00112 os_sync_free(void);
00113
00114
00119 UNIV_INTERN
00120 os_event_t
00121 os_event_create(
00122
00123 const char* name);
00125
00128 UNIV_INTERN
00129 void
00130 os_event_set(
00131
00132 os_event_t event);
00133
00140 UNIV_INTERN
00141 ib_int64_t
00142 os_event_reset(
00143
00144 os_event_t event);
00145
00147 UNIV_INTERN
00148 void
00149 os_event_free(
00150
00151 os_event_t event);
00153
00173 UNIV_INTERN
00174 void
00175 os_event_wait_low(
00176
00177 os_event_t event,
00178 ib_int64_t reset_sig_count);
00182 #define os_event_wait(event) os_event_wait_low(event, 0)
00183 #define os_event_wait_time(e, t) os_event_wait_time_low(event, t, 0)
00184
00185
00189 UNIV_INTERN
00190 ulint
00191 os_event_wait_time_low(
00192
00193 os_event_t event,
00194 ulint time_in_usec,
00197 ib_int64_t reset_sig_count);
00200
00204 UNIV_INTERN
00205 os_mutex_t
00206 os_mutex_create(void);
00207
00208
00210 UNIV_INTERN
00211 void
00212 os_mutex_enter(
00213
00214 os_mutex_t mutex);
00215
00217 UNIV_INTERN
00218 void
00219 os_mutex_exit(
00220
00221 os_mutex_t mutex);
00222
00224 UNIV_INTERN
00225 void
00226 os_mutex_free(
00227
00228 os_mutex_t mutex);
00229
00233 UNIV_INLINE
00234 ulint
00235 os_fast_mutex_trylock(
00236
00237 os_fast_mutex_t* fast_mutex);
00238
00240 UNIV_INTERN
00241 void
00242 os_fast_mutex_unlock(
00243
00244 os_fast_mutex_t* fast_mutex);
00245
00247 UNIV_INTERN
00248 void
00249 os_fast_mutex_init(
00250
00251 os_fast_mutex_t* fast_mutex);
00252
00254 UNIV_INTERN
00255 void
00256 os_fast_mutex_lock(
00257
00258 os_fast_mutex_t* fast_mutex);
00259
00261 UNIV_INTERN
00262 void
00263 os_fast_mutex_free(
00264
00265 os_fast_mutex_t* fast_mutex);
00267
00270 #if defined(HAVE_GCC_ATOMIC_BUILTINS)
00271
00272 #define HAVE_ATOMIC_BUILTINS
00273
00274
00278 # define os_compare_and_swap(ptr, old_val, new_val) \
00279 __sync_bool_compare_and_swap(ptr, old_val, new_val)
00280
00281 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
00282 os_compare_and_swap(ptr, old_val, new_val)
00283
00284 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
00285 os_compare_and_swap(ptr, old_val, new_val)
00286
00287 # ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
00288 # define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
00289 os_compare_and_swap(ptr, old_val, new_val)
00290 # define INNODB_RW_LOCKS_USE_ATOMICS
00291 # define IB_ATOMICS_STARTUP_MSG \
00292 "Mutexes and rw_locks use GCC atomic builtins"
00293 # else
00294 # define IB_ATOMICS_STARTUP_MSG \
00295 "Mutexes use GCC atomic builtins, rw_locks do not"
00296 # endif
00297
00298
00302 # define os_atomic_increment(ptr, amount) \
00303 __sync_add_and_fetch(ptr, amount)
00304
00305 # define os_atomic_increment_lint(ptr, amount) \
00306 os_atomic_increment(ptr, amount)
00307
00308 # define os_atomic_increment_ulint(ptr, amount) \
00309 os_atomic_increment(ptr, amount)
00310
00311
00314 # define os_atomic_test_and_set_byte(ptr, new_val) \
00315 __sync_lock_test_and_set(ptr, (byte) new_val)
00316
00317 #elif defined(HAVE_SOLARIS_ATOMICS)
00318
00319 #define HAVE_ATOMIC_BUILTINS
00320
00321
00322
00323
00324 #include <atomic.h>
00325
00326
00330 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
00331 (atomic_cas_ulong(ptr, old_val, new_val) == old_val)
00332
00333 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
00334 ((lint)atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val)
00335
00336 # ifdef HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS
00337 # if SIZEOF_PTHREAD_T == 4
00338 # define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
00339 ((pthread_t)atomic_cas_32(ptr, old_val, new_val) == old_val)
00340 # elif SIZEOF_PTHREAD_T == 8
00341 # define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
00342 ((pthread_t)atomic_cas_64(ptr, old_val, new_val) == old_val)
00343 # else
00344 # error "SIZEOF_PTHREAD_T != 4 or 8"
00345 # endif
00346 # define INNODB_RW_LOCKS_USE_ATOMICS
00347 # define IB_ATOMICS_STARTUP_MSG \
00348 "Mutexes and rw_locks use Solaris atomic functions"
00349 # else
00350 # define IB_ATOMICS_STARTUP_MSG \
00351 "Mutexes use Solaris atomic functions, rw_locks do not"
00352 # endif
00353
00354
00358 # define os_atomic_increment_lint(ptr, amount) \
00359 atomic_add_long_nv((ulong_t*) ptr, amount)
00360
00361 # define os_atomic_increment_ulint(ptr, amount) \
00362 atomic_add_long_nv(ptr, amount)
00363
00364
00367 # define os_atomic_test_and_set_byte(ptr, new_val) \
00368 atomic_swap_uchar(ptr, new_val)
00369
00370 #elif defined(HAVE_WINDOWS_ATOMICS)
00371
00372 #define HAVE_ATOMIC_BUILTINS
00373
00374
00375 # ifdef _WIN64
00376 # define win_cmp_and_xchg InterlockedCompareExchange64
00377 # define win_xchg_and_add InterlockedExchangeAdd64
00378 # else
00379 # define win_cmp_and_xchg InterlockedCompareExchange
00380 # define win_xchg_and_add InterlockedExchangeAdd
00381 # endif
00382
00383
00387 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
00388 (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
00389
00390 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
00391 (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
00392
00393
00394 # define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
00395 (InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
00396 # define INNODB_RW_LOCKS_USE_ATOMICS
00397 # define IB_ATOMICS_STARTUP_MSG \
00398 "Mutexes and rw_locks use Windows interlocked functions"
00399
00400
00404 # define os_atomic_increment_lint(ptr, amount) \
00405 (win_xchg_and_add(ptr, amount) + amount)
00406
00407 # define os_atomic_increment_ulint(ptr, amount) \
00408 ((ulint) (win_xchg_and_add(ptr, amount) + amount))
00409
00410
00415 # define os_atomic_test_and_set_byte(ptr, new_val) \
00416 ((byte) InterlockedExchange(ptr, new_val))
00417
00418 #else
00419 # define IB_ATOMICS_STARTUP_MSG \
00420 "Mutexes and rw_locks use InnoDB's own implementation"
00421 #endif
00422
00423 #ifndef UNIV_NONINL
00424 #include "os0sync.ic"
00425 #endif
00426
00427 #endif