Skip to content

Commit

Permalink
i#6938 sched migrate: Add missing check for work stealing
Browse files Browse the repository at this point in the history
Add a missing check that we're doing a dynamic schedule before trying
to steal work when idle.  There don't seem to be any consequences from
the missing check but it is best to have it for clarity.

Issue: #6938
  • Loading branch information
derekbruening committed Oct 22, 2024
1 parent e9a983a commit 7b0fb9c
Showing 1 changed file with 26 additions and 21 deletions.
47 changes: 26 additions & 21 deletions clients/drcachesim/scheduler/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4368,29 +4368,34 @@ scheduler_tmpl_t<RecordType, ReaderType>::eof_or_idle(output_ordinal_t output,
live_inputs);
return sched_type_t::STATUS_EOF;
}
// Before going idle, try to steal work from another output.
// We start with us+1 to avoid everyone stealing from the low-numbered outputs.
// We only try when we first transition to idle; we rely on rebalancing after that,
// to avoid repeatededly grabbing other output's locks over and over.
if (!outputs_[output].tried_to_steal_on_idle) {
outputs_[output].tried_to_steal_on_idle = true;
for (unsigned int i = 1; i < outputs_.size(); ++i) {
output_ordinal_t target = (output + i) % outputs_.size();
assert(target != output); // Sanity check (we won't reach "output").
input_info_t *queue_next = nullptr;
sched_type_t::stream_status_t status =
pop_from_ready_queue(target, output, queue_next);
if (status == STATUS_OK && queue_next != nullptr) {
set_cur_input(output, queue_next->index);
++outputs_[output].stats[memtrace_stream_t::SCHED_STAT_RUNQUEUE_STEALS];
VPRINT(this, 2,
"eof_or_idle: output %d stole input %d from %d's ready_queue\n",
output, queue_next->index, target);
return STATUS_STOLE;
if (options_.mapping == MAP_TO_ANY_OUTPUT) {
// Before going idle, try to steal work from another output.
// We start with us+1 to avoid everyone stealing from the low-numbered outputs.
// We only try when we first transition to idle; we rely on rebalancing after
// that, to avoid repeatededly grabbing other output's locks over and over.
if (!outputs_[output].tried_to_steal_on_idle) {
outputs_[output].tried_to_steal_on_idle = true;
for (unsigned int i = 1; i < outputs_.size(); ++i) {
output_ordinal_t target = (output + i) % outputs_.size();
assert(target != output); // Sanity check (we won't reach "output").
input_info_t *queue_next = nullptr;
sched_type_t::stream_status_t status =
pop_from_ready_queue(target, output, queue_next);
if (status == STATUS_OK && queue_next != nullptr) {
set_cur_input(output, queue_next->index);
++outputs_[output]
.stats[memtrace_stream_t::SCHED_STAT_RUNQUEUE_STEALS];
VPRINT(
this, 2,
"eof_or_idle: output %d stole input %d from %d's ready_queue\n",
output, queue_next->index, target);
return STATUS_STOLE;
}
// We didn't find anything; loop and check another output.
}
// We didn't find anything; loop and check another output.
VPRINT(this, 3, "eof_or_idle: output %d failed to steal from anyone\n",
output);
}
VPRINT(this, 3, "eof_or_idle: output %d failed to steal from anyone\n", output);
}
// We rely on rebalancing to handle the case of every input being unscheduled.
outputs_[output].waiting = true;
Expand Down

0 comments on commit 7b0fb9c

Please sign in to comment.