~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2008-09-04 19:31:00 UTC
  • Revision ID: brian@tangent.org-20080904193100-l849hgghfy4urj43
Changing default character set from this point on.

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
say 200. In NT 3.51, allocating events seems to be a quadratic
41
41
algorithm, because 10 000 events are created fast, but
42
42
100 000 events takes a couple of minutes to create.
43
 
 
44
 
As of 5.0.30 the above mentioned design is changed. Since now
45
 
OS can handle millions of wait events efficiently, we no longer
46
 
have this concept of each cell of wait array having one event.
47
 
Instead, now the event that a thread wants to wait on is embedded
48
 
in the wait object (mutex or rw_lock). We still keep the global
49
 
wait array for the sake of diagnostics and also to avoid infinite
50
 
wait The error_monitor thread scans the global wait array to signal
51
 
any waiting threads who have missed the signal. */
 
43
*/
52
44
 
53
45
/* A cell where an individual thread may wait suspended
54
46
until a resource is released. The suspending is implemented
55
47
using an operating system event semaphore. */
56
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
 
53
        any mutex. */
 
54
        enum { SC_FREE, SC_RESERVED, SC_WAKING_UP } state;
 
55
 
57
56
        void*           wait_object;    /* pointer to the object the
58
 
                                        thread is waiting for; if NULL
59
 
                                        the cell is free for use */
 
57
                                        thread is waiting for; this is not
 
58
                                        reseted to NULL when a cell is
 
59
                                        freed. */
 
60
 
60
61
        mutex_t*        old_wait_mutex; /* the latest wait mutex in cell */
61
62
        rw_lock_t*      old_wait_rw_lock;/* the latest wait rw-lock in cell */
62
63
        ulint           request_type;   /* lock type requested on the
70
71
        ibool           waiting;        /* TRUE if the thread has already
71
72
                                        called sync_array_event_wait
72
73
                                        on this cell */
73
 
        ib_int64_t      signal_count;   /* We capture the signal_count
74
 
                                        of the wait_object when we
75
 
                                        reset the event. This value is
76
 
                                        then passed on to os_event_wait
77
 
                                        and we wait only if the event
78
 
                                        has not been signalled in the
79
 
                                        period between the reset and
80
 
                                        wait call. */
 
74
        ibool           event_set;      /* TRUE if the event is set */
 
75
        os_event_t      event;          /* operating system event
 
76
                                        semaphore handle */
81
77
        time_t          reservation_time;/* time when the thread reserved
82
78
                                        the wait cell */
83
79
};
84
80
 
85
 
