1
/******************************************************
2
The wait array used in synchronization primitives
6
Created 9/5/1995 Heikki Tuuri
7
*******************************************************/
11
#include "sync0arr.ic"
14
#include "sync0sync.h"
24
The wait array consists of cells each of which has an
25
an operating system event object created for it. The threads
26
waiting for a mutex, for example, can reserve a cell
27
in the array and suspend themselves to wait for the event
28
to become signaled. When using the wait array, remember to make
29
sure that some thread holding the synchronization object
30
will eventually know that there is a waiter in the array and
31
signal the object, to prevent infinite wait.
32
Why we chose to implement a wait array? First, to make
33
mutexes fast, we had to code our own implementation of them,
34
which only in usually uncommon cases resorts to using
35
slow operating system primitives. Then we had the choice of
36
assigning a unique OS event for each mutex, which would
37
be simpler, or using a global wait array. In some operating systems,
38
the global wait array solution is more efficient and flexible,
39
because we can do with a very small number of OS events,
40
say 200. In NT 3.51, allocating events seems to be a quadratic
41
algorithm, because 10 000 events are created fast, but
42
100 000 events takes a couple of minutes to create.
45
/* A cell where an individual thread may wait suspended
46
until a resource is released. The suspending is implemented
47
using an operating system event semaphore. */
48
struct sync_cell_struct {
49
/* State of the cell. SC_WAKING_UP means
50
sync_array_struct->n_reserved has been decremented, but the thread
51
in this cell has not waken up yet. When it does, it will set the
52
state to SC_FREE. Note that this is done without the protection of
54
enum { SC_FREE, SC_RESERVED, SC_WAKING_UP } state;
56
void* wait_object; /* pointer to the object the
57
thread is waiting for; this is not
58
reseted to NULL when a cell is
61
mutex_t* old_wait_mutex; /* the latest wait mutex in cell */
62
rw_lock_t* old_wait_rw_lock;/* the latest wait rw-lock in cell */
63
ulint request_type; /* lock type requested on the
65
const char* file; /* in debug version file where
67
ulint line; /* in debug version line where
69
os_thread_id_t thread; /* thread id of this waiting
71
ibool waiting; /* TRUE if the thread has already
72
called sync_array_event_wait
74
ibool event_set; /* TRUE if the event is set */
75
os_event_t event; /* operating system event
77
time_t reservation_time;/* time when the thread reserved
81
struct sync_array_struct {
82
ulint n_reserved; /* number of currently reserved
83
cells in the wait array */
84
ulint n_cells; /* number of cells in the
86
sync_cell_t* array; /* pointer to wait array */
87
ulint protection; /* this flag tells which
88
mutex protects the data */
89
mutex_t mutex; /* possible database mutex
90
protecting this data structure */
91
os_mutex_t os_mutex; /* Possible operating system mutex
92
protecting the data structure.
93
As this data structure is used in
94
constructing the database mutex,
95
to prevent infinite recursion
96
in implementation, we fall back to
98
ulint sg_count; /* count of how many times an
99
object has been signalled */
100
ulint res_count; /* count of cell reservations
101
since creation of the array */
104
#ifdef UNIV_SYNC_DEBUG
105
/**********************************************************************
106
This function is called only in the debug version. Detects a deadlock
107
of one or more threads because of waits of semaphores. */
110
sync_array_detect_deadlock(
111
/*=======================*/
112
/* out: TRUE if deadlock detected */
113
sync_array_t* arr, /* in: wait array; NOTE! the caller must
114
own the mutex to array */
115
sync_cell_t* start, /* in: cell where recursive search started */
116
sync_cell_t* cell, /* in: cell to search */
117
ulint depth); /* in: recursion depth */
118
#endif /* UNIV_SYNC_DEBUG */
120
/*********************************************************************
121
Gets the nth cell in array. */
124
sync_array_get_nth_cell(
125
/*====================*/
127
sync_array_t* arr, /* in: sync array */
128
ulint n) /* in: index */
131
ut_a(n < arr->n_cells);
133
return(arr->array + n);
136
/**********************************************************************
137
Reserves the mutex semaphore protecting a sync array. */
142
sync_array_t* arr) /* in: sync wait array */
146
protection = arr->protection;
148
if (protection == SYNC_ARRAY_OS_MUTEX) {
149
os_mutex_enter(arr->os_mutex);
150
} else if (protection == SYNC_ARRAY_MUTEX) {
151
mutex_enter(&(arr->mutex));
157
/**********************************************************************
158
Releases the mutex semaphore protecting a sync array. */
163
sync_array_t* arr) /* in: sync wait array */
167
protection = arr->protection;
169
if (protection == SYNC_ARRAY_OS_MUTEX) {
170
os_mutex_exit(arr->os_mutex);
171
} else if (protection == SYNC_ARRAY_MUTEX) {
172
mutex_exit(&(arr->mutex));
178
/***********************************************************************
179
Creates a synchronization wait array. It is protected by a mutex
180
which is automatically reserved when the functions operating on it
186
/* out, own: created wait array */
187
ulint n_cells, /* in: number of cells in the array
189
ulint protection) /* in: either SYNC_ARRAY_OS_MUTEX or
190
SYNC_ARRAY_MUTEX: determines the type
191
of mutex protecting the data structure */
194
sync_cell_t* cell_array;
200
/* Allocate memory for the data structures */
201
arr = ut_malloc(sizeof(sync_array_t));
203
cell_array = ut_malloc(sizeof(sync_cell_t) * n_cells);
205
arr->n_cells = n_cells;
207
arr->array = cell_array;
208
arr->protection = protection;
212
/* Then create the mutex to protect the wait array complex */
213
if (protection == SYNC_ARRAY_OS_MUTEX) {
214
arr->os_mutex = os_mutex_create(NULL);
215
} else if (protection == SYNC_ARRAY_MUTEX) {
216
mutex_create(&arr->mutex, SYNC_NO_ORDER_CHECK);
221
for (i = 0; i < n_cells; i++) {
222
cell = sync_array_get_nth_cell(arr, i);
223
cell->state = SC_FREE;
224
cell->wait_object = NULL;
226
/* Create an operating system event semaphore with no name */
227
cell->event = os_event_create(NULL);
228
cell->event_set = FALSE; /* it is created in reset state */
234
/**********************************************************************
235
Frees the resources in a wait array. */
240
sync_array_t* arr) /* in, own: sync wait array */
246
ut_a(arr->n_reserved == 0);
248
sync_array_validate(arr);
250
for (i = 0; i < arr->n_cells; i++) {
251
cell = sync_array_get_nth_cell(arr, i);
252
os_event_free(cell->event);
255
protection = arr->protection;
257
/* Release the mutex protecting the wait array complex */
259
if (protection == SYNC_ARRAY_OS_MUTEX) {
260
os_mutex_free(arr->os_mutex);
261
} else if (protection == SYNC_ARRAY_MUTEX) {
262
mutex_free(&(arr->mutex));
271
/************************************************************************
272
Validates the integrity of the wait array. Checks
273
that the number of reserved cells equals the count variable. */
278
sync_array_t* arr) /* in: sync wait array */
284
sync_array_enter(arr);
286
for (i = 0; i < arr->n_cells; i++) {
287
cell = sync_array_get_nth_cell(arr, i);
289
if (cell->state == SC_RESERVED) {
294
ut_a(count == arr->n_reserved);
296
sync_array_exit(arr);
299
/**********************************************************************
300
Reserves a wait array cell for waiting for an object.
301
The event of the cell is reset to nonsignalled state. */
304
sync_array_reserve_cell(
305
/*====================*/
306
sync_array_t* arr, /* in: wait array */
307
void* object, /* in: pointer to the object to wait for */
308
ulint type, /* in: lock request type */
309
const char* file, /* in: file where requested */
310
ulint line, /* in: line where requested */
311
ulint* index) /* out: index of the reserved cell */
319
sync_array_enter(arr);
323
/* Reserve a new cell. */
324
for (i = 0; i < arr->n_cells; i++) {
325
cell = sync_array_get_nth_cell(arr, i);
327
if (cell->state == SC_FREE) {
329
/* We do not check cell->event_set because it is
330
set outside the protection of the sync array mutex
331
and we had a bug regarding it, and since resetting
332
an event when it is not needed does no harm it is
333
safer always to do it. */
335
cell->event_set = FALSE;
336
os_event_reset(cell->event);
338
cell->state = SC_RESERVED;
339
cell->reservation_time = time(NULL);
340
cell->thread = os_thread_get_curr_id();
342
cell->wait_object = object;
344
if (type == SYNC_MUTEX) {
345
cell->old_wait_mutex = object;
347
cell->old_wait_rw_lock = object;
350
cell->request_type = type;
351
cell->waiting = FALSE;
360
sync_array_exit(arr);
366
ut_error; /* No free cell found */
371
/**********************************************************************
372
Frees the cell. Note that we don't have any mutex reserved when calling
376
sync_array_free_cell(
377
/*=================*/
378
sync_array_t* arr, /* in: wait array */
379
ulint index) /* in: index of the cell in array */
383
cell = sync_array_get_nth_cell(arr, index);
385
ut_a(cell->state == SC_WAKING_UP);
386
ut_a(cell->wait_object != NULL);
388
cell->state = SC_FREE;
391
/**********************************************************************
392
Frees the cell safely by reserving the sync array mutex and decrementing
393
n_reserved if necessary. Should only be called from mutex_spin_wait. */
396
sync_array_free_cell_protected(
397
/*===========================*/
398
sync_array_t* arr, /* in: wait array */
399
ulint index) /* in: index of the cell in array */
403
sync_array_enter(arr);
405
cell = sync_array_get_nth_cell(arr, index);
407
ut_a(cell->state != SC_FREE);
408
ut_a(cell->wait_object != NULL);
410
/* We only need to decrement n_reserved if it has not already been
411
done by sync_array_signal_object. */
412
if (cell->state == SC_RESERVED) {
413
ut_a(arr->n_reserved > 0);
415
} else if (cell->state == SC_WAKING_UP) {
416
/* This is tricky; if we don't wait for the event to be
417
signaled, signal_object can set the state of a cell to
418
SC_WAKING_UP, mutex_spin_wait can call this and set the
419
state to SC_FREE, and then signal_object gets around to
420
calling os_set_event for the cell but since it's already
421
been freed things break horribly. */
423
sync_array_exit(arr);
424
os_event_wait(cell->event);
425
sync_array_enter(arr);
428
cell->state = SC_FREE;
430
sync_array_exit(arr);
433
/**********************************************************************
434
This function should be called when a thread starts to wait on
435
a wait array cell. In the debug version this function checks
436
if the wait for a semaphore will result in a deadlock, in which
437
case prints info and asserts. */
440
sync_array_wait_event(
441
/*==================*/
442
sync_array_t* arr, /* in: wait array */
443
ulint index) /* in: index of the reserved cell */
450
cell = sync_array_get_nth_cell(arr, index);
452
ut_a((cell->state == SC_RESERVED) || (cell->state == SC_WAKING_UP));
453
ut_a(cell->wait_object);
454
ut_a(!cell->waiting);
455
ut_ad(os_thread_get_curr_id() == cell->thread);
458
cell->waiting = TRUE;
460
#ifdef UNIV_SYNC_DEBUG
462
/* We use simple enter to the mutex below, because if
463
we cannot acquire it at once, mutex_enter would call
464
recursively sync_array routines, leading to trouble.
465
rw_lock_debug_mutex freezes the debug lists. */
467
sync_array_enter(arr);
468
rw_lock_debug_mutex_enter();
470
if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) {
472
fputs("########################################\n", stderr);
476
rw_lock_debug_mutex_exit();
477
sync_array_exit(arr);
479
os_event_wait(event);
481
sync_array_free_cell(arr, index);
484
/**********************************************************************
485
Reports info of a wait array cell. Note: sync_array_print_long_waits()
486
calls this without mutex protection. */
489
sync_array_cell_print(
490
/*==================*/
491
FILE* file, /* in: file where to print */
492
sync_cell_t* cell) /* in: sync cell */
498
type = cell->request_type;
501
"--Thread %lu has waited at %s line %lu"
502
" for %.2f seconds the semaphore:\n",
503
(ulong) os_thread_pf(cell->thread), cell->file,
505
difftime(time(NULL), cell->reservation_time));
506
fprintf(file, "Wait array cell state %lu\n", (ulong)cell->state);
508
/* If the memory area pointed to by old_wait_mutex /
509
old_wait_rw_lock has been freed, this can crash. */
511
if (cell->state != SC_RESERVED) {
512
/* If cell has this state, then even if we are holding the sync
513
array mutex, the wait object may get freed meanwhile. Do not
514
print the wait object then. */
516
} else if (type == SYNC_MUTEX) {
517
/* We use old_wait_mutex in case the cell has already
518
been freed meanwhile */
519
mutex = cell->old_wait_mutex;
522
"Mutex at %p created file %s line %lu, lock var %lu\n"
523
#ifdef UNIV_SYNC_DEBUG
524
"Last time reserved in file %s line %lu, "
525
#endif /* UNIV_SYNC_DEBUG */
526
"waiters flag %lu\n",
527
(void*) mutex, mutex->cfile_name, (ulong) mutex->cline,
528
(ulong) mutex->lock_word,
529
#ifdef UNIV_SYNC_DEBUG
530
mutex->file_name, (ulong) mutex->line,
531
#endif /* UNIV_SYNC_DEBUG */
532
(ulong) mutex->waiters);
534
} else if (type == RW_LOCK_EX || type == RW_LOCK_SHARED) {
536
fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file);
538
rwlock = cell->old_wait_rw_lock;
541
" RW-latch at %p created in file %s line %lu\n",
542
(void*) rwlock, rwlock->cfile_name,
543
(ulong) rwlock->cline);
544
if (rwlock->writer != RW_LOCK_NOT_LOCKED) {
546
"a writer (thread id %lu) has"
547
" reserved it in mode %s",
548
(ulong) os_thread_pf(rwlock->writer_thread),
549
rwlock->writer == RW_LOCK_EX
551
: " wait exclusive\n");
555
"number of readers %lu, waiters flag %lu\n"
556
"Last time read locked in file %s line %lu\n"
557
"Last time write locked in file %s line %lu\n",
558
(ulong) rwlock->reader_count,
559
(ulong) rwlock->waiters,
560
rwlock->last_s_file_name,
561
(ulong) rwlock->last_s_line,
562
rwlock->last_x_file_name,
563
(ulong) rwlock->last_x_line);
568
if (cell->event_set) {
569
fputs("wait is ending\n", file);
573
#ifdef UNIV_SYNC_DEBUG
574
/**********************************************************************
575
Looks for a cell with the given thread id. */
578
sync_array_find_thread(
579
/*===================*/
580
/* out: pointer to cell or NULL
582
sync_array_t* arr, /* in: wait array */
583
os_thread_id_t thread) /* in: thread id */
588
for (i = 0; i < arr->n_cells; i++) {
590
cell = sync_array_get_nth_cell(arr, i);
592
if ((cell->state == SC_RESERVED)
593
&& os_thread_eq(cell->thread, thread)) {
595
return(cell); /* Found */
599
return(NULL); /* Not found */
602
/**********************************************************************
603
Recursion step for deadlock detection. */
606
sync_array_deadlock_step(
607
/*=====================*/
608
/* out: TRUE if deadlock detected */
609
sync_array_t* arr, /* in: wait array; NOTE! the caller must
610
own the mutex to array */
611
sync_cell_t* start, /* in: cell where recursive search
613
os_thread_id_t thread, /* in: thread to look at */
614
ulint pass, /* in: pass value */
615
ulint depth) /* in: recursion depth */
623
/* If pass != 0, then we do not know which threads are
624
responsible of releasing the lock, and no deadlock can
630
new = sync_array_find_thread(arr, thread);
633
/* Stop running of other threads */
635
ut_dbg_stop_threads = TRUE;
638
fputs("########################################\n"
639
"DEADLOCK of threads detected!\n", stderr);
644
ret = sync_array_detect_deadlock(arr, start, new, depth);
653
/**********************************************************************
654
This function is called only in the debug version. Detects a deadlock
655
of one or more threads because of waits of semaphores. */
658
sync_array_detect_deadlock(
659
/*=======================*/
660
/* out: TRUE if deadlock detected */
661
sync_array_t* arr, /* in: wait array; NOTE! the caller must
662
own the mutex to array */
663
sync_cell_t* start, /* in: cell where recursive search started */
664
sync_cell_t* cell, /* in: cell to search */
665
ulint depth) /* in: recursion depth */
669
os_thread_id_t thread;
671
rw_lock_debug_t*debug;
676
ut_ad(cell->wait_object);
677
ut_ad(os_thread_get_curr_id() == start->thread);
682
if (cell->event_set || !cell->waiting) {
684
return(FALSE); /* No deadlock here */
687
if (cell->request_type == SYNC_MUTEX) {
689
mutex = cell->wait_object;
691
if (mutex_get_lock_word(mutex) != 0) {
693
thread = mutex->thread_id;
695
/* Note that mutex->thread_id above may be
696
also OS_THREAD_ID_UNDEFINED, because the
697
thread which held the mutex maybe has not
698
yet updated the value, or it has already
699
released the mutex: in this case no deadlock
700
can occur, as the wait array cannot contain
701
a thread with ID_UNDEFINED value. */
703
ret = sync_array_deadlock_step(arr, start, thread, 0,
707
"Mutex %p owned by thread %lu"
708
" file %s line %lu\n",
710
(ulong) os_thread_pf(mutex->thread_id),
711
mutex->file_name, (ulong) mutex->line);
712
sync_array_cell_print(stderr, cell);
718
return(FALSE); /* No deadlock */
720
} else if (cell->request_type == RW_LOCK_EX) {
722
lock = cell->wait_object;
724
debug = UT_LIST_GET_FIRST(lock->debug_list);
726
while (debug != NULL) {
728
thread = debug->thread_id;
730
if (((debug->lock_type == RW_LOCK_EX)
731
&& !os_thread_eq(thread, cell->thread))
732
|| ((debug->lock_type == RW_LOCK_WAIT_EX)
733
&& !os_thread_eq(thread, cell->thread))
734
|| (debug->lock_type == RW_LOCK_SHARED)) {
736
/* The (wait) x-lock request can block
737
infinitely only if someone (can be also cell
738
thread) is holding s-lock, or someone
739
(cannot be cell thread) (wait) x-lock, and
740
he is blocked by start thread */
742
ret = sync_array_deadlock_step(
743
arr, start, thread, debug->pass,
747
fprintf(stderr, "rw-lock %p ",
749
sync_array_cell_print(stderr, cell);
750
rw_lock_debug_print(debug);
755
debug = UT_LIST_GET_NEXT(list, debug);
760
} else if (cell->request_type == RW_LOCK_SHARED) {
762
lock = cell->wait_object;
763
debug = UT_LIST_GET_FIRST(lock->debug_list);
765
while (debug != NULL) {
767
thread = debug->thread_id;
769
if ((debug->lock_type == RW_LOCK_EX)
770
|| (debug->lock_type == RW_LOCK_WAIT_EX)) {
772
/* The s-lock request can block infinitely
773
only if someone (can also be cell thread) is
774
holding (wait) x-lock, and he is blocked by
777
ret = sync_array_deadlock_step(
778
arr, start, thread, debug->pass,
785
debug = UT_LIST_GET_NEXT(list, debug);
794
return(TRUE); /* Execution never reaches this line: for compiler
797
#endif /* UNIV_SYNC_DEBUG */
799
/**********************************************************************
800
Determines if we can wake up the thread waiting for a sempahore. */
803
sync_arr_cell_can_wake_up(
804
/*======================*/
805
sync_cell_t* cell) /* in: cell to search */
810
if (cell->request_type == SYNC_MUTEX) {
812
mutex = cell->wait_object;
814
if (mutex_get_lock_word(mutex) == 0) {
819
} else if (cell->request_type == RW_LOCK_EX) {
821
lock = cell->wait_object;
823
if (rw_lock_get_reader_count(lock) == 0
824
&& rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
829
if (rw_lock_get_reader_count(lock) == 0
830
&& rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX
831
&& os_thread_eq(lock->writer_thread, cell->thread)) {
836
} else if (cell->request_type == RW_LOCK_SHARED) {
837
lock = cell->wait_object;
839
if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
848
/**************************************************************************
849
Looks for the cells in the wait array which refer to the wait object
850
specified, and sets their corresponding events to the signaled state. In this
851
way releases the threads waiting for the object to contend for the object.
852
It is possible that no such cell is found, in which case does nothing. */
855
sync_array_signal_object(
856
/*=====================*/
857
sync_array_t* arr, /* in: wait array */
858
void* object) /* in: wait object */
865
/* We store the addresses of cells we need to signal and signal
866
them only after we have released the sync array's mutex (for
867
performance reasons). cell_count is the number of such cells, and
868
cell_ptr points to the first one. If there are less than
869
UT_ARR_SIZE(cells) of them, cell_ptr == &cells[0], otherwise
870
cell_ptr points to malloc'd memory that we must free. */
872
sync_cell_t* cells[100];
873
sync_cell_t** cell_ptr = &cells[0];
874
ulint cell_count = 0;
875
ulint cell_max_count = UT_ARR_SIZE(cells);
877
ut_a(100 == cell_max_count);
879
sync_array_enter(arr);
886
/* We need to store this to a local variable because it is modified
888
res_count = arr->n_reserved;
890
while (count < res_count) {
892
cell = sync_array_get_nth_cell(arr, i);
894
if (cell->state == SC_RESERVED) {
897
if (cell->wait_object == object) {
898
cell->state = SC_WAKING_UP;
900
ut_a(arr->n_reserved > 0);
903
if (cell_count == cell_max_count) {
904
sync_cell_t** old_cell_ptr = cell_ptr;
905
size_t old_size, new_size;
907
old_size = cell_max_count
908
* sizeof(sync_cell_t*);
910
new_size = cell_max_count
911
* sizeof(sync_cell_t*);
913
cell_ptr = malloc(new_size);
915
memcpy(cell_ptr, old_cell_ptr,
918
if (old_cell_ptr != &cells[0]) {
923
cell_ptr[cell_count] = cell;
931
sync_array_exit(arr);
933
for (i = 0; i < cell_count; i++) {
936
cell->event_set = TRUE;
937
os_event_set(cell->event);
940
if (cell_ptr != &cells[0]) {
945
/**************************************************************************
946
If the wakeup algorithm does not work perfectly at semaphore relases,
947
this function will do the waking (see the comment in mutex_exit). This
948
function should be called about every 1 second in the server.
950
Note that there's a race condition between this thread and mutex_exit
951
changing the lock_word and calling signal_object, so sometimes this finds
952
threads to wake up even when nothing has gone wrong. */
955
sync_arr_wake_threads_if_sema_free(void)
956
/*====================================*/
958
sync_array_t* arr = sync_primary_wait_array;
964
sync_array_enter(arr);
969
/* We need to store this to a local variable because it is modified
972
res_count = arr->n_reserved;
974
while (count < res_count) {
976
cell = sync_array_get_nth_cell(arr, i);
978
if (cell->state == SC_RESERVED) {
982
if (sync_arr_cell_can_wake_up(cell)) {
983
cell->state = SC_WAKING_UP;
984
cell->event_set = TRUE;
985
os_event_set(cell->event);
987
ut_a(arr->n_reserved > 0);
995
sync_array_exit(arr);
998
/**************************************************************************
999
Prints warnings of long semaphore waits to stderr. */
1002
sync_array_print_long_waits(void)
1003
/*=============================*/
1004
/* out: TRUE if fatal semaphore wait threshold
1009
ibool noticed = FALSE;
1011
ulint fatal_timeout = srv_fatal_semaphore_wait_threshold;
1012
ibool fatal = FALSE;
1014
for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
1016
cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
1018
if ((cell->state != SC_FREE)
1019
&& difftime(time(NULL), cell->reservation_time) > 240) {
1020
fputs("InnoDB: Warning: a long semaphore wait:\n",
1022
sync_array_cell_print(stderr, cell);
1026
if ((cell->state != SC_FREE)
1027
&& difftime(time(NULL), cell->reservation_time)
1035
"InnoDB: ###### Starts InnoDB Monitor"
1036
" for 30 secs to print diagnostic info:\n");
1037
old_val = srv_print_innodb_monitor;
1039
/* If some crucial semaphore is reserved, then also the InnoDB
1040
Monitor can hang, and we do not get diagnostics. Since in
1041
many cases an InnoDB hang is caused by a pwrite() or a pread()
1042
call hanging inside the operating system, let us print right
1043
now the values of pending calls of these. */
1046
"InnoDB: Pending preads %lu, pwrites %lu\n",
1047
(ulong)os_file_n_pending_preads,
1048
(ulong)os_file_n_pending_pwrites);
1050
srv_print_innodb_monitor = TRUE;
1051
os_event_set(srv_lock_timeout_thread_event);
1053
os_thread_sleep(30000000);
1055
srv_print_innodb_monitor = old_val;
1057
"InnoDB: ###### Diagnostic info printed"
1058
" to the standard error stream\n");
1064
/**************************************************************************
1065
Prints info of the wait array. */
1068
sync_array_output_info(
1069
/*===================*/
1070
FILE* file, /* in: file where to print */
1071
sync_array_t* arr) /* in: wait array; NOTE! caller must own the
1078
"OS WAIT ARRAY INFO: reservation count %ld,"
1079
" signal count %ld\n",
1080
(long) arr->res_count,
1081
(long) arr->sg_count);
1082
for (i = 0; i < arr->n_cells; i++) {
1084
cell = sync_array_get_nth_cell(arr, i);
1086
if (cell->state != SC_FREE) {
1087
sync_array_cell_print(file, cell);
1092
/**************************************************************************
1093
Prints info of the wait array. */
1096
sync_array_print_info(
1097
/*==================*/
1098
FILE* file, /* in: file where to print */
1099
sync_array_t* arr) /* in: wait array */
1101
sync_array_enter(arr);
1103
sync_array_output_info(file, arr);
1105
sync_array_exit(arr);