Skip to content

Commit 8b34aab

Browse files
committed
Follow-up to MDEV-12534: Align srv_sys
Allocate srv_sys statically so that the desired alignment can be guaranteed. This silences -fsanitize=undefined warnings. There probably is no performance impact of this, because the reason for the alignment to ensure the absence of false sharing between counters. Even with the misalignment, each counter would have been been aligned at 64 bits, and the counters would reside in separate cache lines.
1 parent 9f89b94 commit 8b34aab

File tree

2 files changed

+112
-143
lines changed

2 files changed

+112
-143
lines changed

storage/innobase/srv/srv0srv.cc

Lines changed: 53 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ UNIV_INTERN double srv_adaptive_flushing_lwm = 10.0;
293293
UNIV_INTERN ulong srv_flushing_avg_loops = 30;
294294

295295
/* The number of purge threads to use.*/
296-
UNIV_INTERN ulong srv_n_purge_threads = 1;
296+
UNIV_INTERN ulong srv_n_purge_threads;
297297

298298
/* the number of pages to purge in one batch */
299299
UNIV_INTERN ulong srv_purge_batch_size = 20;
@@ -490,16 +490,16 @@ UNIV_INTERN uint srv_simulate_comp_failures = 0;
490490

491491
/** Acquire the system_mutex. */
492492
#define srv_sys_mutex_enter() do { \
493-
mutex_enter(&srv_sys->mutex); \
493+
mutex_enter(&srv_sys.mutex); \
494494
} while (0)
495495

496496
/** Test if the system mutex is owned. */
497-
#define srv_sys_mutex_own() (mutex_own(&srv_sys->mutex) \
497+
#define srv_sys_mutex_own() (mutex_own(&srv_sys.mutex) \
498498
&& !srv_read_only_mode)
499499

500500
/** Release the system mutex. */
501501
#define srv_sys_mutex_exit() do { \
502-
mutex_exit(&srv_sys->mutex); \
502+
mutex_exit(&srv_sys.mutex); \
503503
} while (0)
504504