/* NOTE: It is allowed for a thread to wait
86
 
for an event allocated for the array without owning the
87
 
protecting mutex (depending on the case: OS or database mutex), but
88
 
all changes (set or reset) to the state of the event must be made
89
 
while owning the mutex. */
90
81
struct sync_array_struct {
91
82
        ulint           n_reserved;     /* number of currently reserved
92
83
                                        cells in the wait array */
188
179
Creates a synchronization wait array. It is protected by a mutex
189
180
which is automatically reserved when the functions operating on it
190
181
are called. */
191
 
UNIV_INTERN
 
182
 
192
183
sync_array_t*
193
184
sync_array_create(
194
185
/*==============*/
229
220
 
230
221
        for (i = 0; i < n_cells; i++) {
231
222
                cell = sync_array_get_nth_cell(arr, i);
232
 
        cell->wait_object = NULL;
233
 
                cell->waiting = FALSE;
234
 
                cell->signal_count = 0;
 
223
                cell->state = SC_FREE;
 
224
                cell->wait_object = NULL;
 
225
 
 
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 */
235
229
        }
236
230
 
237
231
        return(arr);
239
233
 
240
234
/**********************************************************************
241
235
Frees the resources in a wait array. */
242
 
UNIV_INTERN
 
236
 
243
237
void
244
238
sync_array_free(
245
239
/*============*/
246
240
        sync_array_t*   arr)    /* in, own: sync wait array */
247
241
{
 
242
        ulint           i;
 
243
        sync_cell_t*    cell;
248
244
        ulint           protection;
249
245
 
250
246
        ut_a(arr->n_reserved == 0);
251
247
 
252
248
        sync_array_validate(arr);
253
249
 
 
250
        for (i = 0; i < arr->n_cells; i++) {
 
251
                cell = sync_array_get_nth_cell(arr, i);
 
252
                os_event_free(cell->event);
 
253
        }
 
254
 
254
255
        protection = arr->protection;
255
256
 
256
257
        /* Release the mutex protecting the wait array complex */
270
271
/************************************************************************
271
272
Validates the integrity of the wait array. Checks
272
273
that the number of reserved cells equals the count variable. */
273
 
UNIV_INTERN
 
274
 
274
275
void
275
276
sync_array_validate(
276
277
/*================*/
284
285
 
285
286
        for (i = 0; i < arr->n_cells; i++) {
286
287
                cell = sync_array_get_nth_cell(arr, i);
287
 
                if (cell->wait_object != NULL) {
 
288
 
 
289
                if (cell->state == SC_RESERVED) {
288
290
                        count++;
289
291
                }
290
292
        }
294
296
        sync_array_exit(arr);
295
297
}
296
298
 
297
 
/***********************************************************************
298
 
Puts the cell event in reset state. */
299
 
static
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 */
307
 
{
308
 
        if (type == SYNC_MUTEX) {
309
 
                return(os_event_reset(((mutex_t *) object)->event));
310
 
#ifdef __WIN__
311
 
        } else if (type == RW_LOCK_WAIT_EX) {
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));
317
 
        }
318
 
}
319
 
 
320
299
/**********************************************************************
321
300
Reserves a wait array cell for waiting for an object.
322
301
The event of the cell is reset to nonsignalled state. */
323
 
UNIV_INTERN
 
302
 
324
303
void
325
304
sync_array_reserve_cell(
326
305
/*====================*/
345
324
        for (i = 0; i < arr->n_cells; i++) {
346
325
                cell = sync_array_get_nth_cell(arr, i);
347
326
 
348
 
                if (cell->wait_object == NULL) {
349
 
 
350
 
                        cell->waiting = FALSE;
 
327
                if (cell->state == SC_FREE) {
 
328
 
 
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. */
 
334
 
 
335
                        cell->event_set = FALSE;
 
336
                        os_event_reset(cell->event);
 
337
 
 
338
                        cell->state = SC_RESERVED;
 
339
                        cell->reservation_time = time(NULL);
 
340
                        cell->thread = os_thread_get_curr_id();
 
341
 
351
342
                        cell->wait_object = object;
352
343
 
353
344
                        if (type == SYNC_MUTEX) {
357
348
                        }
358
349
 
359
350
                        cell->request_type = type;
 
351
                        cell->waiting = FALSE;
360
352
 
361
353
                        cell->file = file;
362
354
                        cell->line = line;
367
359
 
368
360
                        sync_array_exit(arr);
369
361
 
370
 
                        /* Make sure the event is reset and also store
371
 
                        the value of signal_count at which the event
372
 
                        was reset. */
373
 
                        cell->signal_count = sync_cell_event_reset(type,
374
 
                                                                object);
375
 
 
376
 
                        cell->reservation_time = time(NULL);
377
 
 
378
 
                        cell->thread = os_thread_get_curr_id();
379
 
 
380
362
                        return;
381
363
                }
382
364
        }
387
369
}
388
370
 
389
371
/**********************************************************************
 
372
Frees the cell. Note that we don't have any mutex reserved when calling
 
373
this. */
 
374
static
 
375
void
 
376
sync_array_free_cell(
 
377
/*=================*/
 
378
        sync_array_t*   arr,    /* in: wait array */
 
379
        ulint           index)  /* in: index of the cell in array */
 
380
{
 
381
        sync_cell_t*    cell;
 
382
 
 
383
        cell = sync_array_get_nth_cell(arr, index);
 
384
 
 
385
        ut_a(cell->state == SC_WAKING_UP);
 
386
        ut_a(cell->wait_object != NULL);
 
387
 
 
388
        cell->state = SC_FREE;
 
389
}
 
390
 
 
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. */
 
394
 
 
395
void
 
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 */
 
400
{
 
401
        sync_cell_t*    cell;
 
402
 
 
403
        sync_array_enter(arr);
 
404
 
 
405
        cell = sync_array_get_nth_cell(arr, index);
 
406
 
 
407
        ut_a(cell->state != SC_FREE);
 
408
        ut_a(cell->wait_object != NULL);
 
409
 
 
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);
 
414
                arr->n_reserved--;
 
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. */
 
422
 
 
423
                sync_array_exit(arr);
 
424
                os_event_wait(cell->event);
 
425
                sync_array_enter(arr);
 
426
        }
 
427
 
 
428
        cell->state = SC_FREE;
 
429
 
 
430
        sync_array_exit(arr);
 
431
}
 
432
 
 
433
/**********************************************************************
390
434
This function should be called when a thread starts to wait on
391
435
a wait array cell. In the debug version this function checks
392
436
if the wait for a semaphore will result in a deadlock, in which
393
437
case prints info and asserts. */
394
 
UNIV_INTERN
 
438
 
395
439
void
396
440
sync_array_wait_event(
397
441
/*==================*/
403
447
 
404
448
        ut_a(arr);
405
449
 
406
 
        sync_array_enter(arr);
407
 
 
408
450
        cell = sync_array_get_nth_cell(arr, index);
409
451
 
 
452
        ut_a((cell->state == SC_RESERVED) || (cell->state == SC_WAKING_UP));
410
453
        ut_a(cell->wait_object);
411
454
        ut_a(!cell->waiting);
412
455
        ut_ad(os_thread_get_curr_id() == cell->thread);
413
456
 
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
 
 
427
 
                cell->waiting = TRUE;
 
457
        event = cell->event;
 
458
        cell->waiting = TRUE;
428
459
 
429
460
#ifdef UNIV_SYNC_DEBUG
430
461
 
433
464
        recursively sync_array routines, leading to trouble.
434
465
        rw_lock_debug_mutex freezes the debug lists. */
435
466
 
 
467
        sync_array_enter(arr);
436
468
        rw_lock_debug_mutex_enter();
437
469
 
438
470
        if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) {
442
474
        }
443
475
 
444
476
        rw_lock_debug_mutex_exit();
 
477
        sync_array_exit(arr);
445
478
#endif
446
 
