Skip to content

Commit

Permalink
i#6959 unsched exit: Fix stay-unsched bug (#7011)
Browse files Browse the repository at this point in the history
Fixes a bug where an input that just went unscheduled indefinitely will
be resumed if there are no other inputs to run.

Adds a unit test that fails without the fix.

Issue: #6959, #6822
  • Loading branch information
derekbruening authored Sep 28, 2024
1 parent c38045a commit 85b547d
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 8 deletions.
13 changes: 5 additions & 8 deletions clients/drcachesim/scheduler/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3274,14 +3274,11 @@ scheduler_tmpl_t<RecordType, ReaderType>::pick_next_input(output_ordinal_t outpu
} else {
auto lock =
std::unique_lock<mutex_dbg_owned>(*inputs_[prev_index].lock);
// If we can't go back to the current input, we're EOF or idle.
// TODO i#6959: We should go the EOF/idle route if
// inputs_[prev_index].unscheduled as otherwise we're ignoring its
// unscheduled transition: although if there are no other threads
// at all (not just an empty queue) this turns into the
// eof_or_idle() all-unscheduled scenario. Once we have some kind
// of early exit option we'll add the unscheduled check here.
if (inputs_[prev_index].at_eof) {
// If we can't go back to the current input because it's EOF
// or unscheduled indefinitely (we already checked blocked_time
// above: it's 0 here), this output is either idle or EOF.
if (inputs_[prev_index].at_eof ||
inputs_[prev_index].unscheduled) {
lock.unlock();
sched_type_t::stream_status_t status =
eof_or_idle(output, prev_index);
Expand Down
57 changes: 57 additions & 0 deletions clients/drcachesim/tests/scheduler_unit_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5222,6 +5222,62 @@ test_unscheduled_small_timeout()
}
}

static void
test_unscheduled_no_alternative()
{
// Test that an unscheduled 0-timeout input is not incorrectly executed if
// there is nothing else to run (i#6959).
std::cerr << "\n----------------\nTesting unscheduled no alternative (i#6959)\n";
static constexpr int NUM_OUTPUTS = 1;
static constexpr uint64_t REBALANCE_PERIOD_US = 50;
static constexpr memref_tid_t TID_A = 100;
std::vector<trace_entry_t> refs_A = {
make_thread(TID_A),
make_pid(1),
make_version(TRACE_ENTRY_VERSION),
make_timestamp(1001),
make_marker(TRACE_MARKER_TYPE_CPU_ID, 0),
make_instr(/*pc=*/101),
make_timestamp(1002),
make_marker(TRACE_MARKER_TYPE_CPU_ID, 0),
make_marker(TRACE_MARKER_TYPE_SYSCALL, 999),
make_marker(TRACE_MARKER_TYPE_MAYBE_BLOCKING_SYSCALL, 0),
// No timeout means infinite (until the fallback kicks in).
make_marker(TRACE_MARKER_TYPE_SYSCALL_UNSCHEDULE, 0),
make_timestamp(2002),
make_instr(/*pc=*/102),
make_exit(TID_A),
};
{
std::vector<scheduler_t::input_reader_t> readers;
readers.emplace_back(std::unique_ptr<mock_reader_t>(new mock_reader_t(refs_A)),
std::unique_ptr<mock_reader_t>(new mock_reader_t()), TID_A);
static const char *const CORE0_SCHED_STRING =
"...A......__________________________________________________A.";

std::vector<scheduler_t::input_workload_t> sched_inputs;
sched_inputs.emplace_back(std::move(readers));
scheduler_t::scheduler_options_t sched_ops(scheduler_t::MAP_TO_ANY_OUTPUT,
scheduler_t::DEPENDENCY_TIMESTAMPS,
scheduler_t::SCHEDULER_DEFAULTS,
/*verbosity=*/3);
// We use our mock's time==instruction count for a deterministic result.
sched_ops.quantum_unit = scheduler_t::QUANTUM_TIME;
sched_ops.time_units_per_us = 1.;
sched_ops.rebalance_period_us = REBALANCE_PERIOD_US;
scheduler_t scheduler;
if (scheduler.init(sched_inputs, NUM_OUTPUTS, std::move(sched_ops)) !=
scheduler_t::STATUS_SUCCESS)
assert(false);
std::vector<std::string> sched_as_string =
run_lockstep_simulation(scheduler, NUM_OUTPUTS, TID_A, /*send_time=*/true);
for (int i = 0; i < NUM_OUTPUTS; i++) {
std::cerr << "cpu #" << i << " schedule: " << sched_as_string[i] << "\n";
}
assert(sched_as_string[0] == CORE0_SCHED_STRING);
}
}

static void
test_unscheduled()
{
Expand All @@ -5230,6 +5286,7 @@ test_unscheduled()
test_unscheduled_initially();
test_unscheduled_initially_roi();
test_unscheduled_small_timeout();
test_unscheduled_no_alternative();
}

static void
Expand Down

0 comments on commit 85b547d

Please sign in to comment.