From 36e7538ff1f1a33bb466f8ffa8f6ca34dc4bc7b1 Mon Sep 17 00:00:00 2001 From: Derek Bruening Date: Wed, 16 Oct 2024 00:47:53 -0400 Subject: [PATCH] i#6938 sched migrate: Make initial_cur_time atomic (#7043) Fixes a race in the drmemtrace scheduler by making output_info_t.initial_cur_time atomic. Tested on ThreadSanitizer on the internal test where this was first reported. Issue: #6938 --- clients/drcachesim/scheduler/scheduler.cpp | 7 ++++--- clients/drcachesim/scheduler/scheduler.h | 7 ++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/clients/drcachesim/scheduler/scheduler.cpp b/clients/drcachesim/scheduler/scheduler.cpp index 752a140d8f3..7b3f885777c 100644 --- a/clients/drcachesim/scheduler/scheduler.cpp +++ b/clients/drcachesim/scheduler/scheduler.cpp @@ -2784,7 +2784,8 @@ scheduler_tmpl_t::pop_from_ready_queue_hold_locks( // For never-executed inputs we consider their last execution // to be the very first simulation time, which we can't // easily initialize until here. - res->last_run_time = outputs_[from_output].initial_cur_time; + res->last_run_time = outputs_[from_output].initial_cur_time->load( + std::memory_order_acquire); } VPRINT(this, 5, "migration check %d to %d: cur=%" PRIu64 " last=%" PRIu64 @@ -3800,8 +3801,8 @@ scheduler_tmpl_t::next_record(output_ordinal_t output, cur_time = 1 + outputs_[output].stream->get_output_instruction_ordinal() + outputs_[output].idle_count; } - if (outputs_[output].initial_cur_time == 0) { - outputs_[output].initial_cur_time = cur_time; + if (outputs_[output].initial_cur_time->load(std::memory_order_acquire) == 0) { + outputs_[output].initial_cur_time->store(cur_time, std::memory_order_release); } // Invalid values for cur_time are checked below. outputs_[output].cur_time->store(cur_time, std::memory_order_release); diff --git a/clients/drcachesim/scheduler/scheduler.h b/clients/drcachesim/scheduler/scheduler.h index 7a11b52e05e..e752839c1f8 100644 --- a/clients/drcachesim/scheduler/scheduler.h +++ b/clients/drcachesim/scheduler/scheduler.h @@ -1645,6 +1645,9 @@ template class scheduler_tmpl_t { cur_time = std::unique_ptr>(new std::atomic()); cur_time->store(0, std::memory_order_relaxed); + initial_cur_time = + std::unique_ptr>(new std::atomic()); + initial_cur_time->store(0, std::memory_order_relaxed); record_index = std::unique_ptr>(new std::atomic()); record_index->store(0, std::memory_order_relaxed); } @@ -1693,7 +1696,9 @@ template class scheduler_tmpl_t { // Indirected so we can store it in our vector. std::unique_ptr> cur_time; // The first simulation time passed to this output. - uint64_t initial_cur_time = 0; + // This is accessed by other outputs for stealing and rebalancing. + // Indirected so we can store it in our vector. + std::unique_ptr> initial_cur_time; // Used for MAP_TO_RECORDED_OUTPUT get_output_cpuid(). int64_t as_traced_cpuid = -1; // Used for MAP_AS_PREVIOUSLY with live_replay_output_count_.