mariadb/storage/innobase/include/os0sync.ic
Mikael Ronstrom d1d11d6baf Add support for Atomic instructions for Windows
Enables Google patch support on Windows
2009-03-06 19:25:38 +01:00

152 lines
4 KiB
Text

/******************************************************
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));
#elif WIN_ATOMICS64
return ((lint)InterlockedExchangeAdd64(ptr, amount));
#else
#error "Need support for atomic ops"
#endif
}
#endif /* UNIV_SYNC_ATOMIC */