        sync_array_exit(arr);
447
 
 
448
 
        os_event_wait_low(event, cell->signal_count);
 
479
        os_event_wait(event);
449
480
 
450
481
        sync_array_free_cell(arr, index);
451
482
}
452
483
 
453
484
/**********************************************************************
454
 
Reports info of a wait array cell. */
 
485
Reports info of a wait array cell. Note: sync_array_print_long_waits()
 
486
calls this without mutex protection. */
455
487
static
456
488
void
457
489
sync_array_cell_print(
471
503
                (ulong) os_thread_pf(cell->thread), cell->file,
472
504
                (ulong) cell->line,
473
505
                difftime(time(NULL), cell->reservation_time));
474
 
 
475
 
        if (type == SYNC_MUTEX) {
 
506
        fprintf(file, "Wait array cell state %lu\n", (ulong)cell->state);
 
507
 
 
508
        /* If the memory area pointed to by old_wait_mutex /
 
509
        old_wait_rw_lock has been freed, this can crash. */
 
510
 
 
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. */
 
515
 
 
516
        } else if (type == SYNC_MUTEX) {
476
517
                /* We use old_wait_mutex in case the cell has already
477
518
                been freed meanwhile */
478
519
                mutex = cell->old_wait_mutex;
490
531
#endif /* UNIV_SYNC_DEBUG */
491
532
                        (ulong) mutex->waiters);
492
533
 
493
 
        } else if (type == RW_LOCK_EX
494
 
#ifdef __WIN__
495
 
                   || type == RW_LOCK_WAIT_EX
496
 
#endif
497
 
                   || type == RW_LOCK_SHARED) {
 
534
        } else if (type == RW_LOCK_EX || type == RW_LOCK_SHARED) {
498
535
 
499
536
                fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file);
500
537
 
528
565
                ut_error;
529
566
        }
530
567
 
531
 
        if (!cell->waiting) {
532
 
                fputs("wait has ended\n", file);
 
568
        if (cell->event_set) {
 
569
                fputs("wait is ending\n", file);
533
570
        }
534
571
}
535
572
 
552
589
 
553
590
                cell = sync_array_get_nth_cell(arr, i);
554
591
 
