~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2009-04-14 19:16:51 UTC
  • mto: (997.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 994.
  • Revision ID: mordred@inaugust.com-20090414191651-ltbww6hpqks8k7qk
Clarified instructions in README.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
*****************************************************************************/
25
25
 
26
 
/**************************************************//**
27
 
@file sync/sync0sync.c
 
26
/******************************************************
28
27
Mutex, the basic synchronization primitive
29
28
 
30
29
Created 9/5/1995 Heikki Tuuri
164
163
 
165
164
/* Number of spin waits on mutexes: for performance monitoring */
166
165
 
167
 
/** The number of iterations in the mutex_spin_wait() spin loop.
168
 
Intended for performance monitoring. */
169
 
static ib_int64_t       mutex_spin_round_count          = 0;
170
 
/** The number of mutex_spin_wait() calls.  Intended for
171
 
performance monitoring. */
172
 
static ib_int64_t       mutex_spin_wait_count           = 0;
173
 
/** The number of OS waits in mutex_spin_wait().  Intended for
174
 
performance monitoring. */
175
 
static ib_int64_t       mutex_os_wait_count             = 0;
176
 
/** The number of mutex_exit() calls. Intended for performance
177
 
monitoring. */
 
166
/* round=one iteration of a spin loop */
 
167
UNIV_INTERN ib_int64_t  mutex_spin_round_count          = 0;
 
168
UNIV_INTERN ib_int64_t  mutex_spin_wait_count           = 0;
 
169
UNIV_INTERN ib_int64_t  mutex_os_wait_count             = 0;
178
170
UNIV_INTERN ib_int64_t  mutex_exit_count                = 0;
179
171
 
180
 
/** The global array of wait cells for implementation of the database's own
 
172
/* The global array of wait cells for implementation of the database's own
181
173
mutexes and read-write locks */
182
174
UNIV_INTERN sync_array_t*       sync_primary_wait_array;
183
175
 
184
 
/** This variable is set to TRUE when sync_init is called */
 
176
/* This variable is set to TRUE when sync_init is called */
185
177
UNIV_INTERN ibool       sync_initialized        = FALSE;
186
178
 
187
 
/** An acquired mutex or rw-lock and its level in the latching order */
 
179
 
188
180
typedef struct sync_level_struct        sync_level_t;
189
 
/** Mutexes or rw-locks held by a thread */
190
181
typedef struct sync_thread_struct       sync_thread_t;
191
182
 
192
183
#ifdef UNIV_SYNC_DEBUG
193
 
/** The latch levels currently owned by threads are stored in this data
 
184
/* The latch levels currently owned by threads are stored in this data
194
185
structure; the size of this array is OS_THREAD_MAX_N */
195
186
 
196
187
UNIV_INTERN sync_thread_t*      sync_thread_level_arrays;
197
188
 
198
 
/** Mutex protecting sync_thread_level_arrays */
 
189
/* Mutex protecting sync_thread_level_arrays */
199
190
UNIV_INTERN mutex_t             sync_thread_mutex;
200
191
#endif /* UNIV_SYNC_DEBUG */
201
192
 
202
 
/** Global list of database mutexes (not OS mutexes) created. */
 
193
/* Global list of database mutexes (not OS mutexes) created. */
203
194
UNIV_INTERN ut_list_base_node_t  mutex_list;
204
195
 
205
 
/** Mutex protecting the mutex_list variable */
 
196
/* Mutex protecting the mutex_list variable */
206
197
UNIV_INTERN mutex_t mutex_list_mutex;
207
198
 
208
199
#ifdef UNIV_SYNC_DEBUG
209
 
/** Latching order checks start when this is set TRUE */
 
200
/* Latching order checks start when this is set TRUE */
210
201
UNIV_INTERN ibool       sync_order_checks_on    = FALSE;
211
202
#endif /* UNIV_SYNC_DEBUG */
212
203
 
213
 
/** Mutexes or rw-locks held by a thread */
214
204
struct sync_thread_struct{
215
 
        os_thread_id_t  id;     /*!< OS thread id */
216
 
        sync_level_t*   levels; /*!< level array for this thread; if
217
 
                                this is NULL this slot is unused */
 
205
        os_thread_id_t  id;     /* OS thread id */
 
206
        sync_level_t*   levels; /* level array for this thread; if this is NULL
 
207
                                this slot is unused */
218
208
};
219
209
 
220
 
/** Number of slots reserved for each OS thread in the sync level array */
 
210
/* Number of slots reserved for each OS thread in the sync level array */
221
211
#define SYNC_THREAD_N_LEVELS    10000
222
212
 
223
 
/** An acquired mutex or rw-lock and its level in the latching order */
224
213
struct sync_level_struct{
225
 
        void*   latch;  /*!< pointer to a mutex or an rw-lock; NULL means that
 
214
        void*   latch;  /* pointer to a mutex or an rw-lock; NULL means that
226
215
                        the slot is empty */
227
 
        ulint   level;  /*!< level of the latch in the latching order */
 
216
        ulint   level;  /* level of the latch in the latching order */
228
217
};
229
218
 
230
 
/******************************************************************//**
 
219
/**********************************************************************
231
220
Creates, or rather, initializes a mutex object in a specified memory
232
221
location (which must be appropriately aligned). The mutex is initialized
233
222
in the reset state. Explicit freeing of the mutex with mutex_free is
236
225
void
237
226
mutex_create_func(
238
227
/*==============*/
239
 
        mutex_t*        mutex,          /*!< in: pointer to memory */
 
228
        mutex_t*        mutex,          /* in: pointer to memory */
240
229
#ifdef UNIV_DEBUG
241
 
        const char*     cmutex_name,    /*!< in: mutex name */
 
230
        const char*     cmutex_name,    /* in: mutex name */
242
231
# ifdef UNIV_SYNC_DEBUG
243
 
        ulint           level,          /*!< in: level */
 
232
        ulint           level,          /* in: level */
244
233
# endif /* UNIV_SYNC_DEBUG */
245
234
#endif /* UNIV_DEBUG */
246
 
        const char*     cfile_name,     /*!< in: file name where created */
247
 
        ulint           cline)          /*!< in: file line where created */
 
