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