diff options
Diffstat (limited to 'storage/xtradb/include/sync0sync.h')
-rw-r--r-- | storage/xtradb/include/sync0sync.h | 243 |
1 files changed, 126 insertions, 117 deletions
diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h index dccfc020681..966bcced722 100644 --- a/storage/xtradb/include/sync0sync.h +++ b/storage/xtradb/include/sync0sync.h @@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA *****************************************************************************/ -/****************************************************** +/**************************************************//** +@file include/sync0sync.h Mutex, the basic synchronization primitive Created 9/5/1995 Heikki Tuuri @@ -40,23 +41,30 @@ Created 9/5/1995 Heikki Tuuri #include "os0sync.h" #include "sync0arr.h" -#ifndef UNIV_HOTBACKUP +#if defined(UNIV_DEBUG) && !defined(UNIV_HOTBACKUP) extern my_bool timed_mutexes; -#endif /* UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ -/********************************************************************** +#ifdef HAVE_WINDOWS_ATOMICS +typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates + on LONG variable */ +#else +typedef byte lock_word_t; +#endif + +/******************************************************************//** Initializes the synchronization data structures. */ UNIV_INTERN void sync_init(void); /*===========*/ -/********************************************************************** +/******************************************************************//** Frees the resources in synchronization data structures. */ UNIV_INTERN void sync_close(void); /*===========*/ -/********************************************************************** +/******************************************************************//** Creates, or rather, initializes a mutex object to a specified memory location (which must be appropriately aligned). The mutex is initialized in the reset state. Explicit freeing of the mutex with mutex_free is @@ -75,7 +83,7 @@ necessary only if the memory block containing it is freed. */ mutex_create_func((M), __FILE__, __LINE__) #endif -/********************************************************************** +/******************************************************************//** Creates, or rather, initializes a mutex object in a specified memory location (which must be appropriately aligned). The mutex is initialized in the reset state. Explicit freeing of the mutex with mutex_free is @@ -84,19 +92,19 @@ UNIV_INTERN void mutex_create_func( /*==============*/ - mutex_t* mutex, /* in: pointer to memory */ + mutex_t* mutex, /*!< in: pointer to memory */ #ifdef UNIV_DEBUG - const char* cmutex_name, /* in: mutex name */ + const char* cmutex_name, /*!< in: mutex name */ # ifdef UNIV_SYNC_DEBUG - ulint level, /* in: level */ + 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* cfile_name, /*!< in: file name where created */ + ulint cline); /*!< in: file line where created */ #undef mutex_free /* Fix for MacOS X */ -/********************************************************************** +/******************************************************************//** Calling this function is obligatory only if the memory buffer containing the mutex is freed. Removes a mutex object from the mutex list. The mutex is checked to be in the reset state. */ @@ -104,20 +112,20 @@ UNIV_INTERN void mutex_free( /*=======*/ - mutex_t* mutex); /* in: mutex */ -/****************************************************************** + mutex_t* mutex); /*!< in: mutex */ +/**************************************************************//** NOTE! The following macro should be used in mutex locking, not the corresponding function. */ #define mutex_enter(M) mutex_enter_func((M), __FILE__, __LINE__) -/****************************************************************** +/**************************************************************//** NOTE! The following macro should be used in mutex locking, not the corresponding function. */ /* NOTE! currently same as mutex_enter! */ #define mutex_enter_fast(M) mutex_enter_func((M), __FILE__, __LINE__) -/********************************************************************** +/******************************************************************//** NOTE! Use the corresponding macro in the header file, not this function directly. Locks a mutex for the current thread. If the mutex is reserved the function spins a preset time (controlled by SYNC_SPIN_ROUNDS) waiting @@ -126,78 +134,82 @@ UNIV_INLINE void mutex_enter_func( /*=============*/ - mutex_t* mutex, /* in: pointer to mutex */ - const char* file_name, /* in: file name where locked */ - ulint line); /* in: line where locked */ -/****************************************************************** + mutex_t* mutex, /*!< in: pointer to mutex */ + const char* file_name, /*!< in: file name where locked */ + ulint line); /*!< in: line where locked */ +/**************************************************************//** NOTE! The following macro should be used in mutex locking, not the corresponding function. */ #define mutex_enter_nowait(M) \ mutex_enter_nowait_func((M), __FILE__, __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. */ +acquired immediately, returns with return value 1. +@return 0 if succeed, 1 if not */ UNIV_INTERN ulint mutex_enter_nowait_func( /*====================*/ - /* out: 0 if succeed, 1 if not */ - mutex_t* mutex, /* in: pointer to mutex */ - const char* file_name, /* in: file name where mutex + mutex_t* mutex, /*!< in: pointer to mutex */ + const char* file_name, /*!< in: file name where mutex requested */ - ulint line); /* in: line where requested */ -/********************************************************************** + ulint line); /*!< in: line where requested */ +/******************************************************************//** Unlocks a mutex owned by the current thread. */ UNIV_INLINE void mutex_exit( /*=======*/ - mutex_t* mutex); /* in: pointer to mutex */ -/********************************************************************** + mutex_t* mutex); /*!< in: pointer to mutex */ +#ifdef UNIV_SYNC_DEBUG +/******************************************************************//** Returns TRUE if no mutex or rw-lock is currently locked. -Works only in the debug version. */ +Works only in the debug version. +@return TRUE if no mutexes and rw-locks reserved */ UNIV_INTERN ibool sync_all_freed(void); /*================*/ +#endif /* UNIV_SYNC_DEBUG */ /*##################################################################### FUNCTION PROTOTYPES FOR DEBUGGING */ -/*********************************************************************** +/*******************************************************************//** Prints wait info of the sync system. */ UNIV_INTERN void sync_print_wait_info( /*=================*/ - FILE* file); /* in: file where to print */ -/*********************************************************************** + FILE* file); /*!< in: file where to print */ +/*******************************************************************//** Prints info of the sync system. */ UNIV_INTERN void sync_print( /*=======*/ - FILE* file); /* in: file where to print */ + FILE* file); /*!< in: file where to print */ #ifdef UNIV_DEBUG -/********************************************************************** -Checks that the mutex has been initialized. */ +/******************************************************************//** +Checks that the mutex has been initialized. +@return TRUE */ UNIV_INTERN ibool mutex_validate( /*===========*/ - const mutex_t* mutex); -/********************************************************************** + const mutex_t* mutex); /*!< in: mutex */ +/******************************************************************//** Checks that the current thread owns the mutex. Works only -in the debug version. */ +in the debug version. +@return TRUE if owns */ UNIV_INTERN ibool mutex_own( /*======*/ - /* out: TRUE if owns */ - const mutex_t* mutex); /* in: mutex */ + const mutex_t* mutex); /*!< in: mutex */ #endif /* UNIV_DEBUG */ #ifdef UNIV_SYNC_DEBUG -/********************************************************************** +/******************************************************************//** Adds a latch and its level in the thread level array. Allocates the memory for the array if called first time for this OS thread. Makes the checks against other latch levels stored in the array for this thread. */ @@ -205,75 +217,74 @@ UNIV_INTERN void sync_thread_add_level( /*==================*/ - void* latch, /* in: pointer to a mutex or an rw-lock */ - ulint level); /* in: level in the latching order; if + void* latch, /*!< in: pointer to a mutex or an rw-lock */ + ulint level); /*!< in: level in the latching order; if SYNC_LEVEL_VARYING, nothing is done */ -/********************************************************************** -Removes a latch from the thread level array if it is found there. */ +/******************************************************************//** +Removes a latch from the thread level array if it is found there. +@return TRUE if found in the array; it is no error if the latch is +not found, as we presently are not able to determine the level for +every latch reservation the program does */ UNIV_INTERN ibool sync_thread_reset_level( /*====================*/ - /* out: TRUE if found from the array; it is no error - if the latch is not found, as we presently are not - able to determine the level for every latch - reservation the program does */ - void* latch); /* in: pointer to a mutex or an rw-lock */ -/********************************************************************** -Checks that the level array for the current thread is empty. */ + void* latch); /*!< in: pointer to a mutex or an rw-lock */ +/******************************************************************//** +Checks that the level array for the current thread is empty. +@return TRUE if empty */ UNIV_INTERN ibool sync_thread_levels_empty(void); /*==========================*/ - /* out: TRUE if empty */ -/********************************************************************** -Checks that the level array for the current thread is empty. */ +/******************************************************************//** +Checks that the level array for the current thread is empty. +@return TRUE if empty except the exceptions specified below */ UNIV_INTERN ibool sync_thread_levels_empty_gen( /*=========================*/ - /* out: TRUE if empty except the - exceptions specified below */ - ibool dict_mutex_allowed); /* in: TRUE if dictionary mutex is + ibool dict_mutex_allowed); /*!< in: TRUE if dictionary mutex is allowed to be owned by the thread, also purge_is_running mutex is allowed */ -/********************************************************************** +/******************************************************************//** Gets the debug information for a reserved mutex. */ UNIV_INTERN void mutex_get_debug_info( /*=================*/ - mutex_t* mutex, /* in: mutex */ - const char** file_name, /* out: file where requested */ - ulint* line, /* out: line where requested */ - os_thread_id_t* thread_id); /* out: id of the thread which owns + mutex_t* mutex, /*!< in: mutex */ + const char** file_name, /*!< out: file where requested */ + ulint* line, /*!< out: line where requested */ + os_thread_id_t* thread_id); /*!< out: id of the thread which owns the mutex */ -/********************************************************************** -Counts currently reserved mutexes. Works only in the debug version. */ +/******************************************************************//** +Counts currently reserved mutexes. Works only in the debug version. +@return number of reserved mutexes */ UNIV_INTERN ulint mutex_n_reserved(void); /*==================*/ #endif /* UNIV_SYNC_DEBUG */ -/********************************************************************** +/******************************************************************//** NOT to be used outside this module except in debugging! Gets the value of the lock word. */ UNIV_INLINE -byte +lock_word_t mutex_get_lock_word( /*================*/ - const mutex_t* mutex); /* in: mutex */ + const mutex_t* mutex); /*!< in: mutex */ #ifdef UNIV_SYNC_DEBUG -/********************************************************************** +/******************************************************************//** NOT to be used outside this module except in debugging! Gets the waiters -field in a mutex. */ +field in a mutex. +@return value to set */ UNIV_INLINE ulint mutex_get_waiters( /*==============*/ - /* out: value to set */ - const mutex_t* mutex); /* in: mutex */ + const mutex_t* mutex); /*!< in: mutex */ #endif /* UNIV_SYNC_DEBUG */ /* @@ -490,81 +501,79 @@ or row lock! */ Do not use its fields directly! The structure used in the spin lock implementation of a mutual exclusion semaphore. */ +/** InnoDB mutex */ struct mutex_struct { - os_event_t event; /* Used by sync0arr.c for the wait queue */ - byte lock_word; /* This byte is the target of the atomic - test-and-set instruction in Win32 and - x86 32/64 with GCC 4.1.0 or later version */ -#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) -#elif defined(HAVE_GCC_ATOMIC_BUILTINS) -#else + os_event_t event; /*!< Used by sync0arr.c for the wait queue */ + volatile lock_word_t lock_word; /*!< lock_word is the target + of the atomic test-and-set instruction when + atomic operations are enabled. */ + +#if !defined(HAVE_ATOMIC_BUILTINS) os_fast_mutex_t - os_fast_mutex; /* In other systems we use this OS mutex - in place of lock_word */ + os_fast_mutex; /*!< We use this OS mutex in place of lock_word + when atomic operations are not enabled */ #endif - ulint waiters; /* This ulint is set to 1 if there are (or + ulint waiters; /*!< This ulint is set to 1 if there are (or may be) threads waiting in the global wait array for this mutex to be released. Otherwise, this is 0. */ - UT_LIST_NODE_T(mutex_t) list; /* All allocated mutexes are put into + UT_LIST_NODE_T(mutex_t) list; /*!< All allocated mutexes are put into a list. Pointers to the next and prev. */ #ifdef UNIV_SYNC_DEBUG - const char* file_name; /* File where the mutex was locked */ - ulint line; /* Line where the mutex was locked */ - ulint level; /* Level in the global latching order */ + const char* file_name; /*!< File where the mutex was locked */ + ulint line; /*!< Line where the mutex was locked */ + ulint level; /*!< Level in the global latching order */ #endif /* UNIV_SYNC_DEBUG */ - const char* cfile_name;/* File name where mutex created */ - ulint cline; /* Line where created */ + const char* cfile_name;/*!< File name where mutex created */ + ulint cline; /*!< Line where created */ #ifdef UNIV_DEBUG - os_thread_id_t thread_id; /* The thread id of the thread + os_thread_id_t thread_id; /*!< The thread id of the thread which locked the mutex. */ - ulint magic_n; + ulint magic_n; /*!< MUTEX_MAGIC_N */ +/** Value of mutex_struct::magic_n */ # define MUTEX_MAGIC_N (ulint)979585 #endif /* UNIV_DEBUG */ -#ifndef UNIV_HOTBACKUP - ulong count_os_wait; /* count of os_wait */ -# ifdef UNIV_DEBUG - ulong count_using; /* count of times mutex used */ - ulong count_spin_loop; /* count of spin loops */ - ulong count_spin_rounds; /* count of spin rounds */ - ulong count_os_yield; /* count of os_wait */ - ulonglong lspent_time; /* mutex os_wait timer msec */ - ulonglong lmax_spent_time; /* mutex os_wait timer msec */ - const char* cmutex_name;/* mutex name */ - ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */ -# endif /* UNIV_DEBUG */ -#endif /* !UNIV_HOTBACKUP */ + ulong count_os_wait; /*!< count of os_wait */ +#ifdef UNIV_DEBUG + ulong count_using; /*!< count of times mutex used */ + ulong count_spin_loop; /*!< count of spin loops */ + ulong count_spin_rounds;/*!< count of spin rounds */ + ulong count_os_yield; /*!< count of os_wait */ + ulonglong lspent_time; /*!< mutex os_wait timer msec */ + ulonglong lmax_spent_time;/*!< mutex os_wait timer msec */ + const char* cmutex_name; /*!< mutex name */ + ulint mutex_type; /*!< 0=usual mutex, 1=rw_lock mutex */ +#endif /* UNIV_DEBUG */ }; -/* The global array of wait cells for implementation of the databases own -mutexes and read-write locks. Appears here for debugging purposes only! */ +/** The global array of wait cells for implementation of the databases own +mutexes and read-write locks. */ +extern sync_array_t* sync_primary_wait_array;/* Appears here for + debugging purposes only! */ -extern sync_array_t* sync_primary_wait_array; - -/* Constant determining how long spin wait is continued before suspending +/** Constant determining how long spin wait is continued before suspending the thread. A value 600 rounds on a 1995 100 MHz Pentium seems to correspond to 20 microseconds. */ #define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds -/* The number of system calls made in this module. Intended for performance -monitoring. */ - +/** The number of mutex_exit calls. Intended for performance monitoring. */ extern ib_int64_t mutex_exit_count; #ifdef UNIV_SYNC_DEBUG -/* Latching order checks start when this is set TRUE */ +/** Latching order checks start when this is set TRUE */ extern ibool sync_order_checks_on; #endif /* UNIV_SYNC_DEBUG */ -/* This variable is set to TRUE when sync_init is called */ +/** This variable is set to TRUE when sync_init is called */ extern ibool sync_initialized; -/* Global list of database mutexes (not OS mutexes) created. */ +/** Global list of database mutexes (not OS mutexes) created. */ typedef UT_LIST_BASE_NODE_T(mutex_t) ut_list_base_node_t; +/** Global list of database mutexes (not OS mutexes) created. */ extern ut_list_base_node_t mutex_list; -/* Mutex protecting the mutex_list variable */ +/** Mutex protecting the mutex_list variable */ extern mutex_t mutex_list_mutex; |