555
 
                if (cell->wait_object != NULL
 
592
                if ((cell->state == SC_RESERVED)
556
593
                    && os_thread_eq(cell->thread, thread)) {
557
594
 
558
595
                        return(cell);   /* Found */
642
679
 
643
680
        depth++;
644
681
 
645
 
        if (!cell->waiting) {
 
682
        if (cell->event_set || !cell->waiting) {
646
683
 
647
684
                return(FALSE); /* No deadlock here */
648
685
        }
667
704
                                                       depth);
668
705
                        if (ret) {
669
706
                                fprintf(stderr,
670
 
                        "Mutex %p owned by thread %lu file %s line %lu\n",
671
 
                                        mutex, (ulong) os_thread_pf(mutex->thread_id),
 
707
                                        "Mutex %p owned by thread %lu"
 
708
                                        " file %s line %lu\n",
 
709
                                        (void*) mutex,
 
710
                                        (ulong) os_thread_pf(mutex->thread_id),
672
711
                                        mutex->file_name, (ulong) mutex->line);
673
712
                                sync_array_cell_print(stderr, cell);
674
713
 
678
717
 
679
718
                return(FALSE); /* No deadlock */
680
719
 
681
 
        } else if (cell->request_type == RW_LOCK_EX
682
 
                   || cell->request_type == RW_LOCK_WAIT_EX) {
 
720
        } else if (cell->request_type == RW_LOCK_EX) {
683
721
 
684
722
                lock = cell->wait_object;
685
723
 
778
816
                        return(TRUE);
779
817
                }
780
818
 
781
 
        } else if (cell->request_type == RW_LOCK_EX
782
 
                   || cell->request_type == RW_LOCK_WAIT_EX) {
 
819
        } else if (cell->request_type == RW_LOCK_EX) {
783
820
 
784
821
                lock = cell->wait_object;
785
822
 
808
845
        return(FALSE);
809
846
}
810
847
 
811
 
/**********************************************************************
812
 
Frees the cell. NOTE! sync_array_wait_event frees the cell
813
 
automatically! */
814
 
UNIV_INTERN
 
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. */
 
853
 
815
854
void
816
 
sync_array_free_cell(
817
 
/*=================*/
 
855
sync_array_signal_object(
 
856
/*=====================*/
818
857
        sync_array_t*   arr,    /* in: wait array */
819
 
        ulint           index)  /* in: index of the cell in array */
 
858
        void*           object) /* in: wait object */
820
859
{
821
860
        sync_cell_t*    cell;
822
 
 
823
 
        sync_array_enter(arr);
824
 
 
825
 
        cell = sync_array_get_nth_cell(arr, index);
826
 
 
827
 
        ut_a(cell->wait_object != NULL);
828
 
 
829
 
        cell->waiting = FALSE;
830
 
        cell->wait_object =  NULL;
831
 
        cell->signal_count = 0;
832
 
 
833
 
        ut_a(arr->n_reserved > 0);
834
 
        arr->n_reserved--;
835
 
 
836
 
        sync_array_exit(arr);
837
 
}
838
 
 
839
 
/**************************************************************************
840
 
Increments the signalled count. */
841
 
UNIV_INTERN
842
 
void
843
 
sync_array_object_signalled(
844
 
/*========================*/
845
 
        sync_array_t*   arr)    /* in: wait array */
846
 
{
 
861
        ulint           count;
 
862
        ulint           i;
 
863
        ulint           res_count;
 
864
 
 
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. */
 
871
 
 
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);
 
876
 
 
877
        ut_a(100 == cell_max_count);
 
878
 
847
879
        sync_array_enter(arr);
848
880
 
849
881
        arr->sg_count++;
850
882
 
 
883
        i = 0;
 
884
        count = 0;
 
885
 
 
886
        /* We need to store this to a local variable because it is modified
 
887
        inside the loop */
 
888
        res_count = arr->n_reserved;
 
889
 
 
890
        while (count < res_count) {
 
891
 
 
892
                cell = sync_array_get_nth_cell(arr, i);
 
893
 
 
894
                if (cell->state == SC_RESERVED) {
 
895
 
 
896
                        count++;
 
897
                        if (cell->wait_object == object) {
 
898
                                cell->state = SC_WAKING_UP;
 
899
 
 
900
                                ut_a(arr->n_reserved > 0);
 
901
                                arr->n_reserved--;
 
902
 
 
903
                                if (cell_count == cell_max_count) {
 
904
                                        sync_cell_t** old_cell_ptr = cell_ptr;
 
905
                                        size_t old_size, new_size;
 
906
 
 
907
                                        old_size = cell_max_count
 
908
                                                * sizeof(sync_cell_t*);
 
909
                                        cell_max_count *= 2;
 
910
                                        new_size = cell_max_count
 
911
                                                * sizeof(sync_cell_t*);
 
912
 
 
913
                                        cell_ptr = malloc(new_size);
 
914
                                        ut_a(cell_ptr);
 
915
                                        memcpy(cell_ptr, old_cell_ptr,
 
916
                                               old_size);
 
917
 
 
918
                                        if (old_cell_ptr != &cells[0]) {
 
919
                                                free(old_cell_ptr);
 
920
                                        }
 
921
                                }
 
922
 
 
923
                                cell_ptr[cell_count] = cell;
 
924
                                cell_count++;
 
925
                        }
 
926
                }
 
927
 
 
928
                i++;
 
929
        }
 
930
 
851
931
        sync_array_exit(arr);
 
932
 
 
933
        for (i = 0; i < cell_count; i++) {
 
934
                cell = cell_ptr[i];
 
935
 
 
936
                cell->event_set = TRUE;
 
937
                os_event_set(cell->event);
 
938
        }
 
939
 
 
940
        if (cell_ptr != &cells[0]) {
 
941
                free(cell_ptr);
 
942
        }
852
943
}
853
944
 
