~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/sync/sync0arr.c

  • Committer: Monty Taylor
  • Date: 2009-03-03 08:32:10 UTC
  • mfrom: (909 drizzle)
  • mto: This revision was merged to the branch mainline in revision 910.
  • Revision ID: mordred@inaugust.com-20090303083210-3cnjr53jspruighy
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
 
Copyright (c) 2008, Google Inc.
5
 
 
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.
11
 
 
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.
15
 
 
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.
19
 
 
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
23
 
 
24
 
*****************************************************************************/
25
 
 
26
1
/******************************************************
27
2
The wait array used in synchronization primitives
28
3
 
 
4
(c) 1995 Innobase Oy
 
5
 
29
6
Created 9/5/1995 Heikki Tuuri
30
7
*******************************************************/
31
8
 
318
295
}
319
296
 
320
297
/***********************************************************************
321
 
Returns the event that the thread owning the cell waits for. */
 
298
Puts the cell event in reset state. */
322
299
static
323
 
os_event_t
324
 
sync_cell_get_event(
325
 
/*================*/
326
 
        sync_cell_t*    cell) /* in: non-empty sync array cell */
 
300
ib_int64_t
 
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 */
327
307
{
328
 
        ulint type = cell->request_type;
329
 
 
330
308
        if (type == SYNC_MUTEX) {
331
 
                return(((mutex_t *) cell->wait_object)->event);
 
309
                return(os_event_reset(((mutex_t *) object)->event));
 
310
#ifdef __WIN__
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));
 
314
#endif
 
315
        } else {
 
316
                return(os_event_reset(((rw_lock_t *) object)->event));
336
317
        }
337
318
}
338
319
 
351
332
        ulint*          index)  /* out: index of the reserved cell */
352
333
{
353
334
        sync_cell_t*    cell;
354
 
        os_event_t      event;
355
335
        ulint           i;
356
336
 
357
337
        ut_a(object);
390
370
                        /* Make sure the event is reset and also store
391
371
                        the value of signal_count at which the event
392
372
                        was reset. */
393
 
                        event = sync_cell_get_event(cell);
394
 
                        cell->signal_count = os_event_reset(event);
 
373
                        cell->signal_count = sync_cell_event_reset(type,
 
374
                                                                object);
395
375
 
396
376
                        cell->reservation_time = time(NULL);
397
377
 
431
411
        ut_a(!cell->waiting);
432
412
        ut_ad(os_thread_get_curr_id() == cell->thread);
433
413
 
434
 
        event = sync_cell_get_event(cell);
 
414
        if (cell->request_type == SYNC_MUTEX) {
 
415
                event = ((mutex_t*) cell->wait_object)->event;
 
416
#ifdef __WIN__
 
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;
 
422
#endif
 
423
        } else {
 
424
                event = ((rw_lock_t*) cell->wait_object)->event;
 
425
        }
 
426
 
435
427
                cell->waiting = TRUE;
436
428
 
437
429
#ifdef UNIV_SYNC_DEBUG
470
462
        mutex_t*        mutex;
471
463
        rw_lock_t*      rwlock;
472
464
        ulint           type;
473
 
        ulint           writer;
474
465
 
475
466
        type = cell->request_type;
476
467
 
500
491
                        (ulong) mutex->waiters);
501
492
 
502
493
        } else if (type == RW_LOCK_EX
 
494
#ifdef __WIN__
503
495
                   || type == RW_LOCK_WAIT_EX
 
496
#endif
504
497
                   || type == RW_LOCK_SHARED) {
505
498
 
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) {
516
508
                        fprintf(file,
517
509
                                "a writer (thread id %lu) has"
518
510
                                " reserved it in mode %s",
519
511
                                (ulong) os_thread_pf(rwlock->writer_thread),
520
 
                                writer == RW_LOCK_EX
 
512
                                rwlock->writer == RW_LOCK_EX
521
513
                                ? " exclusive\n"
522
514
                                : " wait exclusive\n");
523
515
                }
524
516
 