235
        const char*     cfile_name,     /* in: file name where created */
 
236
        ulint           cline)          /* in: file line where created */
248
237
{
249
 
#if defined(HAVE_ATOMIC_BUILTINS)
 
238
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
 
239
        mutex_reset_lock_word(mutex);
 
240
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
250
241
        mutex_reset_lock_word(mutex);
251
242
#else
252
243
        os_fast_mutex_init(&(mutex->os_fast_mutex));
264
255
#endif /* UNIV_SYNC_DEBUG */
265
256
        mutex->cfile_name = cfile_name;
266
257
        mutex->cline = cline;
 
258
#ifndef UNIV_HOTBACKUP
267
259
        mutex->count_os_wait = 0;
268
 
#ifdef UNIV_DEBUG
 
260
# ifdef UNIV_DEBUG
269
261
        mutex->cmutex_name=       cmutex_name;
270
262
        mutex->count_using=       0;
271
263
        mutex->mutex_type=        0;
274
266
        mutex->count_spin_loop= 0;
275
267
        mutex->count_spin_rounds=   0;
276
268
        mutex->count_os_yield=  0;
277
 
#endif /* UNIV_DEBUG */
 
269
# endif /* UNIV_DEBUG */
 
270
#endif /* !UNIV_HOTBACKUP */
278
271
 
279
272
        /* Check that lock_word is aligned; this is important on Intel */
280
273
        ut_ad(((ulint)(&(mutex->lock_word))) % 4 == 0);
300
293
        mutex_exit(&mutex_list_mutex);
301
294
}
302
295
 
303
 
/******************************************************************//**
 
296
/**********************************************************************
304
297
Calling this function is obligatory only if the memory buffer containing
305
298
the mutex is freed. Removes a mutex object from the mutex list. The mutex
306
299
is checked to be in the reset state. */
308
301
void
309
302
mutex_free(
310
303
/*=======*/
311
 
        mutex_t*        mutex)  /*!< in: mutex */
 
304
        mutex_t*        mutex)  /* in: mutex */
312
305
{
313
306
        ut_ad(mutex_validate(mutex));
314
307
        ut_a(mutex_get_lock_word(mutex) == 0);
336
329
 
337
330
        os_event_free(mutex->event);
338
331
 
339
 
#if !defined(HAVE_ATOMIC_BUILTINS)
 
332
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
 
333
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
 
334
#else
340
335
        os_fast_mutex_free(&(mutex->os_fast_mutex));
341
336
#endif
342
337
        /* If we free the mutex protecting the mutex list (freeing is
347
342
#endif /* UNIV_DEBUG */
348
343
}
349
344
 
