~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

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
 
*/
 
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. */
44
52
 
45
53
/* A cell where an individual thread may wait suspended
46
54
until a resource is released. The suspending is implemented
47
55
using an operating system event semaphore. */
48
56
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
 
 
56
57
        void*           wait_object;    /* pointer to the object the
57
 
                                        thread is waiting for; this is not
58
 
                                        reseted to NULL when a cell is
59
 
                                        freed. */
60
 
 
 
58
                                        thread is waiting for; if NULL
 
59
                                        the cell is free for use */
61
60
        mutex_t*        old_wait_mutex; /* the latest wait mutex in cell */
62
61
        rw_lock_t*      old_wait_rw_lock;/* the latest wait rw-lock in cell */
63
62
        ulint           request_type;   /* lock type requested on the
71
70
        ibool           waiting;        /* TRUE if the thread has already
72
71
                                        called sync_array_event_wait
73
72
                                        on this cell */
74
 
        ibool           event_set;      /* TRUE if the event is set */
75
 
        os_event_t      event;          /* operating system event
76
 
                                        semaphore handle */
 
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. */
77
81
        time_t          reservation_time;/* time when the thread reserved
78
82
                                        the wait cell */
79
83
};
80
84
 
 
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. */
81
90
struct sync_array_struct {
82
91
        ulint           n_reserved;     /* number of currently reserved
83
92
                                        cells in the wait array */
179
188
Creates a synchronization wait array. It is protected by a mutex
180
189
which is automatically reserved when the functions operating on it
181
190
are called. */
182
 
 
 
191
UNIV_INTERN
183
192
sync_array_t*
184
193
sync_array_create(
185
194
/*==============*/
220
229
 
221
230
        for (i = 0; i < n_cells; i++) {
222
231
                cell = sync_array_get_nth_cell(arr, i);
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 */
 
232
        cell->wait_object = NULL;
 
233
                cell->waiting = FALSE;
 
234
                cell->signal_count = 0;
229
235
        }
230
236
 
231
237
        return(arr);
233
239
 
234
240
/**********************************************************************
235
241
Frees the resources in a wait array. */
236
 
 
 
242
UNIV_INTERN
237
243
void
238
244
sync_array_free(
239
245
/*============*/
240
246
        sync_array_t*   arr)    /* in, own: sync wait array */
241
247
{
242
 
        ulint           i;
243
 
        sync_cell_t*    cell;
244
248
        ulint           protection;
245
249
 
246
250
        ut_a(arr->n_reserved == 0);
247
251
 
248
252
        sync_array_validate(arr);
249
253
 
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
 
 
255
254
        protection = arr->protection;
256
255
 
257
256
        /* Release the mutex protecting the wait array complex */
271
270
/************************************************************************
272
271
Validates the integrity of the wait array. Checks
273
272
that the number of reserved cells equals the count variable. */
274
 
 
 
273
UNIV_INTERN
275
274
void
276
275
sync_array_validate(
277
276
/*================*/
285
284
 
286
285
        for (i = 0; i < arr->n_cells; i++) {
287
286
                cell = sync_array_get_nth_cell(arr, i);
288
 
 
289
 
                if (cell->state == SC_RESERVED) {
 
287
                if (cell->wait_object != NULL) {
290
288
                        count++;
291
289
                }
292
290
        }
296
294
        sync_array_exit(arr);
297
295
}
298
296
 
 
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
 
299
320
/**********************************************************************
300
321
Reserves a wait array cell for waiting for an object.
301
322
The event of the cell is reset to nonsignalled state. */
302
 
 
 
323
UNIV_INTERN
303
324
void
304
325
sync_array_reserve_cell(
305
326
/*====================*/
324
345
        for (i = 0; i < arr->n_cells; i++) {
325
346
                cell = sync_array_get_nth_cell(arr, i);
326
347
 
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
 
 
 
348
                if (cell->wait_object == NULL) {
 
349
 
 
350
                        cell->waiting = FALSE;
342
351
                        cell->wait_object = object;
343
352
 
344
353
                        if (type == SYNC_MUTEX) {
348
357
                        }
349
358
 
350
359
                        cell->request_type = type;
351
 
                        cell->waiting = FALSE;
352
360
 
353
361
                        cell->file = file;
354
362
                        cell->line = line;
359
367
 
360
368
                        sync_array_exit(arr);
361
369
 
 
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
 
362
380
                        return;
363
381
                }
364
382
        }
369
387
}
370
388
 
371
389
/**********************************************************************
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
 
/**********************************************************************
434
390
This function should be called when a thread starts to wait on
435
391
a wait array cell. In the debug version this function checks
436
392
if the wait for a semaphore will result in a deadlock, in which
437
393
case prints info and asserts. */
438
 
 
 
394
UNIV_INTERN
439
395
void
440
396
sync_array_wait_event(
441
397
/*==================*/
447
403
 
448
404
        ut_a(arr);
449
405
 
 
406
        sync_array_enter(arr);
 
407
 
450
408
        cell = sync_array_get_nth_cell(arr, index);
451
409
 
452
 
        ut_a((cell->state == SC_RESERVED) || (cell->state == SC_WAKING_UP));
453
410
        ut_a(cell->wait_object);
454
411
        ut_a(!cell->waiting);
455
412
        ut_ad(os_thread_get_curr_id() == cell->thread);
456
413
 
457
 
        event = cell->event;
458
 
        cell->waiting = TRUE;
 
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;
459
428
 
460
429
#ifdef UNIV_SYNC_DEBUG
461
430
 
464
433
        recursively sync_array routines, leading to trouble.
465
434
        rw_lock_debug_mutex freezes the debug lists. */
466
435
 
467
 
        sync_array_enter(arr);
468
436
        rw_lock_debug_mutex_enter();
469
437
 
470
438
        if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) {
474
442
        }
475
443
 
476
444
        rw_lock_debug_mutex_exit();
 
445
#endif
477
446
        sync_array_exit(arr);
478
 
#endif
479
 
        os_event_wait(event);
 
447
 
 
448
        os_event_wait_low(event, cell->signal_count);
480
449
 
481
450
        sync_array_free_cell(arr, index);
482
451
}
483
452
 
484
453
/**********************************************************************
485
 
Reports info of a wait array cell. Note: sync_array_print_long_waits()
486
 
calls this without mutex protection. */
 
454
Reports info of a wait array cell. */
487
455
static
488
456
void
489
457
sync_array_cell_print(
503
471
                (ulong) os_thread_pf(cell->thread), cell->file,
504
472
                (ulong) cell->line,
505
473
                difftime(time(NULL), cell->reservation_time));
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) {
 
474
 
 
475
        if (type == SYNC_MUTEX) {
517
476
                /* We use old_wait_mutex in case the cell has already
518
477
                been freed meanwhile */
519
478
                mutex = cell->old_wait_mutex;
531
490
#endif /* UNIV_SYNC_DEBUG */
532
491
                        (ulong) mutex->waiters);
533
492
 
534
 
        } else if (type == RW_LOCK_EX || type == RW_LOCK_SHARED) {
 
493
        } else if (type == RW_LOCK_EX
 
494
#ifdef __WIN__
 
495
                   || type == RW_LOCK_WAIT_EX
 
496
#endif
 
497
                   || type == RW_LOCK_SHARED) {
535
498
 
536
499
                fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file);
537
500
 
565
528
                ut_error;
566
529
        }
567
530
 
568
 