525
517
                fprintf(file,
526
 
                        "number of readers %lu, waiters flag %lu, "
527
 
                        "lock_word: %lx\n"
 
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,
532
 
                        rwlock->lock_word,
533
523
                        rwlock->last_s_file_name,
534
524
                        (ulong) rwlock->last_s_line,
535
525
                        rwlock->last_x_file_name,
788
778
                        return(TRUE);
789
779
                }
790
780
 
791
 
        } else if (cell->request_type == RW_LOCK_EX) {
792
 
 
793
 
                lock = cell->wait_object;
794
 
 
795
 
                if (lock->lock_word > 0) {
796
 
                /* Either unlocked or only read locked. */
797
 
 
798
 
                        return(TRUE);
799
 
                }
800
 
 
801
 
        } else if (cell->request_type == RW_LOCK_WAIT_EX) {
802
 
 
803
 
                lock = cell->wait_object;
804
 
 
805
 
                /* lock_word == 0 means all readers have left */
806
 
                if (lock->lock_word == 0) {
807
 
 
808
 
                        return(TRUE);
809
 
                }
 
781
        } else if (cell->request_type == RW_LOCK_EX
 
782
                   || cell->request_type == RW_LOCK_WAIT_EX) {
 
783
 
 
784
                lock = cell->wait_object;
 
785
 
 
786
                if (rw_lock_get_reader_count(lock) == 0
 
787
                    && rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
 
788
 
 
789
                        return(TRUE);
 
790
                }
 
791
 
 
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)) {
 
795
 
 
796
                        return(TRUE);
 
797
                }
 
798
 
810
799
        } else if (cell->request_type == RW_LOCK_SHARED) {
811
800
                lock = cell->wait_object;
812
801
 
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) {
815
803
 
816
804
                        return(TRUE);
817
805
                }
856
844
/*========================*/
857
845
        sync_array_t*   arr)    /* in: wait array */
858
846
{
859
 
#ifdef HAVE_GCC_ATOMIC_BUILTINS
860
 
        (void) os_atomic_increment(&arr->sg_count, 1);
861
 
#else
862
847
        sync_array_enter(arr);
863
848
 
864
849
        arr->sg_count++;
865
850
 
866
851
        sync_array_exit(arr);
867
 
#endif
868
852
}
869
853
 
870
854
/**************************************************************************
884
868
        sync_cell_t*    cell;
885
869
        ulint           count;
886
870
        ulint           i;
887
 
        os_event_t      event;
888
871
 
889
872
        sync_array_enter(arr);
890
873
 
894
877
        while (count < arr->n_reserved) {
895
878
 
896
879
                cell = sync_array_get_nth_cell(arr, i);
897
 
                i++;
898
 
 
899
 
                if (cell->wait_object == NULL) {
900
 
                        continue;
901
 
                }
 
880
 
 
881
                if (cell->wait_object != NULL) {
 
882
 
902
883
                        count++;
903
884
 
904
885
                        if (sync_arr_cell_can_wake_up(cell)) {
905
886
 
906
 
                        event = sync_cell_get_event(cell);
907
 
 
908
 
                        os_event_set(event);
 
887
                                if (cell->request_type == SYNC_MUTEX) {
 
888
                                        mutex_t*        mutex;
 
889
 
 
890
                                        mutex = cell->wait_object;
 
891
                                        os_event_set(mutex->event);
 
892
#ifdef __WIN__
 
893
                                } else if (cell->request_type
 
894
                                           == RW_LOCK_WAIT_EX) {
 
895
                                        rw_lock_t*      lock;
 
896
 
 
897
                                        lock = cell->wait_object;
 
898
                                        os_event_set(lock->wait_ex_event);
 
899
#endif
 
900
                                } else {
 
901
                                        rw_lock_t*      lock;
 
902
 
 
903
                                        lock = cell->wait_object;
 
904
                                        os_event_set(lock->event);
 
905
                                }
 
906
                        }
909
907
                }
910
908
 
 
909
                i++;
911
910
        }
912
911
 
913
912
        sync_array_exit(arr);
1027
1026
 
1028
1027
        sync_array_exit(arr);
1029
1028
}
 
1029