350
 
/********************************************************************//**
 
345
/************************************************************************
351
346
NOTE! Use the corresponding macro in the header file, not this function
352
347
directly. Tries to lock the mutex for the current thread. If the lock is not
353
 
acquired immediately, returns with return value 1.
354
 
@return 0 if succeed, 1 if not */
 
348
acquired immediately, returns with return value 1. */
355
349
UNIV_INTERN
356
350
ulint
357
351
mutex_enter_nowait_func(
358
352
/*====================*/
359
 
        mutex_t*        mutex,          /*!< in: pointer to mutex */
 
353
                                        /* out: 0 if succeed, 1 if not */
 
354
        mutex_t*        mutex,          /* in: pointer to mutex */
360
355
        const char*     file_name __attribute__((unused)),
361
 
                                        /*!< in: file name where mutex
 
356
                                        /* in: file name where mutex
362
357
                                        requested */
363
358
        ulint           line __attribute__((unused)))
364
 
                                        /*!< in: line where requested */
 
359
                                        /* in: line where requested */
365
360
{
366
361
        ut_ad(mutex_validate(mutex));
367
362
 
379
374
}
380
375
 
381
376
#ifdef UNIV_DEBUG
382
 
/******************************************************************//**
383
 
Checks that the mutex has been initialized.
384
 
@return TRUE */
 
377
/**********************************************************************
 
378
Checks that the mutex has been initialized. */
385
379
UNIV_INTERN
386
380
ibool
387
381
mutex_validate(
388
382
/*===========*/
389
 
        const mutex_t*  mutex)  /*!< in: mutex */
 
383
        const mutex_t*  mutex)
390
384
{
391
385
        ut_a(mutex);
392
386
        ut_a(mutex->magic_n == MUTEX_MAGIC_N);
394
388
        return(TRUE);
395
389
}
396
390
 
397
 
/******************************************************************//**
 
391
/**********************************************************************
398
392
Checks that the current thread owns the mutex. Works only in the debug
399
 
version.
400
 
@return TRUE if owns */
 
393
version. */
401
394
UNIV_INTERN
402
395
ibool
403
396
mutex_own(
404
397
/*======*/
405
 
        const mutex_t*  mutex)  /*!< in: mutex */
 
398
                                /* out: TRUE if owns */
 
399
        const mutex_t*  mutex)  /* in: mutex */
406
400
{
407
401
        ut_ad(mutex_validate(mutex));
408
402
 
411
405
}
412
406
#endif /* UNIV_DEBUG */
413
407
 
414
 
/******************************************************************//**
 
408
/**********************************************************************
415
409
Sets the waiters field in a mutex. */
416
410
UNIV_INTERN
417
411
void
418
412
mutex_set_waiters(
419
413
/*==============*/
420
 
        mutex_t*        mutex,  /*!< in: mutex */
421
 
        ulint           n)      /*!< in: value to set */
 
414
        mutex_t*        mutex,  /* in: mutex */
 
415
        ulint           n)      /* in: value to set */
422
416
{
423
417
        volatile ulint* ptr;            /* declared volatile to ensure that
424
418
                                        the value is stored to memory */
430
424
                                word in memory is atomic */
431
425
}
432
426
 
433
 
/******************************************************************//**
 
427
/**********************************************************************
434
428
Reserves a mutex for the current thread. If the mutex is reserved, the
435
429
function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
436
430
for the mutex before suspending the thread. */
438
432
void
439
433
mutex_spin_wait(
440
434
/*============*/
441
 
        mutex_t*        mutex,          /*!< in: pointer to mutex */
442
 
        const char*     file_name,      /*!< in: file name where mutex
 
435
        mutex_t*        mutex,          /* in: pointer to mutex */
 
436
        const char*     file_name,      /* in: file name where mutex
443
437
                                        requested */
444
 
        ulint           line)           /*!< in: line where requested */
 
438
        ulint           line)           /* in: line where requested */