        if (cell->event_set) {
569
 
                fputs("wait is ending\n", file);
 
531
        if (!cell->waiting) {
 
532
                fputs("wait has ended\n", file);
570
533
        }
571
534
}
572
535
 
589
552
 
590
553
                cell = sync_array_get_nth_cell(arr, i);
591
554
 
592
 
                if ((cell->state == SC_RESERVED)
 
555
                if (cell->wait_object != NULL
593
556
                    && os_thread_eq(cell->thread, thread)) {
594
557
 
595
558
                        return(cell);   /* Found */
679
642
 
680
643
        depth++;
681
644
 
682
 
        if (cell->event_set || !cell->waiting) {
 
645
        if (!cell->waiting) {
683
646
 
684
647
                return(FALSE); /* No deadlock here */
685
648
        }
704
667
                                                       depth);
705
668
                        if (ret) {
706
669
                                fprintf(stderr,
707
 
                                        "Mutex %p owned by thread %lu"
708
 
                                        " file %s line %lu\n",
709
 
                                        (void*) mutex,
710
 
                                        (ulong) os_thread_pf(mutex->thread_id),
 
670
                        "Mutex %p owned by thread %lu file %s line %lu\n",
 
671
                                        mutex, (ulong) os_thread_pf(mutex->thread_id),
711
672
                                        mutex->file_name, (ulong) mutex->line);
712
673
                                sync_array_cell_print(stderr, cell);
713
674
 
717
678
 
718
679
                return(FALSE); /* No deadlock */
719
680
 
720
 
        } else if (cell->request_type == RW_LOCK_EX) {
 
681
        } else if (cell->request_type == RW_LOCK_EX
 
682
                   || cell->request_type == RW_LOCK_WAIT_EX) {
721
683
 
722
684
                lock = cell->wait_object;
723
685
 
816
778
                        return(TRUE);
817
779
                }
818
780
 
819
 
        } else if (cell->request_type == RW_LOCK_EX) {
 
781
        } else if (cell->request_type == RW_LOCK_EX
 
782
                   || cell->request_type == RW_LOCK_WAIT_EX) {
820
783
 
821
784
                lock = cell->wait_object;
822
785
 
845
808
        return(FALSE);
846
809
}
847
810
 
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
 
 
 
811
/**********************************************************************
 
812
Frees the cell. NOTE! sync_array_wait_event frees the cell
 
813
automatically! */
 
814
UNIV_INTERN
854
815
void
855
 
sync_array_signal_object(
856
 
/*=====================*/
 
816
sync_array_free_cell(
 
817
/*=================*/
857
818
        sync_array_t*   arr,    /* in: wait array */
858
 
        void*           object) /* in: wait object */
 
819
        ulint           index)  /* in: index of the cell in array */
859
820
{
860
821
        sync_cell_t*    cell;
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
 
 
 
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
{
879
847
        sync_array_enter(arr);
880
848
 
881
849
        arr->sg_count++;
882
850
 
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
 
 
931
851
        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
 
        }
943
852
}
944
853
 
945
854
/**************************************************************************
950
859
Note that there's a race condition between this thread and mutex_exit
951
860
changing the lock_word and calling signal_object, so sometimes this finds
952
861
threads to wake up even when nothing has gone wrong. */
953
 
 
 
862
UNIV_INTERN
954
863
void
955
864
sync_arr_wake_threads_if_sema_free(void)
956
865
/*====================================*/
959
868
        sync_cell_t*    cell;
960
869
        ulint           count;
961
870
        ulint           i;
962
 
        ulint           res_count;
963
871
 
964
872
        sync_array_enter(arr);
965
873
 
966
874
        i = 0;
967
875
        count = 0;
968
876
 
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) {
 
877
        while (count < arr->n_reserved) {
975
878
 
976
879
                cell = sync_array_get_nth_cell(arr, i);
977
880
 
978
 
                if (cell->state == SC_RESERVED) {
 
881
                if (cell->wait_object != NULL) {
979
882
 
980
883
                        count++;
981
884
 
982
885
                        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);
986
 
 
987
 
                                ut_a(arr->n_reserved > 0);
988
 
                                arr->n_reserved--;
 
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
                                }
989
906
                        }
990
907
                }
991
908
 
997
914
 
998
915
/**************************************************************************
999
916
Prints warnings of long semaphore waits to stderr. */
1000
 
 
 
917
UNIV_INTERN
1001
918
ibool
1002
919
sync_array_print_long_waits(void)
1003
920
/*=============================*/
1015
932
 
1016
933
                cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
1017
934
 
1018
 