505505
#define fetch_lock_wait_timeout(trx) \
@@ -591,7 +591,7 @@ struct srv_sys_t{
591591
ulint n_sys_threads; /*!< size of the sys_threads
592592
array */
593593

594-
srv_slot_t* sys_threads; /*!< server thread table;
594+
srv_slot_t sys_threads[32 + 1]; /*!< server thread table;
595595
os_event_set() and
596596
os_event_reset() on
597597
sys_threads[]->event are
@@ -611,7 +611,7 @@ struct srv_sys_t{
611611
UNIV_INTERN ib_mutex_t server_mutex;
612612
#endif /* !HAVE_ATOMIC_BUILTINS */
613613

614-
static srv_sys_t* srv_sys = NULL;
614+
static srv_sys_t srv_sys;
615615

616616
/** Event to signal srv_monitor_thread. Not protected by a mutex.
617617
Set after setting srv_print_innodb_monitor. */
@@ -633,10 +633,10 @@ and/or load it during startup. */
633633
UNIV_INTERN char srv_buffer_pool_dump_at_shutdown = FALSE;
634634
UNIV_INTERN char srv_buffer_pool_load_at_startup = FALSE;
635635

636-
/** Slot index in the srv_sys->sys_threads array for the purge thread. */
636+
/** Slot index in the srv_sys.sys_threads array for the purge thread. */
637637
static const ulint SRV_PURGE_SLOT = 1;
638638

639-
/** Slot index in the srv_sys->sys_threads array for the master thread. */
639+
/** Slot index in the srv_sys.sys_threads array for the master thread. */
640640
static const ulint SRV_MASTER_SLOT = 0;
641641

642642
/*********************************************************************//**
@@ -737,21 +737,21 @@ srv_reserve_slot(
737737

738738
switch (type) {
739739
case SRV_MASTER:
740-
slot = &srv_sys->sys_threads[SRV_MASTER_SLOT];
740+
slot = &srv_sys.sys_threads[SRV_MASTER_SLOT];
741741
break;
742742

743743
case SRV_PURGE:
744-
slot = &srv_sys->sys_threads[SRV_PURGE_SLOT];
744+
slot = &srv_sys.sys_threads[SRV_PURGE_SLOT];
745745
break;
746746

747747
case SRV_WORKER:
748748
/* Find an empty slot, skip the master and purge slots. */
749-
for (slot = &srv_sys->sys_threads[2];
749+
for (slot = &srv_sys.sys_threads[2];
750750
slot->in_use;
751751
++slot) {
752752

753-
ut_a(slot < &srv_sys->sys_threads[
754-
srv_sys->n_sys_threads]);
753+
ut_a(slot < &srv_sys.sys_threads[
754+
srv_sys.n_sys_threads]);
755755
}
756756
break;
757757

@@ -767,7 +767,7 @@ srv_reserve_slot(
767767

768768
ut_ad(srv_slot_get_type(slot) == type);
769769

770-
++srv_sys->n_threads_active[type];
770+
++srv_sys.n_threads_active[type];
771771

772772
srv_sys_mutex_exit();
773773

@@ -797,27 +797,27 @@ srv_suspend_thread_low(
797797
case SRV_MASTER:
798798
/* We have only one master thread and it
799799
should be the first entry always. */
800-
ut_a(srv_sys->n_threads_active[type] == 1);
800+
ut_a(srv_sys.n_threads_active[type] == 1);
801801
break;
802802

803803
case SRV_PURGE:
804804
/* We have only one purge coordinator thread
805805
and it should be the second entry always. */
806-
ut_a(srv_sys->n_threads_active[type] == 1);
806+
ut_a(srv_sys.n_threads_active[type] == 1);
807807
break;
808808

809809
case SRV_WORKER:
810810
ut_a(srv_n_purge_threads > 1);
811-
ut_a(srv_sys->n_threads_active[type] > 0);
811+
ut_a(srv_sys.n_threads_active[type] > 0);
812812
break;
813813
}
814814

815815
ut_a(!slot->suspended);
816816
slot->suspended = TRUE;
817817

818-
ut_a(srv_sys->n_threads_active[type] > 0);
818+
ut_a(srv_sys.n_threads_active[type] > 0);
819819

820-
srv_sys->n_threads_active[type]--;
820+
srv_sys.n_threads_active[type]--;
821821

822822
return(os_event_reset(slot->event));
823823
}
@@ -872,7 +872,7 @@ srv_resume_thread(srv_slot_t* slot, ib_int64_t sig_count = 0, bool wait = true,
872872
ut_ad(slot->suspended);
873873

874874
slot->suspended = FALSE;
875-
++srv_sys->n_threads_active[slot->type];
875+
++srv_sys.n_threads_active[slot->type];
876876
srv_sys_mutex_exit();
877877
return(timeout);
878878
}
@@ -894,8 +894,8 @@ srv_release_threads(enum srv_thread_type type, ulint n)
894894

895895
srv_sys_mutex_enter();
896896

897-
for (ulint i = 0; i < srv_sys->n_sys_threads; i++) {
898-
srv_slot_t* slot = &srv_sys->sys_threads[i];
897+
for (ulint i = 0; i < srv_sys.n_sys_threads; i++) {
898+
srv_slot_t* slot = &srv_sys.sys_threads[i];
899899

900900
if (!slot->in_use || srv_slot_get_type(slot) != type) {
901901
continue;
@@ -915,7 +915,7 @@ srv_release_threads(enum srv_thread_type type, ulint n)
915915
should be the first entry always. */
916916
ut_a(n == 1);
917917
ut_a(i == SRV_MASTER_SLOT);
918-
ut_a(srv_sys->n_threads_active[type] == 0);
918+
ut_a(srv_sys.n_threads_active[type] == 0);
919919
break;
920920

921921
case SRV_PURGE:
@@ -924,12 +924,12 @@ srv_release_threads(enum srv_thread_type type, ulint n)
924924
ut_a(n == 1);
925925
ut_a(i == SRV_PURGE_SLOT);
926926
ut_a(srv_n_purge_threads > 0);
927-
ut_a(srv_sys->n_threads_active[type] == 0);
927+
ut_a(srv_sys.n_threads_active[type] == 0);
928928
break;
929929

930930
case SRV_WORKER:
931931
ut_a(srv_n_purge_threads > 1);
932-
ut_a(srv_sys->n_threads_active[type]
932+
ut_a(srv_sys.n_threads_active[type]
933933
< srv_n_purge_threads - 1);
934934
break;
935935
}
@@ -967,39 +967,26 @@ void
967967
srv_init(void)
968968
/*==========*/
969969
{
970-
ulint n_sys_threads = 0;
971-
ulint srv_sys_sz = sizeof(*srv_sys);
972-
973970
#ifndef HAVE_ATOMIC_BUILTINS
974971
mutex_create(server_mutex_key, &server_mutex, SYNC_ANY_LATCH);
975972
#endif /* !HAVE_ATOMIC_BUILTINS */
976973

977974
mutex_create(srv_innodb_monitor_mutex_key,
978975
&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
979976

980-
if (!srv_read_only_mode) {
981-
982-
/* Number of purge threads + master thread */
983-
n_sys_threads = srv_n_purge_threads + 1;
984-
985-
srv_sys_sz += n_sys_threads * sizeof(*srv_sys->sys_threads);
986-
}
987-
988-
srv_sys = static_cast<srv_sys_t*>(mem_zalloc(srv_sys_sz));
989-
990-
srv_sys->n_sys_threads = n_sys_threads;
977+
srv_sys.n_sys_threads = srv_read_only_mode
978+
? 0
979+
: srv_n_purge_threads + 1/* purge coordinator */;
991980

992981
if (!srv_read_only_mode) {
993982

994-
mutex_create(srv_sys_mutex_key, &srv_sys->mutex, SYNC_THREADS);
983+
mutex_create(srv_sys_mutex_key, &srv_sys.mutex, SYNC_THREADS);
995984

996985
mutex_create(srv_sys_tasks_mutex_key,
997-
&srv_sys->tasks_mutex, SYNC_ANY_LATCH);
998-
999-
srv_sys->sys_threads = (srv_slot_t*) &srv_sys[1];
986+
&srv_sys.tasks_mutex, SYNC_ANY_LATCH);
1000987

1001-
for (ulint i = 0; i < srv_sys->n_sys_threads; ++i) {
1002-
srv_slot_t* slot = &srv_sys->sys_threads[i];
988+
for (ulint i = 0; i < srv_sys.n_sys_threads; ++i) {
989+
srv_slot_t* slot = &srv_sys.sys_threads[i];
1003990

1004991
slot->event = os_event_create();
1005992

@@ -1048,10 +1035,8 @@ srv_free(void)
10481035
{
10491036
srv_conc_free();
10501037

1051-
/* The mutexes srv_sys->mutex and srv_sys->tasks_mutex should have
1038+
/* The mutexes srv_sys.mutex and srv_sys.tasks_mutex should have
10521039
been freed by sync_close() already. */
1053-
mem_free(srv_sys);
1054-
srv_sys = NULL;
10551040

10561041
trx_i_s_cache_free(trx_i_s_cache);
10571042

@@ -1882,7 +1867,7 @@ void
18821867
srv_inc_activity_count(void)
18831868
/*========================*/
18841869
{
1885-
srv_sys->activity_count.inc();
1870+
srv_sys.activity_count.inc();
18861871
}
18871872

18881873
/**********************************************************************//**
@@ -1904,7 +1889,7 @@ srv_get_active_thread_type(void)
19041889
srv_sys_mutex_enter();
19051890

19061891
for (ulint i = SRV_WORKER; i <= SRV_MASTER; ++i) {
1907-
if (srv_sys->n_threads_active[i] != 0) {
1892+
if (srv_sys.n_threads_active[i] != 0) {
19081893
ret = static_cast<srv_thread_type>(i);
19091894
break;
19101895
}
@@ -1977,12 +1962,12 @@ srv_active_wake_master_thread(void)
19771962

19781963
srv_inc_activity_count();
19791964

1980-
if (srv_sys->n_threads_active[SRV_MASTER] == 0) {
1965+
if (srv_sys.n_threads_active[SRV_MASTER] == 0) {
19811966
srv_slot_t* slot;
19821967

19831968
srv_sys_mutex_enter();
19841969

1985-
slot = &srv_sys->sys_threads[SRV_MASTER_SLOT];
1970+
slot = &srv_sys.sys_threads[SRV_MASTER_SLOT];
19861971

19871972
/* Only if the master thread has been started. */
19881973

@@ -2009,7 +1994,7 @@ srv_wake_purge_thread_if_not_active(void)
20091994
ut_ad(!srv_sys_mutex_own());
20101995

20111996
if (purge_sys->state == PURGE_STATE_RUN
2012-
&& srv_sys->n_threads_active[SRV_PURGE] == 0) {
1997+
&& srv_sys.n_threads_active[SRV_PURGE] == 0) {
20131998

20141999
srv_release_threads(SRV_PURGE, 1);
20152000
}
@@ -2038,7 +2023,7 @@ ulint
20382023
srv_get_activity_count(void)
20392024
/*========================*/
20402025
{
2041-
return(srv_sys->activity_count);
2026+
return(srv_sys.activity_count);
20422027
}
20432028

20442029
/*******************************************************************//**
@@ -2050,7 +2035,7 @@ srv_check_activity(
20502035
/*===============*/
20512036
ulint old_activity_count) /*!< in: old activity count */
20522037
{
2053-
return(srv_sys->activity_count != old_activity_count);
2038+
return(srv_sys.activity_count != old_activity_count);
20542039
}
20552040

20562041
/********************************************************************//**
@@ -2415,7 +2400,7 @@ DECLARE_THREAD(srv_master_thread)(
24152400
srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
24162401

24172402
slot = srv_reserve_slot(SRV_MASTER);
2418-
ut_a(slot == srv_sys->sys_threads);
2403+
ut_a(slot == srv_sys.sys_threads);
24192404

24202405
last_print_time = ut_time();
24212406
loop:
@@ -2505,18 +2490,18 @@ srv_task_execute(void)
25052490
ut_ad(!srv_read_only_mode);
25062491
ut_a(srv_force_recovery < SRV_FORCE_NO_BACKGROUND);
25072492

2508-
mutex_enter(&srv_sys->tasks_mutex);
2493+
mutex_enter(&srv_sys.tasks_mutex);
25092494

2510-
if (UT_LIST_GET_LEN(srv_sys->tasks) > 0) {
2495+
if (UT_LIST_GET_LEN(srv_sys.tasks) > 0) {
25112496

2512-
thr = UT_LIST_GET_FIRST(srv_sys->tasks);
2497+
thr = UT_LIST_GET_FIRST(srv_sys.tasks);
25132498

25142499
ut_a(que_node_get_type(thr->child) == QUE_NODE_PURGE);
25152500

2516-
UT_LIST_REMOVE(queue, srv_sys->tasks, thr);
2501+
UT_LIST_REMOVE(queue, srv_sys.tasks, thr);
25172502
}
25182503

2519-
mutex_exit(&srv_sys->tasks_mutex);
2504+
mutex_exit(&srv_sys.tasks_mutex);
25202505

25212506
if (thr != NULL) {
25222507

@@ -2556,7 +2541,7 @@ DECLARE_THREAD(srv_worker_thread)(
25562541

25572542
srv_sys_mutex_enter();
25582543

2559-
ut_a(srv_sys->n_threads_active[SRV_WORKER] < srv_n_purge_threads);
2544+
ut_a(srv_sys.n_threads_active[SRV_WORKER] < srv_n_purge_threads);
25602545

25612546
srv_sys_mutex_exit();
25622547

@@ -2885,11 +2870,11 @@ srv_que_task_enqueue_low(
28852870
que_thr_t* thr) /*!< in: query thread */
28862871
{
28872872
ut_ad(!srv_read_only_mode);
2888-
mutex_enter(&srv_sys->tasks_mutex);
2873+
mutex_enter(&srv_sys.tasks_mutex);
28892874

2890-
UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
2875+
UT_LIST_ADD_LAST(queue, srv_sys.tasks, thr);
28912876

2892-
mutex_exit(&srv_sys->tasks_mutex);
2877+
mutex_exit(&srv_sys.tasks_mutex);
28932878

28942879
srv_release_threads(SRV_WORKER, 1);
28952880
}
@@ -2906,11 +2891,11 @@ srv_get_task_queue_length(void)
29062891

29072892
ut_ad(!srv_read_only_mode);
29082893

2909-
mutex_enter(&srv_sys->tasks_mutex);
2894+
mutex_enter(&srv_sys.tasks_mutex);
29102895

2911-
n_tasks = UT_LIST_GET_LEN(srv_sys->tasks);
2896+
n_tasks = UT_LIST_GET_LEN(srv_sys.tasks);
29122897

2913-
mutex_exit(&srv_sys->tasks_mutex);
2898+
mutex_exit(&srv_sys.tasks_mutex);
29142899

29152900
return(n_tasks);
29162901
}

0 commit comments

Comments
 (0)