#include "sync0arr.h"#include "sync0sync.h"#include "sync0rw.h"#include "os0sync.h"#include "os0file.h"#include "srv0srv.h"Include dependency graph for sync0arr.c:

Go to the source code of this file.
| static ibool sync_arr_cell_can_wake_up | ( | sync_cell_t * | cell | ) | [static] |
Definition at line 796 of file sync0arr.c.
References FALSE, lock, mutex, mutex_get_lock_word(), os_thread_eq(), sync_cell_struct::request_type, RW_LOCK_EX, rw_lock_get_reader_count(), rw_lock_get_writer(), RW_LOCK_NOT_LOCKED, RW_LOCK_SHARED, RW_LOCK_WAIT_EX, SYNC_MUTEX, sync_cell_struct::thread, TRUE, and sync_cell_struct::wait_object.
Referenced by sync_arr_wake_threads_if_sema_free().
00798 : cell to search */ 00799 { 00800 mutex_t* mutex; 00801 rw_lock_t* lock; 00802 00803 if (cell->request_type == SYNC_MUTEX) { 00804 00805 mutex = cell->wait_object; 00806 00807 if (mutex_get_lock_word(mutex) == 0) { 00808 00809 return(TRUE); 00810 } 00811 00812 } else if (cell->request_type == RW_LOCK_EX) { 00813 00814 lock = cell->wait_object; 00815 00816 if (rw_lock_get_reader_count(lock) == 0 00817 && rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) { 00818 00819 return(TRUE); 00820 } 00821 00822 if (rw_lock_get_reader_count(lock) == 0 00823 && rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX 00824 && os_thread_eq(lock->writer_thread, cell->thread)) { 00825 00826 return(TRUE); 00827 } 00828 00829 } else if (cell->request_type == RW_LOCK_SHARED) { 00830 lock = cell->wait_object; 00831 00832 if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) { 00833 00834 return(TRUE); 00835 } 00836 } 00837 00838 return(FALSE); 00839 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sync_arr_wake_threads_if_sema_free | ( | void | ) |
Definition at line 948 of file sync0arr.c.
References count, sync_cell_struct::event, sync_cell_struct::event_set, sync_array_struct::n_reserved, os_event_set(), sync_cell_struct::state, sync_arr_cell_can_wake_up(), sync_array_enter(), sync_array_exit(), sync_array_get_nth_cell(), sync_primary_wait_array, TRUE, and ut_a.
Referenced by srv_lock_timeout_and_monitor_thread().
00950 { 00951 sync_array_t* arr = sync_primary_wait_array; 00952 sync_cell_t* cell; 00953 ulint count; 00954 ulint i; 00955 ulint res_count; 00956 00957 sync_array_enter(arr); 00958 00959 i = 0; 00960 count = 0; 00961 00962 /* We need to store this to a local variable because it is modified 00963 inside the loop */ 00964 00965 res_count = arr->n_reserved; 00966 00967 while (count < res_count) { 00968 00969 cell = sync_array_get_nth_cell(arr, i); 00970 00971 if (cell->state == SC_RESERVED) { 00972 00973 count++; 00974 00975 if (sync_arr_cell_can_wake_up(cell)) { 00976 cell->state = SC_WAKING_UP; 00977 cell->event_set = TRUE; 00978 os_event_set(cell->event); 00979 00980 ut_a(arr->n_reserved > 0); 00981 arr->n_reserved--; 00982 } 00983 } 00984 00985 i++; 00986 } 00987 00988 sync_array_exit(arr); 00989 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void sync_array_cell_print | ( | FILE * | file, | |
| sync_cell_t * | cell | |||
| ) | [static] |
Definition at line 489 of file sync0arr.c.
References rw_lock_struct::cfile_name, sync_cell_struct::event_set, sync_cell_struct::file, sync_cell_struct::line, mutex, NULL, sync_cell_struct::old_wait_mutex, sync_cell_struct::old_wait_rw_lock, os_thread_pf(), sync_cell_struct::request_type, sync_cell_struct::reservation_time, RW_LOCK_EX, RW_LOCK_NOT_LOCKED, RW_LOCK_SHARED, sync_cell_struct::state, SYNC_MUTEX, sync_cell_struct::thread, and ut_error.
Referenced by sync_array_output_info(), and sync_array_print_long_waits().
00491 : file where to print */ 00492 sync_cell_t* cell) /* in: sync cell */ 00493 { 00494 mutex_t* mutex; 00495 rw_lock_t* rwlock; 00496 ulint type; 00497 00498 type = cell->request_type; 00499 00500 fprintf(file, 00501 "--Thread %lu has waited at %s line %lu for %.2f seconds the semaphore:\n", 00502 (ulong) os_thread_pf(cell->thread), cell->file, 00503 (ulong) cell->line, 00504 difftime(time(NULL), cell->reservation_time)); 00505 fprintf(file, "Wait array cell state %lu\n", (ulong)cell->state); 00506 00507 /* If the memory area pointed to by old_wait_mutex / 00508 old_wait_rw_lock has been freed, this can crash. */ 00509 00510 if (cell->state != SC_RESERVED) { 00511 /* If cell has this state, then even if we are holding the sync 00512 array mutex, the wait object may get freed meanwhile. Do not 00513 print the wait object then. */ 00514 00515 } else if (type == SYNC_MUTEX) { 00516 /* We use old_wait_mutex in case the cell has already 00517 been freed meanwhile */ 00518 mutex = cell->old_wait_mutex; 00519 00520 fprintf(file, 00521 "Mutex at %p created file %s line %lu, lock var %lu\n" 00522 #ifdef UNIV_SYNC_DEBUG 00523 "Last time reserved in file %s line %lu, " 00524 #endif /* UNIV_SYNC_DEBUG */ 00525 "waiters flag %lu\n", 00526 (void*) mutex, mutex->cfile_name, (ulong) mutex->cline, 00527 (ulong) mutex->lock_word, 00528 #ifdef UNIV_SYNC_DEBUG 00529 mutex->file_name, (ulong) mutex->line, 00530 #endif /* UNIV_SYNC_DEBUG */ 00531 (ulong) mutex->waiters); 00532 00533 } else if (type == RW_LOCK_EX || type == RW_LOCK_SHARED) { 00534 00535 fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file); 00536 00537 rwlock = cell->old_wait_rw_lock; 00538 00539 fprintf(file, 00540 " RW-latch at %p created in file %s line %lu\n", 00541 (void*) rwlock, rwlock->cfile_name, 00542 (ulong) rwlock->cline); 00543 if (rwlock->writer != RW_LOCK_NOT_LOCKED) { 00544 fprintf(file, 00545 "a writer (thread id %lu) has reserved it in mode %s", 00546 (ulong) os_thread_pf(rwlock->writer_thread), 00547 rwlock->writer == RW_LOCK_EX 00548 ? " exclusive\n" 00549 : " wait exclusive\n"); 00550 } 00551 00552 fprintf(file, 00553 "number of readers %lu, waiters flag %lu\n" 00554 "Last time read locked in file %s line %lu\n" 00555 "Last time write locked in file %s line %lu\n", 00556 (ulong) rwlock->reader_count, 00557 (ulong) rwlock->waiters, 00558 rwlock->last_s_file_name, 00559 (ulong) rwlock->last_s_line, 00560 rwlock->last_x_file_name, 00561 (ulong) rwlock->last_x_line); 00562 } else { 00563 ut_error; 00564 } 00565 00566 if (cell->event_set) { 00567 fputs("wait is ending\n", file); 00568 } 00569 }
Here is the call graph for this function:

Here is the caller graph for this function:

| sync_array_t* sync_array_create | ( | ulint | n_cells, | |
| ulint | protection | |||
| ) |
Definition at line 184 of file sync0arr.c.
References sync_array_struct::array, sync_cell_struct::event, sync_cell_struct::event_set, FALSE, sync_array_struct::mutex, mutex_create, sync_array_struct::n_cells, sync_array_struct::n_reserved, NULL, os_event_create(), sync_array_struct::os_mutex, os_mutex_create(), sync_array_struct::protection, sync_array_struct::res_count, sync_array_struct::sg_count, sync_cell_struct::state, sync_array_get_nth_cell(), SYNC_ARRAY_MUTEX, SYNC_ARRAY_OS_MUTEX, SYNC_NO_ORDER_CHECK, ut_a, ut_error, ut_malloc(), and sync_cell_struct::wait_object.
Referenced by sync_init().
00186 : created wait array */ 00187 ulint n_cells, /* in: number of cells in the array 00188 to create */ 00189 ulint protection) /* in: either SYNC_ARRAY_OS_MUTEX or 00190 SYNC_ARRAY_MUTEX: determines the type 00191 of mutex protecting the data structure */ 00192 { 00193 sync_array_t* arr; 00194 sync_cell_t* cell_array; 00195 sync_cell_t* cell; 00196 ulint i; 00197 00198 ut_a(n_cells > 0); 00199 00200 /* Allocate memory for the data structures */ 00201 arr = ut_malloc(sizeof(sync_array_t)); 00202 00203 cell_array = ut_malloc(sizeof(sync_cell_t) * n_cells); 00204 00205 arr->n_cells = n_cells; 00206 arr->n_reserved = 0; 00207 arr->array = cell_array; 00208 arr->protection = protection; 00209 arr->sg_count = 0; 00210 arr->res_count = 0; 00211 00212 /* Then create the mutex to protect the wait array complex */ 00213 if (protection == SYNC_ARRAY_OS_MUTEX) { 00214 arr->os_mutex = os_mutex_create(NULL); 00215 } else if (protection == SYNC_ARRAY_MUTEX) { 00216 mutex_create(&arr->mutex, SYNC_NO_ORDER_CHECK); 00217 } else { 00218 ut_error; 00219 } 00220 00221 for (i = 0; i < n_cells; i++) { 00222 cell = sync_array_get_nth_cell(arr, i); 00223 cell->state = SC_FREE; 00224 cell->wait_object = NULL; 00225 00226 /* Create an operating system event semaphore with no name */ 00227 cell->event = os_event_create(NULL); 00228 cell->event_set = FALSE; /* it is created in reset state */ 00229 } 00230 00231 return(arr); 00232 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void sync_array_enter | ( | sync_array_t * | arr | ) | [static] |
Definition at line 140 of file sync0arr.c.
References sync_array_struct::mutex, mutex_enter, sync_array_struct::os_mutex, os_mutex_enter(), sync_array_struct::protection, SYNC_ARRAY_MUTEX, SYNC_ARRAY_OS_MUTEX, and ut_error.
Referenced by sync_arr_wake_threads_if_sema_free(), sync_array_free_cell_protected(), sync_array_print_info(), sync_array_reserve_cell(), sync_array_signal_object(), sync_array_validate(), and sync_array_wait_event().
00142 : sync wait array */ 00143 { 00144 ulint protection; 00145 00146 protection = arr->protection; 00147 00148 if (protection == SYNC_ARRAY_OS_MUTEX) { 00149 os_mutex_enter(arr->os_mutex); 00150 } else if (protection == SYNC_ARRAY_MUTEX) { 00151 mutex_enter(&(arr->mutex)); 00152 } else { 00153 ut_error; 00154 } 00155 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void sync_array_exit | ( | sync_array_t * | arr | ) | [static] |
Definition at line 161 of file sync0arr.c.
References sync_array_struct::mutex, mutex_exit(), sync_array_struct::os_mutex, os_mutex_exit(), sync_array_struct::protection, SYNC_ARRAY_MUTEX, SYNC_ARRAY_OS_MUTEX, and ut_error.
Referenced by sync_arr_wake_threads_if_sema_free(), sync_array_free_cell_protected(), sync_array_print_info(), sync_array_reserve_cell(), sync_array_signal_object(), and sync_array_wait_event().
00163 : sync wait array */ 00164 { 00165 ulint protection; 00166 00167 protection = arr->protection; 00168 00169 if (protection == SYNC_ARRAY_OS_MUTEX) { 00170 os_mutex_exit(arr->os_mutex); 00171 } else if (protection == SYNC_ARRAY_MUTEX) { 00172 mutex_exit(&(arr->mutex)); 00173 } else { 00174 ut_error; 00175 } 00176 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sync_array_free | ( | sync_array_t * | arr | ) |
Definition at line 238 of file sync0arr.c.
References sync_array_struct::array, sync_cell_struct::event, sync_array_struct::mutex, mutex_free(), sync_array_struct::n_cells, sync_array_struct::n_reserved, os_event_free(), sync_array_struct::os_mutex, os_mutex_free(), sync_array_struct::protection, sync_array_get_nth_cell(), SYNC_ARRAY_MUTEX, SYNC_ARRAY_OS_MUTEX, sync_array_validate(), ut_a, ut_error, and ut_free().
Referenced by sync_close().
00240 : sync wait array */ 00241 { 00242 ulint i; 00243 sync_cell_t* cell; 00244 ulint protection; 00245 00246 ut_a(arr->n_reserved == 0); 00247 00248 sync_array_validate(arr); 00249 00250 for (i = 0; i < arr->n_cells; i++) { 00251 cell = sync_array_get_nth_cell(arr, i); 00252 os_event_free(cell->event); 00253 } 00254 00255 protection = arr->protection; 00256 00257 /* Release the mutex protecting the wait array complex */ 00258 00259 if (protection == SYNC_ARRAY_OS_MUTEX) { 00260 os_mutex_free(arr->os_mutex); 00261 } else if (protection == SYNC_ARRAY_MUTEX) { 00262 mutex_free(&(arr->mutex)); 00263 } else { 00264 ut_error; 00265 } 00266 00267 ut_free(arr->array); 00268 ut_free(arr); 00269 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void sync_array_free_cell | ( | sync_array_t * | arr, | |
| ulint | index | |||
| ) | [static] |
Definition at line 376 of file sync0arr.c.
References NULL, sync_cell_struct::state, sync_array_get_nth_cell(), ut_a, and sync_cell_struct::wait_object.
Referenced by sync_array_wait_event().
00378 : wait array */ 00379 ulint index) /* in: index of the cell in array */ 00380 { 00381 sync_cell_t* cell; 00382 00383 cell = sync_array_get_nth_cell(arr, index); 00384 00385 ut_a(cell->state == SC_WAKING_UP); 00386 ut_a(cell->wait_object != NULL); 00387 00388 cell->state = SC_FREE; 00389 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sync_array_free_cell_protected | ( | sync_array_t * | arr, | |
| ulint | index | |||
| ) |
Definition at line 396 of file sync0arr.c.
References sync_cell_struct::event, sync_array_struct::n_reserved, NULL, os_event_wait(), sync_cell_struct::state, sync_array_enter(), sync_array_exit(), sync_array_get_nth_cell(), ut_a, and sync_cell_struct::wait_object.
Referenced by mutex_spin_wait().
00398 : wait array */ 00399 ulint index) /* in: index of the cell in array */ 00400 { 00401 sync_cell_t* cell; 00402 00403 sync_array_enter(arr); 00404 00405 cell = sync_array_get_nth_cell(arr, index); 00406 00407 ut_a(cell->state != SC_FREE); 00408 ut_a(cell->wait_object != NULL); 00409 00410 /* We only need to decrement n_reserved if it has not already been 00411 done by sync_array_signal_object. */ 00412 if (cell->state == SC_RESERVED) { 00413 ut_a(arr->n_reserved > 0); 00414 arr->n_reserved--; 00415 } else if (cell->state == SC_WAKING_UP) { 00416 /* This is tricky; if we don't wait for the event to be 00417 signaled, signal_object can set the state of a cell to 00418 SC_WAKING_UP, mutex_spin_wait can call this and set the 00419 state to SC_FREE, and then signal_object gets around to 00420 calling os_set_event for the cell but since it's already 00421 been freed things break horribly. */ 00422 00423 sync_array_exit(arr); 00424 os_event_wait(cell->event); 00425 sync_array_enter(arr); 00426 } 00427 00428 cell->state = SC_FREE; 00429 00430 sync_array_exit(arr); 00431 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static sync_cell_t* sync_array_get_nth_cell | ( | sync_array_t * | arr, | |
| ulint | n | |||
| ) | [static] |
Definition at line 124 of file sync0arr.c.
References sync_array_struct::array, and ut_a.
Referenced by sync_arr_wake_threads_if_sema_free(), sync_array_create(), sync_array_free(), sync_array_free_cell(), sync_array_free_cell_protected(), sync_array_output_info(), sync_array_print_long_waits(), sync_array_reserve_cell(), sync_array_signal_object(), sync_array_validate(), and sync_array_wait_event().
00126 : cell */ 00127 sync_array_t* arr, /* in: sync array */ 00128 ulint n) /* in: index */ 00129 { 00130 ut_a(arr); 00131 ut_a(n < arr->n_cells); 00132 00133 return(arr->array + n); 00134 }
Here is the caller graph for this function:

| static void sync_array_output_info | ( | FILE * | file, | |
| sync_array_t * | arr | |||
| ) | [static] |
Definition at line 1058 of file sync0arr.c.
References sync_array_struct::n_cells, sync_array_struct::res_count, sync_array_struct::sg_count, sync_cell_struct::state, sync_array_cell_print(), and sync_array_get_nth_cell().
Referenced by sync_array_print_info().
01060 : file where to print */ 01061 sync_array_t* arr) /* in: wait array; NOTE! caller must own the 01062 mutex */ 01063 { 01064 sync_cell_t* cell; 01065 ulint i; 01066 01067 fprintf(file, 01068 "OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n", 01069 (long) arr->res_count, 01070 (long) arr->sg_count); 01071 for (i = 0; i < arr->n_cells; i++) { 01072 01073 cell = sync_array_get_nth_cell(arr, i); 01074 01075 if (cell->state != SC_FREE) { 01076 sync_array_cell_print(file, cell); 01077 } 01078 } 01079 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sync_array_print_info | ( | FILE * | file, | |
| sync_array_t * | arr | |||
| ) |
Definition at line 1085 of file sync0arr.c.
References sync_array_enter(), sync_array_exit(), and sync_array_output_info().
Referenced by sync_print().
01087 : file where to print */ 01088 sync_array_t* arr) /* in: wait array */ 01089 { 01090 sync_array_enter(arr); 01091 01092 sync_array_output_info(file, arr); 01093 01094 sync_array_exit(arr); 01095 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool sync_array_print_long_waits | ( | void | ) |
Definition at line 995 of file sync0arr.c.
References FALSE, yaSSL::fatal, sync_array_struct::n_cells, NULL, sync_cell_struct::reservation_time, srv_fatal_semaphore_wait_threshold, sync_cell_struct::state, sync_array_cell_print(), sync_array_get_nth_cell(), sync_primary_wait_array, and TRUE.
Referenced by srv_error_monitor_thread().
00997 : TRUE if fatal semaphore wait threshold 00998 was exceeded */ 00999 { 01000 sync_cell_t* cell; 01001 ibool old_val; 01002 ibool noticed = FALSE; 01003 ulint i; 01004 ulint fatal_timeout = srv_fatal_semaphore_wait_threshold; 01005 ibool fatal = FALSE; 01006 01007 for (i = 0; i < sync_primary_wait_array->n_cells; i++) { 01008 01009 cell = sync_array_get_nth_cell(sync_primary_wait_array, i); 01010 01011 if ((cell->state != SC_FREE) 01012 && difftime(time(NULL), cell->reservation_time) > 240) { 01013 fputs("InnoDB: Warning: a long semaphore wait:\n", 01014 stderr); 01015 sync_array_cell_print(stderr, cell); 01016 noticed = TRUE; 01017 } 01018 01019 if ((cell->state != SC_FREE) 01020 && difftime(time(NULL), cell->reservation_time) 01021 > fatal_timeout) { 01022 fatal = TRUE; 01023 } 01024 } 01025 01026 if (noticed) { 01027 fprintf(stderr, 01028 "InnoDB: ###### Starts InnoDB Monitor for 30 secs to print diagnostic info:\n"); 01029 old_val = srv_print_innodb_monitor; 01030 01031 /* If some crucial semaphore is reserved, then also the InnoDB 01032 Monitor can hang, and we do not get diagnostics. Since in 01033 many cases an InnoDB hang is caused by a pwrite() or a pread() 01034 call hanging inside the operating system, let us print right 01035 now the values of pending calls of these. */ 01036 01037 fprintf(stderr, 01038 "InnoDB: Pending preads %lu, pwrites %lu\n", (ulong)os_file_n_pending_preads, 01039 (ulong)os_file_n_pending_pwrites); 01040 01041 srv_print_innodb_monitor = TRUE; 01042 os_event_set(srv_lock_timeout_thread_event); 01043 01044 os_thread_sleep(30000000); 01045 01046 srv_print_innodb_monitor = old_val; 01047 fprintf(stderr, 01048 "InnoDB: ###### Diagnostic info printed to the standard error stream\n"); 01049 } 01050 01051 return(fatal); 01052 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sync_array_reserve_cell | ( | sync_array_t * | arr, | |
| void * | object, | |||
| ulint | type, | |||
| const char * | file, | |||
| ulint | line, | |||
| ulint * | index | |||
| ) |
Definition at line 304 of file sync0arr.c.
References sync_cell_struct::event, sync_cell_struct::event_set, FALSE, sync_cell_struct::file, sync_cell_struct::line, sync_array_struct::n_cells, sync_array_struct::n_reserved, NULL, sync_cell_struct::old_wait_mutex, sync_cell_struct::old_wait_rw_lock, os_event_reset(), os_thread_get_curr_id(), sync_cell_struct::request_type, sync_array_struct::res_count, sync_cell_struct::reservation_time, sync_cell_struct::state, sync_array_enter(), sync_array_exit(), sync_array_get_nth_cell(), SYNC_MUTEX, sync_cell_struct::thread, ut_a, sync_cell_struct::wait_object, and sync_cell_struct::waiting.
Referenced by mutex_spin_wait(), rw_lock_s_lock_spin(), and rw_lock_x_lock_func().
00306 : wait array */ 00307 void* object, /* in: pointer to the object to wait for */ 00308 ulint type, /* in: lock request type */ 00309 const char* file, /* in: file where requested */ 00310 ulint line, /* in: line where requested */ 00311 ulint* index) /* out: index of the reserved cell */ 00312 { 00313 sync_cell_t* cell; 00314 ulint i; 00315 00316 ut_a(object); 00317 ut_a(index); 00318 00319 sync_array_enter(arr); 00320 00321 arr->res_count++; 00322 00323 /* Reserve a new cell. */ 00324 for (i = 0; i < arr->n_cells; i++) { 00325 cell = sync_array_get_nth_cell(arr, i); 00326 00327 if (cell->state == SC_FREE) { 00328 00329 /* We do not check cell->event_set because it is 00330 set outside the protection of the sync array mutex 00331 and we had a bug regarding it, and since resetting 00332 an event when it is not needed does no harm it is 00333 safer always to do it. */ 00334 00335 cell->event_set = FALSE; 00336 os_event_reset(cell->event); 00337 00338 cell->state = SC_RESERVED; 00339 cell->reservation_time = time(NULL); 00340 cell->thread = os_thread_get_curr_id(); 00341 00342 cell->wait_object = object; 00343 00344 if (type == SYNC_MUTEX) { 00345 cell->old_wait_mutex = object; 00346 } else { 00347 cell->old_wait_rw_lock = object; 00348 } 00349 00350 cell->request_type = type; 00351 cell->waiting = FALSE; 00352 00353 cell->file = file; 00354 cell->line = line; 00355 00356 arr->n_reserved++; 00357 00358 *index = i; 00359 00360 sync_array_exit(arr); 00361 00362 return; 00363 } 00364 } 00365 00366 ut_error; /* No free cell found */ 00367 00368 return; 00369 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sync_array_signal_object | ( | sync_array_t * | arr, | |
| void * | object | |||
| ) |
Definition at line 848 of file sync0arr.c.
References count, sync_cell_struct::event, sync_cell_struct::event_set, free, malloc, memcpy, sync_array_struct::n_reserved, os_event_set(), sync_array_struct::sg_count, sync_cell_struct::state, sync_array_enter(), sync_array_exit(), sync_array_get_nth_cell(), TRUE, ut_a, and sync_cell_struct::wait_object.
Referenced by mutex_signal_object().
00850 : wait array */ 00851 void* object) /* in: wait object */ 00852 { 00853 sync_cell_t* cell; 00854 ulint count; 00855 ulint i; 00856 ulint res_count; 00857 00858 /* We store the addresses of cells we need to signal and signal 00859 them only after we have released the sync array's mutex (for 00860 performance reasons). cell_count is the number of such cells, and 00861 cell_ptr points to the first one. If there are less than 00862 UT_ARR_SIZE(cells) of them, cell_ptr == &cells[0], otherwise 00863 cell_ptr points to malloc'd memory that we must free. */ 00864 00865 sync_cell_t* cells[100]; 00866 sync_cell_t** cell_ptr = &cells[0]; 00867 ulint cell_count = 0; 00868 ulint cell_max_count = UT_ARR_SIZE(cells); 00869 00870 ut_a(100 == cell_max_count); 00871 00872 sync_array_enter(arr); 00873 00874 arr->sg_count++; 00875 00876 i = 0; 00877 count = 0; 00878 00879 /* We need to store this to a local variable because it is modified 00880 inside the loop */ 00881 res_count = arr->n_reserved; 00882 00883 while (count < res_count) { 00884 00885 cell = sync_array_get_nth_cell(arr, i); 00886 00887 if (cell->state == SC_RESERVED) { 00888 00889 count++; 00890 if (cell->wait_object == object) { 00891 cell->state = SC_WAKING_UP; 00892 00893 ut_a(arr->n_reserved > 0); 00894 arr->n_reserved--; 00895 00896 if (cell_count == cell_max_count) { 00897 sync_cell_t** old_cell_ptr = cell_ptr; 00898 size_t old_size, new_size; 00899 00900 old_size = cell_max_count * 00901 sizeof(sync_cell_t*); 00902 cell_max_count *= 2; 00903 new_size = cell_max_count * 00904 sizeof(sync_cell_t*); 00905 00906 cell_ptr = malloc(new_size); 00907 ut_a(cell_ptr); 00908 memcpy(cell_ptr, old_cell_ptr, 00909 old_size); 00910 00911 if (old_cell_ptr != &cells[0]) { 00912 free(old_cell_ptr); 00913 } 00914 } 00915 00916 cell_ptr[cell_count] = cell; 00917 cell_count++; 00918 } 00919 } 00920 00921 i++; 00922 } 00923 00924 sync_array_exit(arr); 00925 00926 for (i = 0; i < cell_count; i++) { 00927 cell = cell_ptr[i]; 00928 00929 cell->event_set = TRUE; 00930 os_event_set(cell->event); 00931 } 00932 00933 if (cell_ptr != &cells[0]) { 00934 free(cell_ptr); 00935 } 00936 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sync_array_validate | ( | sync_array_t * | arr | ) |
Definition at line 276 of file sync0arr.c.
References count, sync_array_struct::n_cells, sync_cell_struct::state, sync_array_enter(), and sync_array_get_nth_cell().
Referenced by sync_array_free().
00278 : sync wait array */ 00279 { 00280 ulint i; 00281 sync_cell_t* cell; 00282 ulint count = 0; 00283 00284 sync_array_enter(arr); 00285 00286 for (i = 0; i < arr->n_cells; i++) { 00287 cell = sync_array_get_nth_cell(arr, i); 00288 00289 if (cell->state == SC_RESERVED) { 00290 count++; 00291 } 00292 } 00293 00294 ut_a(count == arr->n_reserved); 00295 00296 sync_array_exit(arr); 00297 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sync_array_wait_event | ( | sync_array_t * | arr, | |
| ulint | index | |||
| ) |
Definition at line 440 of file sync0arr.c.
References sync_cell_struct::event, os_event_wait(), os_thread_get_curr_id(), sync_cell_struct::state, sync_array_enter(), sync_array_exit(), sync_array_free_cell(), sync_array_get_nth_cell(), sync_cell_struct::thread, TRUE, ut_a, ut_ad, ut_error, sync_cell_struct::wait_object, and sync_cell_struct::waiting.
Referenced by mutex_spin_wait(), rw_lock_s_lock_spin(), and rw_lock_x_lock_func().
00442 : wait array */ 00443 ulint index) /* in: index of the reserved cell */ 00444 { 00445 sync_cell_t* cell; 00446 os_event_t event; 00447 00448 ut_a(arr); 00449 00450 cell = sync_array_get_nth_cell(arr, index); 00451 00452 ut_a((cell->state == SC_RESERVED) || (cell->state == SC_WAKING_UP)); 00453 ut_a(cell->wait_object); 00454 ut_a(!cell->waiting); 00455 ut_ad(os_thread_get_curr_id() == cell->thread); 00456 00457 event = cell->event; 00458 cell->waiting = TRUE; 00459 00460 #ifdef UNIV_SYNC_DEBUG 00461 00462 /* We use simple enter to the mutex below, because if 00463 we cannot acquire it at once, mutex_enter would call 00464 recursively sync_array routines, leading to trouble. 00465 rw_lock_debug_mutex freezes the debug lists. */ 00466 00467 sync_array_enter(arr); 00468 rw_lock_debug_mutex_enter(); 00469 00470 if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) { 00471 00472 fputs("########################################\n", stderr); 00473 ut_error; 00474 } 00475 00476 rw_lock_debug_mutex_exit(); 00477 sync_array_exit(arr); 00478 #endif 00479 os_event_wait(event); 00480 00481 sync_array_free_cell(arr, index); 00482 }
Here is the call graph for this function:

Here is the caller graph for this function:

1.4.7

