Skip to content

Commit

Permalink
Follow-up to MDEV-12534: Align srv_sys
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dr-m committed May 17, 2017
1 parent 9f89b94 commit 8b34aab
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 143 deletions.
121 changes: 53 additions & 68 deletions storage/innobase/srv/srv0srv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ UNIV_INTERN double srv_adaptive_flushing_lwm = 10.0;
UNIV_INTERN ulong srv_flushing_avg_loops = 30;

/* The number of purge threads to use.*/
UNIV_INTERN ulong srv_n_purge_threads = 1;
UNIV_INTERN ulong srv_n_purge_threads;

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

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

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

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

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

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

static srv_sys_t* srv_sys = NULL;
static srv_sys_t srv_sys;

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

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

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

/*********************************************************************//**
Expand Down Expand Up @@ -737,21 +737,21 @@ srv_reserve_slot(

switch (type) {
case SRV_MASTER:
slot = &srv_sys->sys_threads[SRV_MASTER_SLOT];
slot = &srv_sys.sys_threads[SRV_MASTER_SLOT];
break;

case SRV_PURGE:
slot = &srv_sys->sys_threads[SRV_PURGE_SLOT];
slot = &srv_sys.sys_threads[SRV_PURGE_SLOT];
break;

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

ut_a(slot < &srv_sys->sys_threads[
srv_sys->n_sys_threads]);
ut_a(slot < &srv_sys.sys_threads[
srv_sys.n_sys_threads]);
}
break;

Expand All @@ -767,7 +767,7 @@ srv_reserve_slot(

ut_ad(srv_slot_get_type(slot) == type);

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

srv_sys_mutex_exit();

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

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

case SRV_WORKER:
ut_a(srv_n_purge_threads > 1);
ut_a(srv_sys->n_threads_active[type] > 0);
ut_a(srv_sys.n_threads_active[type] > 0);
break;
}

ut_a(!slot->suspended);
slot->suspended = TRUE;

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

srv_sys->n_threads_active[type]--;
srv_sys.n_threads_active[type]--;

return(os_event_reset(slot->event));
}
Expand Down Expand Up @@ -872,7 +872,7 @@ srv_resume_thread(srv_slot_t* slot, ib_int64_t sig_count = 0, bool wait = true,
ut_ad(slot->suspended);

slot->suspended = FALSE;
++srv_sys->n_threads_active[slot->type];
++srv_sys.n_threads_active[slot->type];
srv_sys_mutex_exit();
return(timeout);
}
Expand All @@ -894,8 +894,8 @@ srv_release_threads(enum srv_thread_type type, ulint n)

srv_sys_mutex_enter();

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

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

case SRV_PURGE:
Expand All @@ -924,12 +924,12 @@ srv_release_threads(enum srv_thread_type type, ulint n)
ut_a(n == 1);
ut_a(i == SRV_PURGE_SLOT);
ut_a(srv_n_purge_threads > 0);
ut_a(srv_sys->n_threads_active[type] == 0);
ut_a(srv_sys.n_threads_active[type] == 0);
break;

case SRV_WORKER:
ut_a(srv_n_purge_threads > 1);
ut_a(srv_sys->n_threads_active[type]
ut_a(srv_sys.n_threads_active[type]
< srv_n_purge_threads - 1);
break;
}
Expand Down Expand Up @@ -967,39 +967,26 @@ void
srv_init(void)
/*==========*/
{
ulint n_sys_threads = 0;
ulint srv_sys_sz = sizeof(*srv_sys);

#ifndef HAVE_ATOMIC_BUILTINS
mutex_create(server_mutex_key, &server_mutex, SYNC_ANY_LATCH);
#endif /* !HAVE_ATOMIC_BUILTINS */

mutex_create(srv_innodb_monitor_mutex_key,
&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);

if (!srv_read_only_mode) {

/* Number of purge threads + master thread */
n_sys_threads = srv_n_purge_threads + 1;

srv_sys_sz += n_sys_threads * sizeof(*srv_sys->sys_threads);
}

srv_sys = static_cast<srv_sys_t*>(mem_zalloc(srv_sys_sz));

srv_sys->n_sys_threads = n_sys_threads;
srv_sys.n_sys_threads = srv_read_only_mode
? 0
: srv_n_purge_threads + 1/* purge coordinator */;

if (!srv_read_only_mode) {

mutex_create(srv_sys_mutex_key, &srv_sys->mutex, SYNC_THREADS);
mutex_create(srv_sys_mutex_key, &srv_sys.mutex, SYNC_THREADS);

mutex_create(srv_sys_tasks_mutex_key,
&srv_sys->tasks_mutex, SYNC_ANY_LATCH);

srv_sys->sys_threads = (srv_slot_t*) &srv_sys[1];
&srv_sys.tasks_mutex, SYNC_ANY_LATCH);

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

slot->event = os_event_create();

Expand Down Expand Up @@ -1048,10 +1035,8 @@ srv_free(void)
{
srv_conc_free();

/* The mutexes srv_sys->mutex and srv_sys->tasks_mutex should have
/* The mutexes srv_sys.mutex and srv_sys.tasks_mutex should have
been freed by sync_close() already. */
mem_free(srv_sys);
srv_sys = NULL;

trx_i_s_cache_free(trx_i_s_cache);

Expand Down Expand Up @@ -1882,7 +1867,7 @@ void
srv_inc_activity_count(void)
/*========================*/
{
srv_sys->activity_count.inc();
srv_sys.activity_count.inc();
}

/**********************************************************************//**
Expand All @@ -1904,7 +1889,7 @@ srv_get_active_thread_type(void)
srv_sys_mutex_enter();

for (ulint i = SRV_WORKER; i <= SRV_MASTER; ++i) {
if (srv_sys->n_threads_active[i] != 0) {
if (srv_sys.n_threads_active[i] != 0) {
ret = static_cast<srv_thread_type>(i);
break;
}
Expand Down Expand Up @@ -1977,12 +1962,12 @@ srv_active_wake_master_thread(void)

srv_inc_activity_count();

if (srv_sys->n_threads_active[SRV_MASTER] == 0) {
if (srv_sys.n_threads_active[SRV_MASTER] == 0) {
srv_slot_t* slot;

srv_sys_mutex_enter();

slot = &srv_sys->sys_threads[SRV_MASTER_SLOT];
slot = &srv_sys.sys_threads[SRV_MASTER_SLOT];

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

Expand All @@ -2009,7 +1994,7 @@ srv_wake_purge_thread_if_not_active(void)
ut_ad(!srv_sys_mutex_own());

if (purge_sys->state == PURGE_STATE_RUN
&& srv_sys->n_threads_active[SRV_PURGE] == 0) {
&& srv_sys.n_threads_active[SRV_PURGE] == 0) {

srv_release_threads(SRV_PURGE, 1);
}
Expand Down Expand Up @@ -2038,7 +2023,7 @@ ulint
srv_get_activity_count(void)
/*========================*/
{
return(srv_sys->activity_count);
return(srv_sys.activity_count);
}

/*******************************************************************//**
Expand All @@ -2050,7 +2035,7 @@ srv_check_activity(
/*===============*/
ulint old_activity_count) /*!< in: old activity count */
{
return(srv_sys->activity_count != old_activity_count);
return(srv_sys.activity_count != old_activity_count);
}

/********************************************************************//**
Expand Down Expand Up @@ -2415,7 +2400,7 @@ DECLARE_THREAD(srv_master_thread)(
srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());

slot = srv_reserve_slot(SRV_MASTER);
ut_a(slot == srv_sys->sys_threads);
ut_a(slot == srv_sys.sys_threads);

last_print_time = ut_time();
loop:
Expand Down Expand Up @@ -2505,18 +2490,18 @@ srv_task_execute(void)
ut_ad(!srv_read_only_mode);
ut_a(srv_force_recovery < SRV_FORCE_NO_BACKGROUND);

mutex_enter(&srv_sys->tasks_mutex);
mutex_enter(&srv_sys.tasks_mutex);

if (UT_LIST_GET_LEN(srv_sys->tasks) > 0) {
if (UT_LIST_GET_LEN(srv_sys.tasks) > 0) {

thr = UT_LIST_GET_FIRST(srv_sys->tasks);
thr = UT_LIST_GET_FIRST(srv_sys.tasks);

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

UT_LIST_REMOVE(queue, srv_sys->tasks, thr);
UT_LIST_REMOVE(queue, srv_sys.tasks, thr);
}

mutex_exit(&srv_sys->tasks_mutex);
mutex_exit(&srv_sys.tasks_mutex);

if (thr != NULL) {

Expand Down Expand Up @@ -2556,7 +2541,7 @@ DECLARE_THREAD(srv_worker_thread)(

srv_sys_mutex_enter();

ut_a(srv_sys->n_threads_active[SRV_WORKER] < srv_n_purge_threads);
ut_a(srv_sys.n_threads_active[SRV_WORKER] < srv_n_purge_threads);

srv_sys_mutex_exit();

Expand Down Expand Up @@ -2885,11 +2870,11 @@ srv_que_task_enqueue_low(
que_thr_t* thr) /*!< in: query thread */
{
ut_ad(!srv_read_only_mode);
mutex_enter(&srv_sys->tasks_mutex);
mutex_enter(&srv_sys.tasks_mutex);

UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
UT_LIST_ADD_LAST(queue, srv_sys.tasks, thr);

mutex_exit(&srv_sys->tasks_mutex);
mutex_exit(&srv_sys.tasks_mutex);

srv_release_threads(SRV_WORKER, 1);
}
Expand All @@ -2906,11 +2891,11 @@ srv_get_task_queue_length(void)

ut_ad(!srv_read_only_mode);

mutex_enter(&srv_sys->tasks_mutex);
mutex_enter(&srv_sys.tasks_mutex);

n_tasks = UT_LIST_GET_LEN(srv_sys->tasks);
n_tasks = UT_LIST_GET_LEN(srv_sys.tasks);

mutex_exit(&srv_sys->tasks_mutex);
mutex_exit(&srv_sys.tasks_mutex);

return(n_tasks);
}
Expand Down
Loading

0 comments on commit 8b34aab

Please sign in to comment.