445
439
{
446
440
        ulint      index; /* index of the reserved wait cell */
447
441
        ulint      i;     /* spin round count */
448
 
#ifdef UNIV_DEBUG
 
442
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
449
443
        ib_int64_t lstart_time = 0, lfinish_time; /* for timing os_wait */
450
444
        ulint ltime_diff;
451
445
        ulint sec;
452
446
        ulint ms;
453
447
        uint timer_started = 0;
454
 
#endif /* UNIV_DEBUG */
 
448
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
455
449
        ut_ad(mutex);
456
450
 
457
451
        /* This update is not thread safe, but we don't mind if the count
471
465
        a memory word. */
472
466
 
473
467
spin_loop:
474
 
        ut_d(mutex->count_spin_loop++);
 
468
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
 
469
        mutex->count_spin_loop++;
 
470
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
475
471
 
476
472
        while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) {
477
473
                if (srv_spin_wait_delay) {
482
478
        }
483
479
 
484
480
        if (i == SYNC_SPIN_ROUNDS) {
485
 
#ifdef UNIV_DEBUG
 
481
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
486
482
                mutex->count_os_yield++;
487
 
#ifndef UNIV_HOTBACKUP
488
 
                if (timed_mutexes && timer_started == 0) {
 
483
                if (timed_mutexes == 1 && timer_started==0) {
489
484
                        ut_usectime(&sec, &ms);
490
485
                        lstart_time= (ib_int64_t)sec * 1000000 + ms;
491
486
                        timer_started = 1;
492
487
                }
493
 
#endif /* UNIV_HOTBACKUP */
494
 
#endif /* UNIV_DEBUG */
 
488
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
495
489
                os_thread_yield();
496
490
        }
497
491
 
505
499
 
506
500
        mutex_spin_round_count += i;
507
501
 
508
 
        ut_d(mutex->count_spin_rounds += i);
 
502
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
 
503
        mutex->count_spin_rounds += i;
 
504
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
509
505
 
510
506
        if (mutex_test_and_set(mutex) == 0) {
511
507
                /* Succeeded! */
582
578
 
583
579
        mutex_os_wait_count++;
584
580
 
 
581
#ifndef UNIV_HOTBACKUP
585
582
        mutex->count_os_wait++;
586
 
#ifdef UNIV_DEBUG
 
583
# ifdef UNIV_DEBUG
587
584
        /* !!!!! Sometimes os_wait can be called without os_thread_yield */
588
 
#ifndef UNIV_HOTBACKUP
589
 
        if (timed_mutexes == 1 && timer_started == 0) {
 
585
 
 
586
        if (timed_mutexes == 1 && timer_started==0) {
590
587
                ut_usectime(&sec, &ms);
591
588
                lstart_time= (ib_int64_t)sec * 1000000 + ms;
592
589
                timer_started = 1;
593
590
        }
594
 
#endif /* UNIV_HOTBACKUP */
595
 
#endif /* UNIV_DEBUG */
 
591
# endif /* UNIV_DEBUG */
 
592
#endif /* !UNIV_HOTBACKUP */
596
593
 
597
594
        sync_array_wait_event(sync_primary_wait_array, index);
598
595
        goto mutex_loop;
599
596
 
600
597
finish_timing:
601
 
#ifdef UNIV_DEBUG
 
598
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
602
599
        if (timed_mutexes == 1 && timer_started==1) {
603
600
                ut_usectime(&sec, &ms);
604
601
                lfinish_time= (ib_int64_t)sec * 1000000 + ms;
610
607
                        mutex->lmax_spent_time= ltime_diff;
611
608
                }
612
609
        }
613
 
#endif /* UNIV_DEBUG */
 
610
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
614
611
        return;
615
612
}
616
613
 
617
 
/******************************************************************//**
 
614
/**********************************************************************
618
615
Releases the threads waiting in the primary wait array for this mutex. */
619
616
UNIV_INTERN
620
617
void
621
618
mutex_signal_object(
622
619
/*================*/
623
 
        mutex_t*        mutex)  /*!< in: mutex */
 
620
        mutex_t*        mutex)  /* in: mutex */
624
621
{
625
622
        mutex_set_waiters(mutex, 0);
626
623
 
631
628
}
632
629
 
633
630
#ifdef UNIV_SYNC_DEBUG
634
 
/******************************************************************//**
 
631
/**********************************************************************
635
632
Sets the debug information for a reserved mutex. */
636
633
UNIV_INTERN
637
634
void
638
635
mutex_set_debug_info(
639
636
/*=================*/
640
 
        mutex_t*        mutex,          /*!< in: mutex */
641
 
        const char*     file_name,      /*!< in: file where requested */
642
 
        ulint           line)           /*!< in: line where requested */
 
637
        mutex_t*        mutex,          /* in: mutex */
 
638
        const char*     file_name,      /* in: file where requested */
 
639
        ulint           line)           /* in: line where requested */
