mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 21:12:26 +01:00
265 lines
8 KiB
Text
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
|
|
}
|