                if ((cell->state != SC_FREE)
 
935
                if (cell->wait_object != NULL && cell->waiting
1019
936
                    && difftime(time(NULL), cell->reservation_time) > 240) {
1020
937
                        fputs("InnoDB: Warning: a long semaphore wait:\n",
1021
938
                              stderr);
1023
940
                        noticed = TRUE;
1024
941
                }
1025
942
 
1026
 
                if ((cell->state != SC_FREE)
 
943
                if (cell->wait_object != NULL && cell->waiting
1027
944
                    && difftime(time(NULL), cell->reservation_time)
1028
945
                    > fatal_timeout) {
1029
946
                        fatal = TRUE;
1072
989
                                mutex */
1073
990
{
1074
991
        sync_cell_t*    cell;
 
992
        ulint           count;
1075
993
        ulint           i;
1076
994
 
1077
995
        fprintf(file,
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++) {
 
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) {
1083
1002
 
1084
1003
                cell = sync_array_get_nth_cell(arr, i);
1085
1004
 
1086
 
                if (cell->state != SC_FREE) {
 
1005
        if (cell->wait_object != NULL) {
 
1006
                count++;
1087
1007
                        sync_array_cell_print(file, cell);
1088
1008
                }
 
1009
 
 
1010
                i++;
1089
1011
        }
1090
1012
}
1091
1013
 
1092
1014
/**************************************************************************
1093
1015
Prints info of the wait array. */
1094
 
 
 
1016
UNIV_INTERN
1095
1017
void
1096
1018
sync_array_print_info(
1097
1019
/*==================*/