643
640
{
644
641
        ut_ad(mutex);
645
642
        ut_ad(file_name);
650
647
        mutex->line      = line;
651
648
}
652
649
 
653
 
/******************************************************************//**
 
650
/**********************************************************************
654
651
Gets the debug information for a reserved mutex. */
655
652
UNIV_INTERN
656
653
void
657
654
mutex_get_debug_info(
658
655
/*=================*/
659
 
        mutex_t*        mutex,          /*!< in: mutex */
660
 
        const char**    file_name,      /*!< out: file where requested */
661
 
        ulint*          line,           /*!< out: line where requested */
662
 
        os_thread_id_t* thread_id)      /*!< out: id of the thread which owns
 
656
        mutex_t*        mutex,          /* in: mutex */
 
657
        const char**    file_name,      /* out: file where requested */
 
658
        ulint*          line,           /* out: line where requested */
 
659
        os_thread_id_t* thread_id)      /* out: id of the thread which owns
663
660
                                        the mutex */
664
661
{
665
662
        ut_ad(mutex);
669
666
        *thread_id = mutex->thread_id;
670
667
}
671
668
 
672
 
/******************************************************************//**
 
669
/**********************************************************************
673
670
Prints debug info of currently reserved mutexes. */
674
671
static
675
672
void
676
673
mutex_list_print_info(
677
674
/*==================*/
678
 
        FILE*   file)           /*!< in: file where to print */
 
675
        FILE*   file)           /* in: file where to print */
679
676
{
680
677
        mutex_t*        mutex;
681
678
        const char*     file_name;
712
709
        mutex_exit(&mutex_list_mutex);
713
710
}
714
711
 
715
 
/******************************************************************//**
716
 
Counts currently reserved mutexes. Works only in the debug version.
717
 
@return number of reserved mutexes */
 
712
/**********************************************************************
 
713
Counts currently reserved mutexes. Works only in the debug version. */
718
714
UNIV_INTERN
719
715
ulint
720
716
mutex_n_reserved(void)
744
740
                           was holding one mutex (mutex_list_mutex) */
745
741
}
746
742
 
747
 
/******************************************************************//**
 
743
/**********************************************************************
748
744
Returns TRUE if no mutex or rw-lock is currently locked. Works only in
749
 
the debug version.
750
 
@return TRUE if no mutexes and rw-locks reserved */
 
745
the debug version. */
751
746
UNIV_INTERN
752
747
ibool
753
748
sync_all_freed(void)
756
751
        return(mutex_n_reserved() + rw_lock_n_locked() == 0);
757
752
}
758
753
 
759
 
/******************************************************************//**
760
 
Gets the value in the nth slot in the thread level arrays.
761
 
@return pointer to thread slot */
 
754
/**********************************************************************
 
755
Gets the value in the nth slot in the thread level arrays. */
762
756
static
763
757
sync_thread_t*
764
758
sync_thread_level_arrays_get_nth(
765
759
/*=============================*/
766
 
        ulint   n)      /*!< in: slot number */
 
760
                        /* out: pointer to thread slot */
 
761
        ulint   n)      /* in: slot number */
767
762
{
768
763
        ut_ad(n < OS_THREAD_MAX_N);
769
764
 
770
765
        return(sync_thread_level_arrays + n);
771
766
}
772
767
 
773
 
/******************************************************************//**
774
 
Looks for the thread slot for the calling thread.
775
 
@return pointer to thread slot, NULL if not found */
 
768
/**********************************************************************
 
769
Looks for the thread slot for the calling thread. */
776
770
static
777
771
sync_thread_t*
778
772
sync_thread_level_arrays_find_slot(void)
779
773
/*====================================*/
 
774
                        /* out: pointer to thread slot, NULL if not found */
780
775
 
781
776
{
782
777
        sync_thread_t*  slot;
798
793
        return(NULL);
799
794
}
800
795
 
801
 
/******************************************************************//**
802
 
Looks for an unused thread slot.
803
 
@return pointer to thread slot */
 
796
/**********************************************************************
 
797
Looks for an unused thread slot. */
804
798
static
805
799
sync_thread_t*
806
800
sync_thread_level_arrays_find_free(void)
807
801
/*====================================*/
 
802
                        /* out: pointer to thread slot */
808
803
 