854
945
/**************************************************************************
859
950
Note that there's a race condition between this thread and mutex_exit
860
951
changing the lock_word and calling signal_object, so sometimes this finds
861
952
threads to wake up even when nothing has gone wrong. */
862
 
UNIV_INTERN
 
953
 
863
954
void
864
955
sync_arr_wake_threads_if_sema_free(void)
865
956
/*====================================*/
868
959
        sync_cell_t*    cell;
869
960
        ulint           count;
870
961
        ulint           i;
 
962
        ulint           res_count;
871
963
 
872
964
        sync_array_enter(arr);
873
965
 
874
966
        i = 0;
875
967
        count = 0;
876
968
 
877
 
        while (count < arr->n_reserved) {
 
969
        /* We need to store this to a local variable because it is modified
 
970
        inside the loop */
 
971
 
 
972
        res_count = arr->n_reserved;
 
973
 
 
974
        while (count < res_count) {
878
975
 
879
976
                cell = sync_array_get_nth_cell(arr, i);
880
977
 
881
 
                if (cell->wait_object != NULL) {
 
978
                if (cell->state == SC_RESERVED) {
882
979
 
883
980
                        count++;
884
981
 
885
982
                        if (sync_arr_cell_can_wake_up(cell)) {
886
 
 
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
 
                                }
 
983
                                cell->state = SC_WAKING_UP;
 
984
                                cell->event_set = TRUE;
 
985
                                os_event_set(cell->event);
 
986
 
 
987
                                ut_a(arr->n_reserved > 0);
 
988
                                arr->n_reserved--;
906
989
                        }
907
990
                }
908
991
 
914
997
 
915
998
/**************************************************************************
916
999
Prints warnings of long semaphore waits to stderr. */
917
 
UNIV_INTERN
 
1000
 
918
1001
ibool
919
1002
sync_array_print_long_waits(void)
920
1003
/*=============================*/
932
1015
 
933
1016
                cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
934
1017
 
935
 
                if (cell->wait_object != NULL && cell->waiting
 
1018
                if ((cell->state != SC_FREE)
936
1019
                    && difftime(time(NULL), cell->reservation_time) > 240) {
937
1020
                        fputs("InnoDB: Warning: a long semaphore wait:\n",
938
1021
                              stderr);
940
1023
                        noticed = TRUE;
941
1024
                }
942
1025
 
943
 
                if (cell->wait_object != NULL && cell->waiting
 
1026
                if ((cell->state != SC_FREE)
944
1027
                    && difftime(time(NULL), cell->reservation_time)
945
1028
                    > fatal_timeout) {
946
1029
                        fatal = TRUE;
989
1072
                                mutex */
990
1073
{
991
1074
        sync_cell_t*    cell;
992
 
        ulint           count;
993
1075
        ulint           i;
994
1076
 
995
1077
        fprintf(file,
996
 
                "OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n",
997
 
                                                (long) arr->res_count, (long) arr->sg_count);
998
 
        i = 0;
999
 
        count = 0;
1000
 
 
1001
 
        while (count < arr->n_reserved) {
 
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++) {
1002
1083
 
1003
1084
                cell = sync_array_get_nth_cell(arr, i);
1004
1085
 
1005
 
        if (cell->wait_object != NULL) {
1006
 
                count++;
 
1086
                if (cell->state != SC_FREE) {
1007
1087
                        sync_array_cell_print(file, cell);
1008
1088
                }
1009
 
 
1010
 
                i++;
1011
1089
        }
1012
1090
}
1013
1091
 
1014
1092
/**************************************************************************
1015
1093
Prints info of the wait array. */
1016
 
UNIV_INTERN
 
1094
 
1017
1095
void
1018
1096
sync_array_print_info(
1019
1097
/*==================*/