diff options
Diffstat (limited to 'storage/xtradb/include/sync0sync.ic')
-rw-r--r-- | storage/xtradb/include/sync0sync.ic | 665 |
1 files changed, 0 insertions, 665 deletions
diff --git a/storage/xtradb/include/sync0sync.ic b/storage/xtradb/include/sync0sync.ic deleted file mode 100644 index fb24c0ec244..00000000000 --- a/storage/xtradb/include/sync0sync.ic +++ /dev/null @@ -1,665 +0,0 @@ -/***************************************************************************** - -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2008, Google Inc. - -Portions of this file contain modifications contributed and copyrighted by -Google, Inc. Those modifications are gratefully acknowledged and are described -briefly in the InnoDB documentation. The contributions by Google are -incorporated with their permission, and subject to the conditions contained in -the file COPYING.Google. - -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/sync0sync.ic -Mutex, the basic synchronization primitive - -Created 9/5/1995 Heikki Tuuri -*******************************************************/ - -/******************************************************************//** -Sets the waiters field in a mutex. */ -UNIV_INTERN -void -mutex_set_waiters( -/*==============*/ - ib_mutex_t* mutex, /*!< in: mutex */ - ulint n); /*!< in: value to set */ -/******************************************************************//** -Reserves a mutex or a priority mutex for the current thread. If the mutex is -reserved, the function spins a preset time (controlled by SYNC_SPIN_ROUNDS) -waiting for the mutex before suspending the thread. */ -UNIV_INTERN -void -mutex_spin_wait( -/*============*/ - void* _mutex, /*!< in: pointer to mutex */ - bool high_priority, /*!< in: whether the mutex is a - priority mutex with high priority - specified */ - const char* file_name, /*!< in: file name where mutex - requested */ - ulint line); /*!< in: line where requested */ -#ifdef UNIV_SYNC_DEBUG -/******************************************************************//** -Sets the debug information for a reserved mutex. */ -UNIV_INTERN -void -mutex_set_debug_info( -/*=================*/ - ib_mutex_t* mutex, /*!< in: mutex */ - const char* file_name, /*!< in: file where requested */ - ulint line); /*!< in: line where requested */ -#endif /* UNIV_SYNC_DEBUG */ -/******************************************************************//** -Releases the threads waiting in the primary wait array for this mutex. */ -UNIV_INTERN -void -mutex_signal_object( -/*================*/ - ib_mutex_t* mutex); /*!< in: mutex */ - -/******************************************************************//** -Performs an atomic test-and-set instruction to the lock_word field of a -mutex. -@return the previous value of lock_word: 0 or 1 */ -UNIV_INLINE -lock_word_t -ib_mutex_test_and_set( -/*==================*/ - ib_mutex_t* mutex) /*!< in: mutex */ -{ -#if defined(HAVE_ATOMIC_BUILTINS) - return(os_atomic_test_and_set(&mutex->lock_word)); -#else - ibool ret; - - ret = os_fast_mutex_trylock_full_barrier(&(mutex->os_fast_mutex)); - - if (ret == 0) { - /* We check that os_fast_mutex_trylock does not leak - and allow race conditions */ - ut_a(mutex->lock_word == 0); - - mutex->lock_word = 1; - } - - return((byte) ret); -#endif /* HAVE_ATOMIC_BUILTINS */ -} - -/******************************************************************//** -Performs a reset instruction to the lock_word field of a mutex. This -instruction also serializes memory operations to the program order. */ -UNIV_INLINE -void -mutex_reset_lock_word( -/*==================*/ - ib_mutex_t* mutex) /*!< in: mutex */ -{ -#if defined(HAVE_ATOMIC_BUILTINS) - os_atomic_clear(&mutex->lock_word); -#else - mutex->lock_word = 0; - - os_fast_mutex_unlock(&(mutex->os_fast_mutex)); -#endif /* HAVE_ATOMIC_BUILTINS */ -} - -/******************************************************************//** -Gets the value of the lock word. */ -UNIV_INLINE -lock_word_t -mutex_get_lock_word( -/*================*/ - const ib_mutex_t* mutex) /*!< in: mutex */ -{ - ut_ad(mutex); - - return(mutex->lock_word); -} - -/******************************************************************//** -Gets the waiters field in a mutex. -@return value to set */ -UNIV_INLINE -ulint -mutex_get_waiters( -/*==============*/ - const ib_mutex_t* mutex) /*!< in: mutex */ -{ - const volatile ulint* ptr; /*!< declared volatile to ensure that - the value is read from memory */ - ut_ad(mutex); - - ptr = &(mutex->waiters); - - return(*ptr); /* Here we assume that the read of a single - word from memory is atomic */ -} - -/******************************************************************//** -NOTE! Use the corresponding macro mutex_exit(), not directly this function! -Unlocks a mutex owned by the current thread. */ -UNIV_INLINE -void -mutex_exit_func( -/*============*/ - ib_mutex_t* mutex) /*!< in: pointer to mutex */ -{ - ut_ad(mutex_own(mutex)); - - mutex->thread_id = (os_thread_id_t) ULINT_UNDEFINED; - -#ifdef UNIV_SYNC_DEBUG - sync_thread_reset_level(mutex); -#endif - mutex_reset_lock_word(mutex); - - /* A problem: we assume that mutex_reset_lock word - is a memory barrier, that is when we read the waiters - field next, the read must be serialized in memory - after the reset. A speculative processor might - perform the read first, which could leave a waiting - thread hanging indefinitely. - - Our current solution call every second - sync_arr_wake_threads_if_sema_free() - to wake up possible hanging threads if - they are missed in mutex_signal_object. */ - - /* We add a memory barrier to prevent reading of the - number of waiters before releasing the lock. */ - - os_mb; - - if (mutex_get_waiters(mutex) != 0) { - - mutex_signal_object(mutex); - } - -#ifdef UNIV_SYNC_PERF_STAT - mutex_exit_count++; -#endif -} - -/******************************************************************//** -NOTE! Use the corresponding macro mutex_exit(), not directly this function! -Unlocks a priority mutex owned by the current thread. */ -UNIV_INLINE -void -mutex_exit_func( -/*============*/ - ib_prio_mutex_t* mutex) /*!< in: pointer to mutex */ -{ - ut_ad(mutex_own(mutex)); - - mutex->base_mutex.thread_id = (os_thread_id_t) ULINT_UNDEFINED; - -#ifdef UNIV_SYNC_DEBUG - sync_thread_reset_level(&mutex->base_mutex); -#endif - mutex_reset_lock_word(&mutex->base_mutex); - - /* A problem: we assume that mutex_reset_lock word - is a memory barrier, that is when we read the waiters - field next, the read must be serialized in memory - after the reset. A speculative processor might - perform the read first, which could leave a waiting - thread hanging indefinitely. - - Our current solution call every second - sync_arr_wake_threads_if_sema_free() - to wake up possible hanging threads if - they are missed in mutex_signal_object. */ - - /* Wake up any high priority waiters first. */ - if (mutex->high_priority_waiters != 0) { - - os_event_set(&mutex->high_priority_event); - sync_array_object_signalled(); - - } else if (mutex_get_waiters(&mutex->base_mutex) != 0) { - - mutex_signal_object(&mutex->base_mutex); - } - -#ifdef UNIV_SYNC_PERF_STAT - mutex_exit_count++; -#endif - -} - - -/******************************************************************//** -Locks a mutex for the current thread. If the mutex is reserved, the function -spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting for the mutex -before suspending the thread. */ -UNIV_INLINE -void -mutex_enter_func( -/*=============*/ - ib_mutex_t* mutex, /*!< in: pointer to mutex */ - const char* file_name, /*!< in: file name where locked */ - ulint line) /*!< in: line where locked */ -{ - ut_ad(mutex_validate(mutex)); -#ifndef WITH_WSREP - /* this cannot be be granted when BF trx kills a trx in lock wait state */ - ut_ad(!mutex_own(mutex)); -#endif /* WITH_WSREP */ - - /* Note that we do not peek at the value of lock_word before trying - the atomic test_and_set; we could peek, and possibly save time. */ - - if (!ib_mutex_test_and_set(mutex)) { - mutex->thread_id = os_thread_get_curr_id(); -#ifdef UNIV_SYNC_DEBUG - mutex_set_debug_info(mutex, file_name, line); -#endif - if (srv_instrument_semaphores) { - mutex->file_name = file_name; - mutex->line = line; - } - - return; /* Succeeded! */ - } - - mutex_spin_wait(mutex, false, file_name, line); -} - -/******************************************************************//** -NOTE! Use the corresponding macro in the header file, not this function -directly. Locks a priority mutex for the current thread. If the mutex is -reserved the function spins a preset time (controlled by SYNC_SPIN_ROUNDS) -waiting for the mutex before suspending the thread. If the thread is suspended, -the priority argument value determines the relative order for its wake up. Any -IB_HIGH_PRIO waiters will be woken up before any IB_LOW_PRIO waiters. In case -of IB_DEFAULT_PRIO, the relative priority will be set according to -srv_current_thread_priority. */ -UNIV_INLINE -void -mutex_enter_func( -/*=============*/ - ib_prio_mutex_t* mutex, /*!< in: pointer to mutex */ - const char* file_name, /*!< in: file name where - locked */ - ulint line, /*!< in: line where locked */ - enum ib_sync_priority priority) - /*!<in: mutex acquisition - priority */ -{ - bool high_priority; - - ut_ad(mutex_validate(&mutex->base_mutex)); - ut_ad(!mutex_own(mutex)); - - /* Note that we do not peek at the value of lock_word before trying - the atomic test_and_set; we could peek, and possibly save time. */ - - if (!ib_mutex_test_and_set(&mutex->base_mutex)) { - mutex->base_mutex.thread_id = os_thread_get_curr_id(); -#ifdef UNIV_SYNC_DEBUG - mutex_set_debug_info(&mutex->base_mutex, file_name, line); -#endif - if(srv_instrument_semaphores) { - mutex->base_mutex.file_name = file_name; - mutex->base_mutex.line = line; - } - - return; /* Succeeded! */ - } - - if (UNIV_LIKELY(priority == IB_DEFAULT_PRIO)) { - high_priority = srv_current_thread_priority; - } else { - high_priority = (priority == IB_HIGH_PRIO); - } - mutex_spin_wait(mutex, high_priority, file_name, line); -} - -/********************************************************************//** -NOTE! Use the corresponding macro in the header file, not this function -directly. Tries to lock the mutex for the current thread. If the lock is not -acquired immediately, returns with return value 1. -@return 0 if succeed, 1 if not */ -UNIV_INLINE -ulint -mutex_enter_nowait_func( -/*====================*/ - ib_prio_mutex_t* mutex, /*!< in: pointer to mutex */ - const char* file_name, /*!< in: file name where mutex - requested */ - ulint line) /*!< in: line where - requested */ -{ - return mutex_enter_nowait_func(&mutex->base_mutex, file_name, line); -} - -#ifdef UNIV_PFS_MUTEX -/******************************************************************//** -NOTE! Please use the corresponding macro mutex_enter(), not directly -this function! -This is a performance schema instrumented wrapper function for -mutex_enter_func(). */ -UNIV_INLINE -void -pfs_mutex_enter_func( -/*=================*/ - ib_mutex_t* mutex, /*!< in: pointer to mutex */ - const char* file_name, /*!< in: file name where locked */ - ulint line) /*!< in: line where locked */ -{ - if (mutex->pfs_psi != NULL) { - PSI_mutex_locker* locker; - PSI_mutex_locker_state state; - - locker = PSI_MUTEX_CALL(start_mutex_wait)( - &state, mutex->pfs_psi, - PSI_MUTEX_LOCK, file_name, - static_cast<uint>(line)); - - mutex_enter_func(mutex, file_name, line); - - if (locker != NULL) { - PSI_MUTEX_CALL(end_mutex_wait)(locker, 0); - } - } else { - mutex_enter_func(mutex, file_name, line); - } -} - -/******************************************************************//** -NOTE! Please use the corresponding macro mutex_enter(), not directly -this function! -This is a performance schema instrumented wrapper function for -mutex_enter_func(). */ -UNIV_INLINE -void -pfs_mutex_enter_func( -/*=================*/ - ib_prio_mutex_t* mutex, /*!< in: pointer to mutex */ - const char* file_name, /*!< in: file name where - locked */ - ulint line, /*!< in: line where locked */ - enum ib_sync_priority priority) /*!<in: mutex acquisition - priority */ -{ - if (mutex->base_mutex.pfs_psi != NULL) { - PSI_mutex_locker* locker; - PSI_mutex_locker_state state; - - locker = PSI_MUTEX_CALL(start_mutex_wait)( - &state, mutex->base_mutex.pfs_psi, - PSI_MUTEX_LOCK, file_name, line); - - mutex_enter_func(mutex, file_name, line, priority); - - if (locker != NULL) { - PSI_MUTEX_CALL(end_mutex_wait)(locker, 0); - } - } else { - mutex_enter_func(mutex, file_name, line, priority); - } -} - -/********************************************************************//** -NOTE! Please use the corresponding macro mutex_enter_nowait(), not directly -this function! -This is a performance schema instrumented wrapper function for -mutex_enter_nowait_func. -@return 0 if succeed, 1 if not */ -UNIV_INLINE -ulint -pfs_mutex_enter_nowait_func( -/*========================*/ - ib_mutex_t* mutex, /*!< in: pointer to mutex */ - const char* file_name, /*!< in: file name where mutex - requested */ - ulint line) /*!< in: line where requested */ -{ - ulint ret; - - if (mutex->pfs_psi != NULL) { - PSI_mutex_locker* locker; - PSI_mutex_locker_state state; - - locker = PSI_MUTEX_CALL(start_mutex_wait)( - &state, mutex->pfs_psi, - PSI_MUTEX_TRYLOCK, file_name, - static_cast<uint>(line)); - - ret = mutex_enter_nowait_func(mutex, file_name, line); - - if (locker != NULL) { - PSI_MUTEX_CALL(end_mutex_wait)(locker, (int) ret); - } - } else { - ret = mutex_enter_nowait_func(mutex, file_name, line); - } - - return(ret); -} - -/********************************************************************//** -NOTE! Please use the corresponding macro mutex_enter_nowait(), not directly -this function! -This is a performance schema instrumented wrapper function for -mutex_enter_nowait_func. -@return 0 if succeed, 1 if not */ -UNIV_INLINE -ulint -pfs_mutex_enter_nowait_func( -/*========================*/ - ib_prio_mutex_t* mutex, /*!< in: pointer to mutex */ - const char* file_name, /*!< in: file name where mutex - requested */ - ulint line) /*!< in: line where - requested */ -{ - return pfs_mutex_enter_nowait_func(&mutex->base_mutex, file_name, - line); -} - -/******************************************************************//** -NOTE! Please use the corresponding macro mutex_exit(), not directly -this function! -A wrap function of mutex_exit_func() with performance schema instrumentation. -Unlocks a mutex owned by the current thread. */ -UNIV_INLINE -void -pfs_mutex_exit_func( -/*================*/ - ib_mutex_t* mutex) /*!< in: pointer to mutex */ -{ - if (mutex->pfs_psi != NULL) { - PSI_MUTEX_CALL(unlock_mutex)(mutex->pfs_psi); - } - - mutex_exit_func(mutex); -} - -/******************************************************************//** -NOTE! Please use the corresponding macro mutex_exit(), not directly -this function! -A wrap function of mutex_exit_func() with peformance schema instrumentation. -Unlocks a priority mutex owned by the current thread. */ -UNIV_INLINE -void -pfs_mutex_exit_func( -/*================*/ - ib_prio_mutex_t* mutex) /*!< in: pointer to mutex */ -{ - if (mutex->base_mutex.pfs_psi != NULL) { - PSI_MUTEX_CALL(unlock_mutex)(mutex->base_mutex.pfs_psi); - } - - mutex_exit_func(mutex); -} - - -/******************************************************************//** -NOTE! Please use the corresponding macro mutex_create(), not directly -this function! -A wrapper function for mutex_create_func(), registers the mutex -with performance schema if "UNIV_PFS_MUTEX" is defined when -creating the mutex */ -UNIV_INLINE -void -pfs_mutex_create_func( -/*==================*/ - mysql_pfs_key_t key, /*!< in: Performance Schema key */ - ib_mutex_t* mutex, /*!< in: pointer to memory */ -# ifdef UNIV_DEBUG -# ifdef UNIV_SYNC_DEBUG - ulint level, /*!< in: level */ -# endif /* UNIV_SYNC_DEBUG */ -# endif /* UNIV_DEBUG */ - const char* cfile_name, /*!< in: file name where created */ - ulint cline, /*!< in: file line where created */ - const char* cmutex_name) /*!< in: mutex name */ -{ - mutex->pfs_psi = PSI_MUTEX_CALL(init_mutex)(key, mutex); - - mutex_create_func(mutex, -# ifdef UNIV_DEBUG -# ifdef UNIV_SYNC_DEBUG - level, -# endif /* UNIV_SYNC_DEBUG */ -# endif /* UNIV_DEBUG */ - cfile_name, - cline, - cmutex_name); -} - -/******************************************************************//** -NOTE! Please use the corresponding macro mutex_create(), not directly -this function! -A wrapper function for mutex_create_func(), registers the mutex -with peformance schema if "UNIV_PFS_MUTEX" is defined when -creating the performance mutex */ -UNIV_INLINE -void -pfs_mutex_create_func( -/*==================*/ - PSI_mutex_key key, /*!< in: Performance Schema - key */ - ib_prio_mutex_t* mutex, /*!< in: pointer to memory */ -# ifdef UNIV_DEBUG -# ifdef UNIV_SYNC_DEBUG - ulint level, /*!< in: level */ -# endif /* UNIV_SYNC_DEBUG */ -# endif /* UNIV_DEBUG */ - const char* cfile_name, /*!< in: file name where - created */ - ulint cline, /*!< in: file line where - created */ - const char* cmutex_name) -{ - mutex->base_mutex.pfs_psi = PSI_MUTEX_CALL(init_mutex)(key, mutex); - - mutex_create_func(mutex, -# ifdef UNIV_DEBUG -# ifdef UNIV_SYNC_DEBUG - level, -# endif /* UNIV_SYNC_DEBUG */ -# endif /* UNIV_DEBUG */ - cfile_name, - cline, - cmutex_name); -} - - -/******************************************************************//** -NOTE! Please use the corresponding macro mutex_free(), not directly -this function! -Wrapper function for mutex_free_func(). Also destroys the performance -schema probes when freeing the mutex */ -UNIV_INLINE -void -pfs_mutex_free_func( -/*================*/ - ib_mutex_t* mutex) /*!< in: mutex */ -{ - if (mutex->pfs_psi != NULL) { - PSI_MUTEX_CALL(destroy_mutex)(mutex->pfs_psi); - mutex->pfs_psi = NULL; - } - - mutex_free_func(mutex); -} - -/******************************************************************//** -NOTE! Please use the corresponding macro mutex_free(), not directly -this function! -Wrapper function for mutex_free_func(). Also destroys the performance -schema probes when freeing the priority mutex */ -UNIV_INLINE -void -pfs_mutex_free_func( -/*================*/ - ib_prio_mutex_t* mutex) /*!< in: mutex */ -{ - if (mutex->base_mutex.pfs_psi != NULL) { - PSI_MUTEX_CALL(destroy_mutex)(mutex->base_mutex.pfs_psi); - mutex->base_mutex.pfs_psi = NULL; - } - - mutex_free_func(mutex); -} - - -#endif /* UNIV_PFS_MUTEX */ - -#ifndef HAVE_ATOMIC_BUILTINS -/**********************************************************//** -Function that uses a mutex to decrement a variable atomically */ -UNIV_INLINE -void -os_atomic_dec_ulint_func( -/*=====================*/ - ib_mutex_t* mutex, /*!< in: mutex guarding the dec */ - volatile ulint* var, /*!< in/out: variable to decrement */ - ulint delta) /*!< in: delta to decrement */ -{ - mutex_enter(mutex); - - /* I don't think we will encounter a situation where - this check will not be required. */ - ut_ad(*var >= delta); - - *var -= delta; - - mutex_exit(mutex); -} - -/**********************************************************//** -Function that uses a mutex to increment a variable atomically */ -UNIV_INLINE -void -os_atomic_inc_ulint_func( -/*=====================*/ - ib_mutex_t* mutex, /*!< in: mutex guarding the increment */ - volatile ulint* var, /*!< in/out: variable to increment */ - ulint delta) /*!< in: delta to increment */ -{ - mutex_enter(mutex); - - *var += delta; - - mutex_exit(mutex); -} -#endif /* !HAVE_ATOMIC_BUILTINS */ |