/****************************************************** The interface to the operating system synchronization primitives. (c) 1995 Innobase Oy Created 9/6/1995 Heikki Tuuri *******************************************************/ #ifdef __WIN__ #include <winbase.h> #endif /************************************************************** Acquires ownership of a fast mutex. Currently in Windows this is the same as os_fast_mutex_lock! */ UNIV_INLINE ulint os_fast_mutex_trylock( /*==================*/ /* out: 0 if success, != 0 if was reserved by another thread */ os_fast_mutex_t* fast_mutex) /* in: mutex to acquire */ { #ifdef __WIN__ EnterCriticalSection(fast_mutex); return(0); #else #if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10) /* Since the hot backup version is standalone, MySQL does not redefine pthread_mutex_trylock for HP-UX-10.20, and consequently we must invert the return value here */ return((ulint) (1 - pthread_mutex_trylock(fast_mutex))); #else /* NOTE that the MySQL my_pthread.h redefines pthread_mutex_trylock so that it returns 0 on success. In the operating system libraries, HP-UX-10.20 follows the old Posix 1003.4a Draft 4 and returns 1 on success (but MySQL remaps that to 0), while Linux, FreeBSD, Solaris, AIX, Tru64 Unix, HP-UX-11.0 return 0 on success. */ return((ulint) pthread_mutex_trylock(fast_mutex)); #endif #endif } #ifdef UNIV_SYNC_ATOMIC /************************************************************** Atomic compare-and-swap for InnoDB. Currently requires GCC atomic builtins or Solaris atomic_* functions. */ UNIV_INLINE ibool os_compare_and_swap( /*================*/ /* out: true if swapped */ volatile lint* ptr, /* in: pointer to target */ lint oldVal, /* in: value to compare to */ lint newVal) /* in: value to swap in */ { #ifdef HAVE_GCC_ATOMIC_BUILTINS return (__sync_bool_compare_and_swap(ptr, oldVal, newVal)); #elif HAVE_SOLARIS_ATOMIC lint retVal = (lint)atomic_cas_ulong((volatile ulong_t *)ptr, oldVal, newVal); return (retVal == oldVal); #elif WIN_ATOMICS32 lint retVal = (lint)InterlockedCompareExchange(ptr, newVal, oldVal); return (retVal == oldVal); #elif WIN_ATOMICS64 lint retVal = (lint)InterlockedCompareExchange64(ptr, newVal, oldVal); return (retVal == oldVal); #else #error "Need support for atomic ops" #endif } /************************************************************** Memory barrier for load */ UNIV_INLINE void os_memory_barrier_load() { #ifdef HAVE_GCC_ATOMIC_BUILTINS __sync_synchronize(); #elif HAVE_SOLARIS_ATOMIC membar_consumer(); #elif WIN_ATOMICS32 MemoryBarrier(); #elif WIN_ATOMICS64 MemoryBarrier(); #endif } /************************************************************** Memory barrier for store */ UNIV_INLINE void os_memory_barrier_store() { #ifdef HAVE_GCC_ATOMIC_BUILTINS __sync_synchronize(); #elif HAVE_SOLARIS_ATOMIC membar_producer(); #elif WIN_ATOMICS32 MemoryBarrier(); #elif WIN_ATOMICS64 MemoryBarrier(); #endif } /************************************************************** Memory barrier */ UNIV_INLINE void os_memory_barrier() { #ifdef HAVE_GCC_ATOMIC_BUILTINS __sync_synchronize(); #elif HAVE_SOLARIS_ATOMIC membar_enter(); #elif WIN_ATOMICS32 MemoryBarrier(); #elif WIN_ATOMICS64 MemoryBarrier(); #endif } /************************************************************** Atomic increment for InnoDB. Currently requires GCC atomic builtins. */ UNIV_INLINE lint os_atomic_increment( /*================*/ /* out: resulting value */ volatile lint* ptr, /* in: pointer to target */ lint amount) /* in: amount of increment */ { #ifdef HAVE_GCC_ATOMIC_BUILTINS return (__sync_add_and_fetch(ptr, amount)); #elif HAVE_SOLARIS_ATOMIC return ((lint)atomic_add_long_nv((volatile ulong_t *)ptr, amount)); #elif WIN_ATOMICS32 return ((lint)InterlockedExchangeAdd(ptr, amount) + amount); #elif WIN_ATOMICS64 return ((lint)InterlockedExchangeAdd64(ptr, amount) + amount); #else #error "Need support for atomic ops" #endif } #endif /* UNIV_SYNC_ATOMIC */