Skip to content

Commit

Permalink
Merge branch 'master' into i6678-rename-ci-aarchxx-cross-workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
xdje42 authored Mar 12, 2024
2 parents 8644d24 + 2d2cd90 commit a60ec81
Show file tree
Hide file tree
Showing 30 changed files with 447 additions and 137 deletions.
2 changes: 2 additions & 0 deletions clients/drcachesim/common/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ namespace drmemtrace {

// XXX: DR should export this
#define INVALID_THREAD_ID 0
// We avoid collisions with DR's INVALID_PROCESS_ID by using our own name.
#define INVALID_PID -1

// XXX: perhaps we should use a C++-ish stream approach instead
// This cannot be named ERROR as that conflicts with Windows headers.
Expand Down
4 changes: 2 additions & 2 deletions clients/drcachesim/reader/record_file_reader.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2022-2023 Google, Inc. All rights reserved.
* Copyright (c) 2022-2024 Google, Inc. All rights reserved.
* **********************************************************/

/*
Expand Down Expand Up @@ -126,7 +126,7 @@ class record_reader_t : public std::iterator<std::input_iterator_tag, trace_entr
virtual ~record_reader_t()
{
}
bool
virtual bool
init()
{
if (!open_input_file())
Expand Down
117 changes: 112 additions & 5 deletions clients/drcachesim/scheduler/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,17 @@ scheduler_tmpl_t<memref_t, reader_t>::record_type_has_tid(memref_t record,
return true;
}

template <>
bool
scheduler_tmpl_t<memref_t, reader_t>::record_type_has_pid(memref_t record,
memref_pid_t &pid)
{
if (record.marker.pid == INVALID_PID)
return false;
pid = record.marker.pid;
return true;
}

template <>
void
scheduler_tmpl_t<memref_t, reader_t>::record_type_set_tid(memref_t &record,
Expand All @@ -222,6 +233,23 @@ scheduler_tmpl_t<memref_t, reader_t>::record_type_is_instr(memref_t record)
return type_is_instr(record.instr.type);
}

template <>
bool
scheduler_tmpl_t<memref_t, reader_t>::record_type_is_encoding(memref_t record)
{
// There are no separate memref_t encoding records: encoding info is
// inside instruction records.
return false;
}

template <>
bool
scheduler_tmpl_t<memref_t, reader_t>::record_type_is_instr_boundary(memref_t record,
memref_t prev_record)
{
return record_type_is_instr(record);
}

template <>
bool
scheduler_tmpl_t<memref_t, reader_t>::record_type_is_marker(memref_t record,
Expand Down Expand Up @@ -302,6 +330,13 @@ scheduler_tmpl_t<memref_t, reader_t>::print_record(const memref_t &record)
fprintf(stderr, "\n");
}

template <>
void
scheduler_tmpl_t<memref_t, reader_t>::insert_switch_tid_pid(input_info_t &info)
{
// We do nothing, as every record has a tid from the separate inputs.
}

/******************************************************************************
* Specializations for scheduler_tmpl_t<record_reader_t>, aka record_scheduler_t.
*/
Expand Down Expand Up @@ -343,6 +378,17 @@ scheduler_tmpl_t<trace_entry_t, record_reader_t>::record_type_has_tid(
return true;
}

template <>
bool
scheduler_tmpl_t<trace_entry_t, record_reader_t>::record_type_has_pid(
trace_entry_t record, memref_pid_t &pid)
{
if (record.type != TRACE_TYPE_PID)
return false;
pid = static_cast<memref_pid_t>(record.addr);
return true;
}

template <>
void
scheduler_tmpl_t<trace_entry_t, record_reader_t>::record_type_set_tid(
Expand All @@ -361,6 +407,34 @@ scheduler_tmpl_t<trace_entry_t, record_reader_t>::record_type_is_instr(
return type_is_instr(static_cast<trace_type_t>(record.type));
}

template <>
bool
scheduler_tmpl_t<trace_entry_t, record_reader_t>::record_type_is_encoding(
trace_entry_t record)
{
return static_cast<trace_type_t>(record.type) == TRACE_TYPE_ENCODING;
}

template <>
bool
scheduler_tmpl_t<trace_entry_t, record_reader_t>::record_type_is_instr_boundary(
trace_entry_t record, trace_entry_t prev_record)
{
// Don't advance past encodings and split them from their associated instr.
return (record_type_is_instr(record) || record_type_is_encoding(record)) &&
!record_type_is_encoding(prev_record);
}

template <>
typename scheduler_tmpl_t<trace_entry_t, record_reader_t>::stream_status_t
scheduler_tmpl_t<trace_entry_t, record_reader_t>::unread_last_record(
output_ordinal_t output, trace_entry_t &record, input_info_t *&input)
{
// See the general unread_last_record() below: we don't support this as
// we can't provide the prev-prev record for record_type_is_instr_boundary().
return STATUS_NOT_IMPLEMENTED;
}

template <>
bool
scheduler_tmpl_t<trace_entry_t, record_reader_t>::record_type_is_marker(
Expand Down Expand Up @@ -437,6 +511,27 @@ scheduler_tmpl_t<trace_entry_t, record_reader_t>::print_record(
record.addr);
}

template <>
void
scheduler_tmpl_t<trace_entry_t, record_reader_t>::insert_switch_tid_pid(
input_info_t &input)
{
// We need explicit tid,pid records so reader_t will see the new context.
// We insert at the front, so we have reverse order.
trace_entry_t pid;
pid.type = TRACE_TYPE_PID;
pid.size = 0;
pid.addr = static_cast<addr_t>(input.pid);

trace_entry_t tid;
tid.type = TRACE_TYPE_THREAD;
tid.size = 0;
tid.addr = static_cast<addr_t>(input.tid);

input.queue.push_front(pid);
input.queue.push_front(tid);
}

/***************************************************************************
* Scheduled stream.
*/
Expand Down Expand Up @@ -1470,7 +1565,8 @@ scheduler_tmpl_t<RecordType, ReaderType>::get_tid(output_ordinal_t output)
int index = outputs_[output].cur_input;
if (index < 0)
return -1;
if (inputs_[index].is_combined_stream())
if (inputs_[index].is_combined_stream() ||
TESTANY(OFFLINE_FILE_TYPE_CORE_SHARDED, inputs_[index].reader->get_filetype()))
return inputs_[index].last_record_tid;
return inputs_[index].tid;
}
Expand Down Expand Up @@ -2035,6 +2131,10 @@ scheduler_tmpl_t<RecordType, ReaderType>::set_cur_input(output_ordinal_t output,
outputs_[output].stream->filetype_ = inputs_[input].reader->get_filetype();
}

if (inputs_[input].pid != INVALID_PID) {
insert_switch_tid_pid(inputs_[input]);
}

if (!switch_sequence_.empty() &&
outputs_[output].stream->get_instruction_ordinal() > 0) {
sched_type_t::switch_type_t switch_type = SWITCH_INVALID;
Expand Down Expand Up @@ -2583,7 +2683,8 @@ scheduler_tmpl_t<RecordType, ReaderType>::next_record(output_ordinal_t output,
} else {
input->switch_to_input = it->second;
}
} else if (record_type_is_instr(record)) {
} else if (record_type_is_instr_boundary(record,
outputs_[output].last_record)) {
if (syscall_incurs_switch(input, blocked_time)) {
// Model as blocking and should switch to a different input.
need_new_input = true;
Expand Down Expand Up @@ -2641,7 +2742,8 @@ scheduler_tmpl_t<RecordType, ReaderType>::next_record(output_ordinal_t output,
}
}
if (options_.quantum_unit == QUANTUM_INSTRUCTIONS &&
record_type_is_instr(record) && !outputs_[output].in_kernel_code) {
record_type_is_instr_boundary(record, outputs_[output].last_record) &&
!outputs_[output].in_kernel_code) {
++input->instrs_in_quantum;
if (input->instrs_in_quantum > options_.quantum_duration) {
// We again prefer to switch to another input even if the current
Expand Down Expand Up @@ -2669,7 +2771,7 @@ scheduler_tmpl_t<RecordType, ReaderType>::next_record(output_ordinal_t output,
// We only switch on instruction boundaries. We could possibly switch
// in between (e.g., scatter/gather long sequence of reads/writes) by
// setting input->switching_pre_instruction.
record_type_is_instr(record)) {
record_type_is_instr_boundary(record, outputs_[output].last_record)) {
VPRINT(this, 4,
"next_record[%d]: hit end of time quantum after %" PRIu64 "\n",
output, input->time_spent_in_quantum);
Expand Down Expand Up @@ -2715,7 +2817,8 @@ scheduler_tmpl_t<RecordType, ReaderType>::next_record(output_ordinal_t output,
prev_input, outputs_[output].cur_input);
if (!preempt) {
if (options_.quantum_unit == QUANTUM_INSTRUCTIONS &&
record_type_is_instr(record)) {
record_type_is_instr_boundary(record,
outputs_[output].last_record)) {
--inputs_[prev_input].instrs_in_quantum;
} else if (options_.quantum_unit == QUANTUM_TIME) {
inputs_[prev_input].time_spent_in_quantum -=
Expand Down Expand Up @@ -2764,6 +2867,7 @@ scheduler_tmpl_t<RecordType, ReaderType>::next_record(output_ordinal_t output,

outputs_[output].last_record = record;
record_type_has_tid(record, input->last_record_tid);
record_type_has_pid(record, input->pid);
return sched_type_t::STATUS_OK;
}

Expand All @@ -2784,6 +2888,9 @@ scheduler_tmpl_t<RecordType, ReaderType>::unread_last_record(output_ordinal_t ou
VPRINT(this, 4, "next_record[%d]: unreading last record, from %d\n", output,
input->index);
input->queue.push_back(outinfo.last_record);
// XXX: This should be record_type_is_instr_boundary() but we don't have the pre-prev
// record. For now we don't support unread_last_record() for record_reader_t,
// enforced in a specialization of unread_last_record().
if (options_.quantum_unit == QUANTUM_INSTRUCTIONS && record_type_is_instr(record))
--input->instrs_in_quantum;
outinfo.last_record = create_invalid_record();
Expand Down
19 changes: 19 additions & 0 deletions clients/drcachesim/scheduler/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,8 @@ template <typename RecordType, typename ReaderType> class scheduler_tmpl_t {
: lock(new std::mutex)
{
}
// Returns whether the stream mixes threads (online analysis mode) yet
// wants to treat them as separate shards (so not core-sharded-on-disk).
bool
is_combined_stream()
{
Expand All @@ -1152,6 +1154,8 @@ template <typename RecordType, typename ReaderType> class scheduler_tmpl_t {
int workload = -1;
// If left invalid, this is a combined stream (online analysis mode).
memref_tid_t tid = INVALID_THREAD_ID;
memref_pid_t pid = INVALID_PID;
// Used for combined streams.
memref_tid_t last_record_tid = INVALID_THREAD_ID;
// If non-empty these records should be returned before incrementing the reader.
// This is used for read-ahead and inserting synthetic records.
Expand Down Expand Up @@ -1437,6 +1441,10 @@ template <typename RecordType, typename ReaderType> class scheduler_tmpl_t {
bool
record_type_has_tid(RecordType record, memref_tid_t &tid);

// If the given record has a process id field, returns true and the value.
bool
record_type_has_pid(RecordType record, memref_pid_t &pid);

// For trace_entry_t, only sets the tid for record types that have it.
void
record_type_set_tid(RecordType &record, memref_tid_t tid);
Expand All @@ -1456,6 +1464,12 @@ template <typename RecordType, typename ReaderType> class scheduler_tmpl_t {
bool
record_type_is_invalid(RecordType record);

bool
record_type_is_encoding(RecordType record);

bool
record_type_is_instr_boundary(RecordType record, RecordType prev_record);

// Creates the marker we insert between regions of interest.
RecordType
create_region_separator_marker(memref_tid_t tid, uintptr_t value);
Expand All @@ -1467,6 +1481,11 @@ template <typename RecordType, typename ReaderType> class scheduler_tmpl_t {
RecordType
create_invalid_record();

// If necessary, inserts context switch info on the incoming pid+tid.
// The lock for 'input' is held by the caller.
void
insert_switch_tid_pid(input_info_t &input);

// Used for diagnostics: prints record fields to stderr.
void
print_record(const RecordType &record);
Expand Down
18 changes: 5 additions & 13 deletions clients/drcachesim/tests/core_on_disk.templatex
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,19 @@ Total counts:
.*
8 total threads
.*
Core [0-5] counts:
Core [0-3] counts:
.*
2 threads
.*
Core [0-5] counts:
Core [0-3] counts:
.*
2 threads
.*
Core [0-5] counts:
Core [0-3] counts:
.*
2 threads
.*
Core [0-5] counts:
Core [0-3] counts:
.*
1 threads
.*
Core [0-5] counts:
.*
1 threads
.*
Core [0-5] counts:
.*
1 threads
2 threads
.*
5 changes: 5 additions & 0 deletions clients/drcachesim/tests/core_on_disk_schedule.templatex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.*
Core #0 schedule: (FJ_|EK_|GI|CHC_C__)
Core #1 schedule: (FJ_|EK_|GI|CHC_C__)
Core #2 schedule: (FJ_|EK_|GI|CHC_C__)
Core #3 schedule: (FJ_|EK_|GI|CHC_C__)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit a60ec81

Please sign in to comment.