mariadb/storage/xtradb/include/os0sync.ic
2015-05-04 19:15:28 +02:00

265 lines
8 KiB
Text

/*****************************************************************************
Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/os0sync.ic
The interface to the operating system synchronization primitives.
Created 9/6/1995 Heikki Tuuri
*******************************************************/
#ifdef __WIN__
#include <winbase.h>
#endif
/**********************************************************//**
Acquires ownership of a fast mutex.
@return 0 if success, != 0 if was reserved by another thread */
UNIV_INLINE
ulint
os_fast_mutex_trylock(
/*==================*/
os_fast_mutex_t* fast_mutex) /*!< in: mutex to acquire */
{
fast_mutex_t* mutex = &fast_mutex->mutex;
#ifdef __WIN__
return(!TryEnterCriticalSection(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(mutex));
#endif
}
#ifdef UNIV_PFS_MUTEX
/*********************************************************//**
NOTE! Please use the corresponding macro os_fast_mutex_init(), not directly
this function!
A wrapper function for os_fast_mutex_init_func(). Initializes an operating
system fast mutex semaphore. */
UNIV_INLINE
void
pfs_os_fast_mutex_init(
/*===================*/
PSI_mutex_key key, /*!< in: Performance Schema
key */
os_fast_mutex_t* fast_mutex) /*!< out: fast mutex */
{
#ifdef HAVE_PSI_MUTEX_INTERFACE
fast_mutex->pfs_psi = PSI_MUTEX_CALL(init_mutex)(key, &fast_mutex->mutex);
#else
fast_mutex->pfs_psi = NULL;
#endif
os_fast_mutex_init_func(&fast_mutex->mutex);
}
/******************************************************************//**
NOTE! Please use the corresponding macro os_fast_mutex_free(), not directly
this function!
Wrapper function for pfs_os_fast_mutex_free(). Also destroys the performance
schema probes when freeing the mutex */
UNIV_INLINE
void
pfs_os_fast_mutex_free(
/*===================*/
os_fast_mutex_t* fast_mutex) /*!< in/out: mutex */
{
#ifdef HAVE_PSI_MUTEX_INTERFACE
if (fast_mutex->pfs_psi != NULL)
PSI_MUTEX_CALL(destroy_mutex)(fast_mutex->pfs_psi);
#endif
fast_mutex->pfs_psi = NULL;
os_fast_mutex_free_func(&fast_mutex->mutex);
}
/**********************************************************//**
NOTE! Please use the corresponding macro os_fast_mutex_lock, not directly
this function!
Wrapper function of os_fast_mutex_lock_func. Acquires ownership of a fast
mutex. */
UNIV_INLINE
void
pfs_os_fast_mutex_lock(
/*===================*/
os_fast_mutex_t* fast_mutex, /*!< in/out: mutex to acquire */
const char* file_name, /*!< in: file name where
locked */
ulint line) /*!< in: line where locked */
{
#ifdef HAVE_PSI_MUTEX_INTERFACE
if (fast_mutex->pfs_psi != NULL)
{
PSI_mutex_locker* locker;
PSI_mutex_locker_state state;
locker = PSI_MUTEX_CALL(start_mutex_wait)(
&state, fast_mutex->pfs_psi,
PSI_MUTEX_LOCK, file_name,
static_cast<uint>(line));
os_fast_mutex_lock_func(&fast_mutex->mutex);
if (locker != NULL)
PSI_MUTEX_CALL(end_mutex_wait)(locker, 0);
}
else
#endif
{
os_fast_mutex_lock_func(&fast_mutex->mutex);
}
return;
}
/**********************************************************//**
NOTE! Please use the corresponding macro os_fast_mutex_unlock, not directly
this function!
Wrapper function of os_fast_mutex_unlock_func. Releases ownership of a
fast mutex. */
UNIV_INLINE
void
pfs_os_fast_mutex_unlock(
/*=====================*/
os_fast_mutex_t* fast_mutex) /*!< in/out: mutex to release */
{
#ifdef HAVE_PSI_MUTEX_INTERFACE
if (fast_mutex->pfs_psi != NULL)
PSI_MUTEX_CALL(unlock_mutex)(fast_mutex->pfs_psi);
#endif
os_fast_mutex_unlock_func(&fast_mutex->mutex);
}
#endif /* UNIV_PFS_MUTEX */
#ifdef HAVE_WINDOWS_ATOMICS
/* Use inline functions to make 64 and 32 bit versions of windows atomic
functions so that typecasts are evaluated at compile time. Take advantage
that lint is either __int64 or long int and windows atomic functions work
on __int64 and LONG */
/**********************************************************//**
Atomic compare and exchange of unsigned integers.
@return value found before the exchange.
If it is not equal to old_value the exchange did not happen. */
UNIV_INLINE
lint
win_cmp_and_xchg_lint(
/*==================*/
volatile lint* ptr, /*!< in/out: source/destination */
lint new_val, /*!< in: exchange value */
lint old_val) /*!< in: value to compare to */
{
# ifdef _WIN64
return(InterlockedCompareExchange64(ptr, new_val, old_val));
# else
return(InterlockedCompareExchange(ptr, new_val, old_val));
# endif
}
/**********************************************************//**
Atomic addition of signed integers.
@return Initial value of the variable pointed to by ptr */
UNIV_INLINE
lint
win_xchg_and_add(
/*=============*/
volatile lint* ptr, /*!< in/out: address of destination */
lint val) /*!< in: number to be added */
{
#ifdef _WIN64
return(InterlockedExchangeAdd64(ptr, val));
#else
return(InterlockedExchangeAdd(ptr, val));
#endif
}
/**********************************************************//**
Atomic compare and exchange of unsigned integers.
@return value found before the exchange.
If it is not equal to old_value the exchange did not happen. */
UNIV_INLINE
ulint
win_cmp_and_xchg_ulint(
/*===================*/
volatile ulint* ptr, /*!< in/out: source/destination */
ulint new_val, /*!< in: exchange value */
ulint old_val) /*!< in: value to compare to */
{
return((ulint) win_cmp_and_xchg_lint(
(volatile lint*) ptr,
(lint) new_val,
(lint) old_val));
}
/**********************************************************//**
Atomic compare and exchange of 32-bit unsigned integers.
@return value found before the exchange.
If it is not equal to old_value the exchange did not happen. */
UNIV_INLINE
DWORD
win_cmp_and_xchg_dword(
/*===================*/
volatile DWORD* ptr, /*!< in/out: source/destination */
DWORD new_val, /*!< in: exchange value */
DWORD old_val) /*!< in: value to compare to */
{
ut_ad(sizeof(DWORD) == sizeof(LONG)); /* We assume this. */
return(InterlockedCompareExchange(
(volatile LONG*) ptr,
(LONG) new_val,
(LONG) old_val));
}
#endif /* HAVE_WINDOWS_ATOMICS */
/**********************************************************//**
Acquires ownership of a fast mutex. Implies a full memory barrier even on
platforms such as PowerPC where this is not normally required.
@return 0 if success, != 0 if was reserved by another thread */
UNIV_INLINE
ulint
os_fast_mutex_trylock_full_barrier(
/*==================*/
os_fast_mutex_t* fast_mutex) /*!< in: mutex to acquire */
{
#ifdef __WIN__
if (TryEnterCriticalSection(&fast_mutex->mutex)) {
return(0);
} else {
return(1);
}
#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. */
#ifdef __powerpc__
os_mb;
#endif
return((ulint) pthread_mutex_trylock(&fast_mutex->mutex));
#endif
}