809
804
{
810
805
        sync_thread_t*  slot;
823
818
        return(NULL);
824
819
}
825
820
 
826
 
/******************************************************************//**
827
 
Gets the value in the nth slot in the thread level array.
828
 
@return pointer to level slot */
 
821
/**********************************************************************
 
822
Gets the value in the nth slot in the thread level array. */
829
823
static
830
824
sync_level_t*
831
825
sync_thread_levels_get_nth(
832
826
/*=======================*/
833
 
        sync_level_t*   arr,    /*!< in: pointer to level array for an OS
 
827
                                /* out: pointer to level slot */
 
828
        sync_level_t*   arr,    /* in: pointer to level array for an OS
834
829
                                thread */
835
 
        ulint           n)      /*!< in: slot number */
 
830
        ulint           n)      /* in: slot number */
836
831
{
837
832
        ut_ad(n < SYNC_THREAD_N_LEVELS);
838
833
 
839
834
        return(arr + n);
840
835
}
841
836
 
842
 
/******************************************************************//**
 
837
/**********************************************************************
843
838
Checks if all the level values stored in the level array are greater than
844
 
the given limit.
845
 
@return TRUE if all greater */
 
839
the given limit. */
846
840
static
847
841
ibool
848
842
sync_thread_levels_g(
849
843
/*=================*/
850
 
        sync_level_t*   arr,    /*!< in: pointer to level array for an OS
 
844
                                /* out: TRUE if all greater */
 
845
        sync_level_t*   arr,    /* in: pointer to level array for an OS
851
846
                                thread */
852
 
        ulint           limit)  /*!< in: level limit */
 
847
        ulint           limit)  /* in: level limit */
853
848
{
854
849
        sync_level_t*   slot;
855
850
        rw_lock_t*      lock;
910
905
        return(TRUE);
911
906
}
912
907
 
913
 
/******************************************************************//**
914
 
Checks if the level value is stored in the level array.
915
 
@return TRUE if stored */
 
908
/**********************************************************************
 
909
Checks if the level value is stored in the level array. */
916
910
static
917
911
ibool
918
912
sync_thread_levels_contain(
919
913
/*=======================*/
920
 
        sync_level_t*   arr,    /*!< in: pointer to level array for an OS
 
914
                                /* out: TRUE if stored */
 
915
        sync_level_t*   arr,    /* in: pointer to level array for an OS
921
916
                                thread */
922
 
        ulint           level)  /*!< in: level */
 
917
        ulint           level)  /* in: level */
923
918
{
924
919
        sync_level_t*   slot;
925
920
        ulint           i;
939
934
        return(FALSE);
940
935
}
941
936
 
942
 
/******************************************************************//**
943
 
Checks that the level array for the current thread is empty.
944
 
@return TRUE if empty except the exceptions specified below */
 
937
/**********************************************************************
 
938
Checks that the level array for the current thread is empty. */
945
939
UNIV_INTERN
946
940
ibool
947
941
sync_thread_levels_empty_gen(
948
942
/*=========================*/
949
 
        ibool   dict_mutex_allowed)     /*!< in: TRUE if dictionary mutex is
 
943
                                        /* out: TRUE if empty except the
 
944
                                        exceptions specified below */
 
945
        ibool   dict_mutex_allowed)     /* in: TRUE if dictionary mutex is
950
946
                                        allowed to be owned by the thread,
951
947
                                        also purge_is_running mutex is
952
948
                                        allowed */
995
991
        return(TRUE);
996
992
}
997
993
 
998
 
/******************************************************************//**
999
 
Checks that the level array for the current thread is empty.
1000
 
@return TRUE if empty */
 
994
/**********************************************************************
 
995
Checks that the level array for the current thread is empty. */
1001
996
UNIV_INTERN
1002
997
ibool
1003
998
sync_thread_levels_empty(void)
1004
999
/*==========================*/
 
1000
                        /* out: TRUE if empty */
1005
1001
{
1006
1002
        return(sync_thread_levels_empty_gen(FALSE));
1007
1003
}
1008
1004
 
1009
 
/******************************************************************//**
 
1005
/**********************************************************************
1010
1006
Adds a latch and its level in the thread level array. Allocates the memory
1011
1007
for the array if called first time for this OS thread. Makes the checks
1012
1008
against other latch levels stored in the array for this thread. */
1014
1010
void
1015
1011
sync_thread_add_level(
1016
1012
/*==================*/
1017
 
        void*   latch,  /*!< in: pointer to a mutex or an rw-lock */
1018
 
        ulint   level)  /*!< in: level in the latching order; if
 
1013
        void*   latch,  /* in: pointer to a mutex or an rw-lock */
 
