1
/*****************************************************************************
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
Copyright (c) 2008, Google Inc.
6
Portions of this file contain modifications contributed and copyrighted by
7
Google, Inc. Those modifications are gratefully acknowledged and are described
8
briefly in the InnoDB documentation. The contributions by Google are
9
incorporated with their permission, and subject to the conditions contained in
10
the file COPYING.Google.
12
This program is free software; you can redistribute it and/or modify it under
13
the terms of the GNU General Public License as published by the Free Software
14
Foundation; version 2 of the License.
16
This program is distributed in the hope that it will be useful, but WITHOUT
17
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License along with
21
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22
Place, Suite 330, Boston, MA 02111-1307 USA
24
*****************************************************************************/
26
1
/******************************************************
27
2
The wait array used in synchronization primitives
29
6
Created 9/5/1995 Heikki Tuuri
30
7
*******************************************************/
320
297
/***********************************************************************
321
Returns the event that the thread owning the cell waits for. */
298
Puts the cell event in reset state. */
326
sync_cell_t* cell) /* in: non-empty sync array cell */
301
sync_cell_event_reset(
302
/*==================*/
303
/* out: value of signal_count
304
at the time of reset. */
305
ulint type, /* in: lock type mutex/rw_lock */
306
void* object) /* in: the rw_lock/mutex object */
328
ulint type = cell->request_type;
330
308
if (type == SYNC_MUTEX) {
331
return(((mutex_t *) cell->wait_object)->event);
309
return(os_event_reset(((mutex_t *) object)->event));
332
311
} else if (type == RW_LOCK_WAIT_EX) {
333
return(((rw_lock_t *) cell->wait_object)->wait_ex_event);
334
} else { /* RW_LOCK_SHARED and RW_LOCK_EX wait on the same event */
335
return(((rw_lock_t *) cell->wait_object)->event);
312
return(os_event_reset(
313
((rw_lock_t *) object)->wait_ex_event));
316
return(os_event_reset(((rw_lock_t *) object)->event));
390
370
/* Make sure the event is reset and also store
391
371
the value of signal_count at which the event
393
event = sync_cell_get_event(cell);
394
cell->signal_count = os_event_reset(event);
373
cell->signal_count = sync_cell_event_reset(type,
396
376
cell->reservation_time = time(NULL);
431
411
ut_a(!cell->waiting);
432
412
ut_ad(os_thread_get_curr_id() == cell->thread);
434
event = sync_cell_get_event(cell);
414
if (cell->request_type == SYNC_MUTEX) {
415
event = ((mutex_t*) cell->wait_object)->event;
417
/* On windows if the thread about to wait is the one which
418
has set the state of the rw_lock to RW_LOCK_WAIT_EX, then
419
it waits on a special event i.e.: wait_ex_event. */
420
} else if (cell->request_type == RW_LOCK_WAIT_EX) {
421
event = ((rw_lock_t*) cell->wait_object)->wait_ex_event;
424
event = ((rw_lock_t*) cell->wait_object)->event;
435
427
cell->waiting = TRUE;
437
429
#ifdef UNIV_SYNC_DEBUG
500
491
(ulong) mutex->waiters);
502
493
} else if (type == RW_LOCK_EX
503
495
|| type == RW_LOCK_WAIT_EX
504
497
|| type == RW_LOCK_SHARED) {
506
499
fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file);
511
504
" RW-latch at %p created in file %s line %lu\n",
512
505
(void*) rwlock, rwlock->cfile_name,
513
506
(ulong) rwlock->cline);
514
writer = rw_lock_get_writer(rwlock);
515
if (writer != RW_LOCK_NOT_LOCKED) {
507
if (rwlock->writer != RW_LOCK_NOT_LOCKED) {
517
509
"a writer (thread id %lu) has"
518
510
" reserved it in mode %s",
519
511
(ulong) os_thread_pf(rwlock->writer_thread),
512
rwlock->writer == RW_LOCK_EX
522
514
: " wait exclusive\n");
526
"number of readers %lu, waiters flag %lu, "
518
"number of readers %lu, waiters flag %lu\n"
528
519
"Last time read locked in file %s line %lu\n"
529
520
"Last time write locked in file %s line %lu\n",
530
(ulong) rw_lock_get_reader_count(rwlock),
521
(ulong) rwlock->reader_count,
531
522
(ulong) rwlock->waiters,
533
523
rwlock->last_s_file_name,
534
524
(ulong) rwlock->last_s_line,
535
525
rwlock->last_x_file_name,
791
} else if (cell->request_type == RW_LOCK_EX) {
793
lock = cell->wait_object;
795
if (lock->lock_word > 0) {
796
/* Either unlocked or only read locked. */
801
} else if (cell->request_type == RW_LOCK_WAIT_EX) {
803
lock = cell->wait_object;
805
/* lock_word == 0 means all readers have left */
806
if (lock->lock_word == 0) {
781
} else if (cell->request_type == RW_LOCK_EX
782
|| cell->request_type == RW_LOCK_WAIT_EX) {
784
lock = cell->wait_object;
786
if (rw_lock_get_reader_count(lock) == 0
787
&& rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
792
if (rw_lock_get_reader_count(lock) == 0
793
&& rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX
794
&& os_thread_eq(lock->writer_thread, cell->thread)) {
810
799
} else if (cell->request_type == RW_LOCK_SHARED) {
811
800
lock = cell->wait_object;
813
/* lock_word > 0 means no writer or reserved writer */
814
if (lock->lock_word > 0) {
802
if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
856
844
/*========================*/
857
845
sync_array_t* arr) /* in: wait array */
859
#ifdef HAVE_GCC_ATOMIC_BUILTINS
860
(void) os_atomic_increment(&arr->sg_count, 1);
862
847
sync_array_enter(arr);
866
851
sync_array_exit(arr);
870
854
/**************************************************************************
894
877
while (count < arr->n_reserved) {
896
879
cell = sync_array_get_nth_cell(arr, i);
899
if (cell->wait_object == NULL) {
881
if (cell->wait_object != NULL) {
904
885
if (sync_arr_cell_can_wake_up(cell)) {
906
event = sync_cell_get_event(cell);
887
if (cell->request_type == SYNC_MUTEX) {
890
mutex = cell->wait_object;
891
os_event_set(mutex->event);
893
} else if (cell->request_type
894
== RW_LOCK_WAIT_EX) {
897
lock = cell->wait_object;
898
os_event_set(lock->wait_ex_event);
903
lock = cell->wait_object;
904
os_event_set(lock->event);
913
912
sync_array_exit(arr);