164
165
/* Number of spin waits on mutexes: for performance monitoring */
166
/* round=one iteration of a spin loop */
167
UNIV_INTERN ib_int64_t mutex_spin_round_count = 0;
168
UNIV_INTERN ib_int64_t mutex_spin_wait_count = 0;
169
UNIV_INTERN ib_int64_t mutex_os_wait_count = 0;
167
/** The number of iterations in the mutex_spin_wait() spin loop.
168
Intended for performance monitoring. */
169
static ib_int64_t mutex_spin_round_count = 0;
170
/** The number of mutex_spin_wait() calls. Intended for
171
performance monitoring. */
172
static ib_int64_t mutex_spin_wait_count = 0;
173
/** The number of OS waits in mutex_spin_wait(). Intended for
174
performance monitoring. */
175
static ib_int64_t mutex_os_wait_count = 0;
176
/** The number of mutex_exit() calls. Intended for performance
170
178
UNIV_INTERN ib_int64_t mutex_exit_count = 0;
172
/* The global array of wait cells for implementation of the database's own
180
/** The global array of wait cells for implementation of the database's own
173
181
mutexes and read-write locks */
174
182
UNIV_INTERN sync_array_t* sync_primary_wait_array;
176
/* This variable is set to TRUE when sync_init is called */
184
/** This variable is set to TRUE when sync_init is called */
177
185
UNIV_INTERN ibool sync_initialized = FALSE;
187
/** An acquired mutex or rw-lock and its level in the latching order */
180
188
typedef struct sync_level_struct sync_level_t;
189
/** Mutexes or rw-locks held by a thread */
181
190
typedef struct sync_thread_struct sync_thread_t;
183
192
#ifdef UNIV_SYNC_DEBUG
184
/* The latch levels currently owned by threads are stored in this data
193
/** The latch levels currently owned by threads are stored in this data
185
194
structure; the size of this array is OS_THREAD_MAX_N */
187
196
UNIV_INTERN sync_thread_t* sync_thread_level_arrays;
189
/* Mutex protecting sync_thread_level_arrays */
198
/** Mutex protecting sync_thread_level_arrays */
190
199
UNIV_INTERN mutex_t sync_thread_mutex;
191
200
#endif /* UNIV_SYNC_DEBUG */
193
/* Global list of database mutexes (not OS mutexes) created. */
202
/** Global list of database mutexes (not OS mutexes) created. */
194
203
UNIV_INTERN ut_list_base_node_t mutex_list;
196
/* Mutex protecting the mutex_list variable */
205
/** Mutex protecting the mutex_list variable */
197
206
UNIV_INTERN mutex_t mutex_list_mutex;
199
208
#ifdef UNIV_SYNC_DEBUG
200
/* Latching order checks start when this is set TRUE */
209
/** Latching order checks start when this is set TRUE */
201
210
UNIV_INTERN ibool sync_order_checks_on = FALSE;
202
211
#endif /* UNIV_SYNC_DEBUG */
213
/** Mutexes or rw-locks held by a thread */
204
214
struct sync_thread_struct{
205
os_thread_id_t id; /* OS thread id */
206
sync_level_t* levels; /* level array for this thread; if this is NULL
207
this slot is unused */
215
os_thread_id_t id; /*!< OS thread id */
216
sync_level_t* levels; /*!< level array for this thread; if
217
this is NULL this slot is unused */
210
/* Number of slots reserved for each OS thread in the sync level array */
220
/** Number of slots reserved for each OS thread in the sync level array */
211
221
#define SYNC_THREAD_N_LEVELS 10000
223
/** An acquired mutex or rw-lock and its level in the latching order */
213
224
struct sync_level_struct{
214
void* latch; /* pointer to a mutex or an rw-lock; NULL means that
225
void* latch; /*!< pointer to a mutex or an rw-lock; NULL means that
215
226
the slot is empty */
216
ulint level; /* level of the latch in the latching order */
227
ulint level; /*!< level of the latch in the latching order */
219
/**********************************************************************
230
/******************************************************************//**
220
231
Creates, or rather, initializes a mutex object in a specified memory
221
232
location (which must be appropriately aligned). The mutex is initialized
222
233
in the reset state. Explicit freeing of the mutex with mutex_free is
226
237
mutex_create_func(
227
238
/*==============*/
228
mutex_t* mutex, /* in: pointer to memory */
239
mutex_t* mutex, /*!< in: pointer to memory */
229
240
#ifdef UNIV_DEBUG
230
const char* cmutex_name, /* in: mutex name */
241
const char* cmutex_name, /*!< in: mutex name */
231
242
# ifdef UNIV_SYNC_DEBUG
232
ulint level, /* in: level */
243
ulint level, /*!< in: level */
233
244
# endif /* UNIV_SYNC_DEBUG */
234
245
#endif /* UNIV_DEBUG */
235
const char* cfile_name, /* in: file name where created */
236
ulint cline) /* in: file line where created */
246
const char* cfile_name, /*!< in: file name where created */
247
ulint cline) /*!< in: file line where created */
238
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
239
mutex_reset_lock_word(mutex);
240
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
249
#if defined(HAVE_ATOMIC_BUILTINS)
241
250
mutex_reset_lock_word(mutex);
243
252
os_fast_mutex_init(&(mutex->os_fast_mutex));
342
347
#endif /* UNIV_DEBUG */
345
/************************************************************************
350
/********************************************************************//**
346
351
NOTE! Use the corresponding macro in the header file, not this function
347
352
directly. Tries to lock the mutex for the current thread. If the lock is not
348
acquired immediately, returns with return value 1. */
353
acquired immediately, returns with return value 1.
354
@return 0 if succeed, 1 if not */
351
357
mutex_enter_nowait_func(
352
358
/*====================*/
353
/* out: 0 if succeed, 1 if not */
354
mutex_t* mutex, /* in: pointer to mutex */
359
mutex_t* mutex, /*!< in: pointer to mutex */
355
360
const char* file_name __attribute__((unused)),
356
/* in: file name where mutex
361
/*!< in: file name where mutex
358
363
ulint line __attribute__((unused)))
359
/* in: line where requested */
364
/*!< in: line where requested */
361
366
ut_ad(mutex_validate(mutex));
435
mutex_t* mutex, /* in: pointer to mutex */
436
const char* file_name, /* in: file name where mutex
441
mutex_t* mutex, /*!< in: pointer to mutex */
442
const char* file_name, /*!< in: file name where mutex
438
ulint line) /* in: line where requested */
444
ulint line) /*!< in: line where requested */
440
446
ulint index; /* index of the reserved wait cell */
441
447
ulint i; /* spin round count */
442
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
443
449
ib_int64_t lstart_time = 0, lfinish_time; /* for timing os_wait */
444
450
ulint ltime_diff;
447
453
uint timer_started = 0;
448
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
454
#endif /* UNIV_DEBUG */
451
457
/* This update is not thread safe, but we don't mind if the count
630
633
#ifdef UNIV_SYNC_DEBUG
631
/**********************************************************************
634
/******************************************************************//**
632
635
Sets the debug information for a reserved mutex. */
635
638
mutex_set_debug_info(
636
639
/*=================*/
637
mutex_t* mutex, /* in: mutex */
638
const char* file_name, /* in: file where requested */
639
ulint line) /* in: line where requested */
640
mutex_t* mutex, /*!< in: mutex */
641
const char* file_name, /*!< in: file where requested */
642
ulint line) /*!< in: line where requested */
642
645
ut_ad(file_name);
647
650
mutex->line = line;
650
/**********************************************************************
653
/******************************************************************//**
651
654
Gets the debug information for a reserved mutex. */
654
657
mutex_get_debug_info(
655
658
/*=================*/
656
mutex_t* mutex, /* in: mutex */
657
const char** file_name, /* out: file where requested */
658
ulint* line, /* out: line where requested */
659
os_thread_id_t* thread_id) /* out: id of the thread which owns
659
mutex_t* mutex, /*!< in: mutex */
660
const char** file_name, /*!< out: file where requested */
661
ulint* line, /*!< out: line where requested */
662
os_thread_id_t* thread_id) /*!< out: id of the thread which owns
751
756
return(mutex_n_reserved() + rw_lock_n_locked() == 0);
754
/**********************************************************************
755
Gets the value in the nth slot in the thread level arrays. */
759
/******************************************************************//**
760
Gets the value in the nth slot in the thread level arrays.
761
@return pointer to thread slot */
758
764
sync_thread_level_arrays_get_nth(
759
765
/*=============================*/
760
/* out: pointer to thread slot */
761
ulint n) /* in: slot number */
766
ulint n) /*!< in: slot number */
763
768
ut_ad(n < OS_THREAD_MAX_N);
765
770
return(sync_thread_level_arrays + n);
768
/**********************************************************************
769
Looks for the thread slot for the calling thread. */
773
/******************************************************************//**
774
Looks for the thread slot for the calling thread.
775
@return pointer to thread slot, NULL if not found */
772
778
sync_thread_level_arrays_find_slot(void)
773
779
/*====================================*/
774
/* out: pointer to thread slot, NULL if not found */
777
782
sync_thread_t* slot;
821
/**********************************************************************
822
Gets the value in the nth slot in the thread level array. */
826
/******************************************************************//**
827
Gets the value in the nth slot in the thread level array.
828
@return pointer to level slot */
825
831
sync_thread_levels_get_nth(
826
832
/*=======================*/
827
/* out: pointer to level slot */
828
sync_level_t* arr, /* in: pointer to level array for an OS
833
sync_level_t* arr, /*!< in: pointer to level array for an OS
830
ulint n) /* in: slot number */
835
ulint n) /*!< in: slot number */
832
837
ut_ad(n < SYNC_THREAD_N_LEVELS);
837
/**********************************************************************
842
/******************************************************************//**
838
843
Checks if all the level values stored in the level array are greater than
845
@return TRUE if all greater */
842
848
sync_thread_levels_g(
843
849
/*=================*/
844
/* out: TRUE if all greater */
845
sync_level_t* arr, /* in: pointer to level array for an OS
850
sync_level_t* arr, /*!< in: pointer to level array for an OS
847
ulint limit) /* in: level limit */
852
ulint limit) /*!< in: level limit */
849
854
sync_level_t* slot;
908
/**********************************************************************
909
Checks if the level value is stored in the level array. */
913
/******************************************************************//**
914
Checks if the level value is stored in the level array.
915
@return TRUE if stored */
912
918
sync_thread_levels_contain(
913
919
/*=======================*/
914
/* out: TRUE if stored */
915
sync_level_t* arr, /* in: pointer to level array for an OS
920
sync_level_t* arr, /*!< in: pointer to level array for an OS
917
ulint level) /* in: level */
922
ulint level) /*!< in: level */
919
924
sync_level_t* slot;
937
/**********************************************************************
938
Checks that the level array for the current thread is empty. */
942
/******************************************************************//**
943
Checks that the level array for the current thread is empty.
944
@return TRUE if empty except the exceptions specified below */
941
947
sync_thread_levels_empty_gen(
942
948
/*=========================*/
943
/* out: TRUE if empty except the
944
exceptions specified below */
945
ibool dict_mutex_allowed) /* in: TRUE if dictionary mutex is
949
ibool dict_mutex_allowed) /*!< in: TRUE if dictionary mutex is
946
950
allowed to be owned by the thread,
947
951
also purge_is_running mutex is
994
/**********************************************************************
995
Checks that the level array for the current thread is empty. */
998
/******************************************************************//**
999
Checks that the level array for the current thread is empty.
1000
@return TRUE if empty */
998
1003
sync_thread_levels_empty(void)
999
1004
/*==========================*/
1000
/* out: TRUE if empty */
1002
1006
return(sync_thread_levels_empty_gen(FALSE));
1005
/**********************************************************************
1009
/******************************************************************//**
1006
1010
Adds a latch and its level in the thread level array. Allocates the memory
1007
1011
for the array if called first time for this OS thread. Makes the checks
1008
1012
against other latch levels stored in the array for this thread. */
1107
1111
/* Either the thread must own the buffer pool mutex
1108
1112
(buf_pool_mutex), or it is allowed to latch only ONE
1109
1113
buffer block (block->mutex or buf_pool_zip_mutex). */
1110
ut_a((sync_thread_levels_contain(array, SYNC_BUF_POOL)
1111
&& sync_thread_levels_g(array, SYNC_BUF_BLOCK - 1))
1112
|| sync_thread_levels_g(array, SYNC_BUF_BLOCK));
1114
if (!sync_thread_levels_g(array, level)) {
1115
ut_a(sync_thread_levels_g(array, level - 1));
1116
ut_a(sync_thread_levels_contain(array, SYNC_BUF_POOL));
1114
1119
case SYNC_REC_LOCK:
1115
1120
ut_a((sync_thread_levels_contain(array, SYNC_KERNEL)
1201
1206
mutex_exit(&sync_thread_mutex);
1204
/**********************************************************************
1205
Removes a latch from the thread level array if it is found there. */
1209
/******************************************************************//**
1210
Removes a latch from the thread level array if it is found there.
1211
@return TRUE if found in the array; it is no error if the latch is
1212
not found, as we presently are not able to determine the level for
1213
every latch reservation the program does */
1208
1216
sync_thread_reset_level(
1209
1217
/*====================*/
1210
/* out: TRUE if found from the array; it is an error
1211
if the latch is not found */
1212
void* latch) /* in: pointer to a mutex or an rw-lock */
1218
void* latch) /*!< in: pointer to a mutex or an rw-lock */
1214
1220
sync_level_t* array;
1215
1221
sync_level_t* slot;