1014
        ulint   level)  /* in: level in the latching order; if
1019
1015
                        SYNC_LEVEL_VARYING, nothing is done */
1020
1016
{
1021
1017
        sync_level_t*   array;
1111
1107
                /* Either the thread must own the buffer pool mutex
1112
1108
                (buf_pool_mutex), or it is allowed to latch only ONE
1113
1109
                buffer block (block->mutex or buf_pool_zip_mutex). */
1114
 
                if (!sync_thread_levels_g(array, level)) {
1115
 
                        ut_a(sync_thread_levels_g(array, level - 1));
1116
 
                        ut_a(sync_thread_levels_contain(array, SYNC_BUF_POOL));
1117
 
                }
 
1110
                ut_a((sync_thread_levels_contain(array, SYNC_BUF_POOL)
 
1111
                      && sync_thread_levels_g(array, SYNC_BUF_BLOCK - 1))
 
1112
                     || sync_thread_levels_g(array, SYNC_BUF_BLOCK));
1118
1113
                break;
1119
1114
        case SYNC_REC_LOCK:
1120
1115
                ut_a((sync_thread_levels_contain(array, SYNC_KERNEL)
1206
1201
        mutex_exit(&sync_thread_mutex);
1207
1202
}
1208
1203
 
1209
 
/******************************************************************//**
1210
 
Removes a latch from the thread level array if it is found there.
1211
 
@return TRUE if found in the array; it is no error if the latch is
1212
 
not found, as we presently are not able to determine the level for
1213
 
every latch reservation the program does */
 
1204
/**********************************************************************
 
1205
Removes a latch from the thread level array if it is found there. */
1214
1206
UNIV_INTERN
1215
1207
ibool
1216
1208
sync_thread_reset_level(
1217
1209
/*====================*/
1218
 
        void*   latch)  /*!< in: pointer to a mutex or an rw-lock */
 
1210
                        /* out: TRUE if found from the array; it is an error
 
1211
                        if the latch is not found */
 
1212
        void*   latch)  /* in: pointer to a mutex or an rw-lock */
1219
1213
{
1220
1214
        sync_level_t*   array;
1221
1215
        sync_level_t*   slot;
1282
1276
}
1283
1277
#endif /* UNIV_SYNC_DEBUG */
1284
1278
 
1285
 
/******************************************************************//**
 
1279
/**********************************************************************
1286
1280
Initializes the synchronization data structures. */
1287
1281
UNIV_INTERN
1288
1282
void
1336
1330
#endif /* UNIV_SYNC_DEBUG */
1337
1331
}
1338
1332
 
1339
 
/******************************************************************//**
 
1333
/**********************************************************************
1340
1334
Frees the resources in InnoDB's own synchronization data structures. Use
1341
1335
os_sync_free() after calling this. */
1342
1336
UNIV_INTERN
1361
1355
#endif /* UNIV_SYNC_DEBUG */
1362
1356
}
1363
1357
 
1364
 
/*******************************************************************//**
 
1358
/***********************************************************************
1365
1359
Prints wait info of the sync system. */
1366
1360
UNIV_INTERN
1367
1361
void
1368
1362
sync_print_wait_info(
1369
1363
/*=================*/
1370
 
        FILE*   file)           /*!< in: file where to print */
 
1364
        FILE*   file)           /* in: file where to print */
1371
1365
{
1372
1366
#ifdef UNIV_SYNC_DEBUG
1373
1367
        fprintf(file, "Mutex exits %llu, rws exits %llu, rwx exits %llu\n",
1398
1392
                (rw_x_spin_wait_count ? rw_x_spin_wait_count : 1));
1399
1393
}
1400
1394
 
1401
 
/*******************************************************************//**
 
1395
/***********************************************************************
1402
1396
Prints info of the sync system. */
1403
1397
UNIV_INTERN
1404
1398
void
1405
1399
sync_print(
1406
1400
/*=======*/
1407
 
        FILE*   file)           /*!< in: file where to print */
 
1401
        FILE*   file)           /* in: file where to print */
1408
1402
{
1409
1403
#ifdef UNIV_SYNC_DEBUG
1410
1404
        mutex_list_print_info(file);