Skip to content

Commit

Permalink
Merge pull request #304 from mstange/windows-cpus
Browse files Browse the repository at this point in the history
Implement --per-cpu-threads support on Windows
  • Loading branch information
mstange authored Jul 18, 2024
2 parents 987db3c + bcb65f4 commit 4b67b7c
Show file tree
Hide file tree
Showing 11 changed files with 364 additions and 144 deletions.
5 changes: 3 additions & 2 deletions etw-reader/examples/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ fn main() {
}
}
println!(
"{:?} {} {} {}-{} {} {}",
"{:?} {} {} {}-{} {} {}, processor {}",
e.EventHeader.ProviderId,
s.name(),
s.provider_name(),
e.EventHeader.EventDescriptor.Opcode,
e.EventHeader.EventDescriptor.Id,
s.property_count(),
e.EventHeader.TimeStamp
e.EventHeader.TimeStamp,
unsafe { e.BufferContext.Anonymous.ProcessorIndex },
);
println!(
"pid: {} {:?}",
Expand Down
6 changes: 6 additions & 0 deletions fxprof-processed-profile/src/profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,12 @@ impl Profile {
self.threads[thread.0].set_end_time(end_time);
}

/// Set the tid (thread ID) of a thread.
pub fn set_thread_tid(&mut self, thread: ThreadHandle, tid: u32) {
let tid = self.make_unique_tid(tid);
self.threads[thread.0].set_tid(tid);
}

/// Turn the string into in a [`StringHandle`], for use in [`Frame::Label`].
pub fn intern_string(&mut self, s: &str) -> StringHandle {
StringHandle(self.string_table.index_for_string(s))
Expand Down
4 changes: 4 additions & 0 deletions fxprof-processed-profile/src/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ impl Thread {
self.end_time = Some(end_time);
}

pub fn set_tid(&mut self, tid: String) {
self.tid = tid;
}

pub fn process(&self) -> ProcessHandle {
self.process
}
Expand Down
5 changes: 3 additions & 2 deletions samply/src/linux_shared/converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use fxprof_processed_profile::{
ReferenceTimestamp, SamplingInterval, StaticSchemaMarker, StringHandle, SymbolTable,
ThreadHandle,
};
use linux_perf_data::linux_perf_event_reader::TaskWasPreempted;
use linux_perf_data::simpleperf_dso_type::{DSO_DEX_FILE, DSO_KERNEL, DSO_KERNEL_MODULE};
use linux_perf_data::{
linux_perf_event_reader, DsoInfo, DsoKey, Endianness, SimpleperfFileRecord, SimpleperfSymbol,
Expand All @@ -35,14 +36,14 @@ use super::injected_jit_object::{correct_bad_perf_jit_so_file, jit_function_name
use super::kernel_symbols::{kernel_module_build_id, KernelSymbols};
use super::mmap_range_or_vec::MmapRangeOrVec;
use super::pe_mappings::{PeMappings, SuspectedPeMapping};
use super::per_cpu::Cpus;
use super::processes::Processes;
use super::rss_stat::{RssStat, MM_ANONPAGES, MM_FILEPAGES, MM_SHMEMPAGES, MM_SWAPENTS};
use super::svma_file_range::compute_vma_bias;
use super::vdso::VdsoObject;
use crate::shared::context_switch::{ContextSwitchHandler, OffCpuSampleGroup};
use crate::shared::jit_category_manager::JitCategoryManager;
use crate::shared::lib_mappings::{AndroidArtInfo, LibMappingInfo};
use crate::shared::per_cpu::Cpus;
use crate::shared::process_name::make_process_name;
use crate::shared::process_sample_data::{
OtherEventMarker, RssStatMarker, RssStatMember, SchedSwitchMarkerOnCpuTrack,
Expand Down Expand Up @@ -980,7 +981,7 @@ where
&self.timestamp_converter,
&[cpu.thread_handle, combined_thread],
thread.profile_thread,
preempted,
preempted == TaskWasPreempted::Yes,
&mut self.profile,
);
}
Expand Down
1 change: 0 additions & 1 deletion samply/src/linux_shared/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ mod kernel_symbols;
mod mmap_range_or_vec;
mod object_rewriter;
mod pe_mappings;
mod per_cpu;
mod process;
mod process_threads;
mod processes;
Expand Down
1 change: 1 addition & 0 deletions samply/src/shared/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod jit_function_recycler;
pub mod jitdump_manager;
pub mod lib_mappings;
pub mod marker_file;
pub mod per_cpu;
pub mod perf_map;
pub mod process_name;
pub mod process_sample_data;
Expand Down
21 changes: 10 additions & 11 deletions samply/src/linux_shared/per_cpu.rs → samply/src/shared/per_cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use fxprof_processed_profile::{
MarkerLocation, MarkerSchema, MarkerTiming, ProcessHandle, Profile, StaticSchemaMarker,
StringHandle, ThreadHandle, Timestamp,
};
use linux_perf_data::linux_perf_event_reader::TaskWasPreempted;

use crate::shared::context_switch::ThreadContextSwitchData;
use crate::shared::timestamp_converter::TimestampConverter;
Expand Down Expand Up @@ -46,7 +45,7 @@ impl Cpu {
let previous_tid =
std::mem::replace(&mut self.current_tid, Some((tid, thread_name, timestamp)));
if let Some((_previous_tid, previous_thread_name, switch_in_timestamp)) = previous_tid {
// eprintln!("Missing switch-out (noticed during switch-in) on {}: {previous_tid}, {switch_in_timestamp}", self.name);
// eprintln!("Missing switch-out (noticed during switch-in) on {}: {previous_tid}, {switch_in_timestamp}", profile.get_string(self.name));
let start_timestamp = converter.convert_time(switch_in_timestamp);
let end_timestamp = converter.convert_time(timestamp);
let timing = MarkerTiming::Interval(start_timestamp, end_timestamp);
Expand All @@ -63,12 +62,12 @@ impl Cpu {
#[allow(clippy::too_many_arguments)]
pub fn notify_switch_out(
&mut self,
tid: i32,
tid: i32, // tid that is being switched away from
timestamp: u64,
converter: &TimestampConverter,
thread_handles: &[ThreadHandle],
thread_handle: ThreadHandle,
preempted: TaskWasPreempted,
thread_handles: &[ThreadHandle], // for cpu tracks
thread_handle: ThreadHandle, // for thread tracks
preempted: bool,
profile: &mut Profile,
) {
let previous_tid = self.current_tid.take();
Expand All @@ -84,8 +83,8 @@ impl Cpu {
);
}
let switch_out_reason = match preempted {
TaskWasPreempted::Yes => profile.intern_string("preempted"),
TaskWasPreempted::No => profile.intern_string("blocked"),
true => profile.intern_string("preempted"),
false => profile.intern_string("blocked"),
};
profile.add_marker(
thread_handle,
Expand All @@ -96,16 +95,16 @@ impl Cpu {
},
);
if previous_tid != tid {
// eprintln!("Missing switch-out (noticed during switch-out) on {}: {previous_tid}, {switch_in_timestamp}", self.name);
// eprintln!("Missing switch-out (noticed during switch-out) on {}: {previous_tid}, {switch_in_timestamp}", profile.get_string(self.name));
// eprintln!(
// "Missing switch-in (noticed during switch-out) on {}: {tid}, {timestamp}",
// self.name
// profile.get_string(self.name)
// );
}
} else {
// eprintln!(
// "Missing switch-in (noticed during switch-out) on {}: {tid}, {timestamp}",
// self.name
// profile.get_string(self.name)
// );
}
}
Expand Down
7 changes: 6 additions & 1 deletion samply/src/shared/timestamp_converter.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use fxprof_processed_profile::Timestamp;
use fxprof_processed_profile::{CpuDelta, Timestamp};

#[derive(Debug, Clone, Copy)]
pub struct TimestampConverter {
Expand All @@ -15,6 +15,11 @@ impl TimestampConverter {
)
}

#[allow(dead_code)]
pub fn convert_cpu_delta(&self, delta_raw: u64) -> CpuDelta {
CpuDelta::from_nanos(delta_raw * self.raw_to_ns_factor)
}

#[allow(unused)]
pub fn convert_us(&self, time_us: u64) -> Timestamp {
Timestamp::from_nanos_since_reference(
Expand Down
9 changes: 8 additions & 1 deletion samply/src/shared/unresolved_samples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,14 @@ impl UnresolvedStacks {
/// Get the `UnresolvedStackHandle` for a stack. The stack must be ordered from
/// caller-most to callee-most ("outside to inside").
pub fn convert(&mut self, frames: impl Iterator<Item = StackFrame>) -> UnresolvedStackHandle {
let mut prefix = UnresolvedStackHandle::EMPTY;
self.convert_with_prefix(UnresolvedStackHandle::EMPTY, frames)
}

pub fn convert_with_prefix(
&mut self,
mut prefix: UnresolvedStackHandle,
frames: impl Iterator<Item = StackFrame>,
) -> UnresolvedStackHandle {
for frame in frames {
let x = (prefix, frame);
let node = *self.stack_lookup.entry(x).or_insert_with(|| {
Expand Down
10 changes: 7 additions & 3 deletions samply/src/windows/etw_gecko.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ fn process_trace(
return;
}
let tid: u32 = parser.parse("ThreadId");
context.handle_sample(timestamp_raw, tid);
let cpu = u32::from(unsafe { e.BufferContext.Anonymous.ProcessorIndex });
context.handle_sample(timestamp_raw, tid, cpu);
}
"MSNT_SystemTrace/PageFault/DemandZeroFault" => {
if !context.is_in_time_range(timestamp_raw) {
Expand All @@ -218,7 +219,8 @@ fn process_trace(
}

let tid: u32 = s.thread_id();
context.handle_sample(timestamp_raw, tid);
let cpu = u32::from(unsafe { e.BufferContext.Anonymous.ProcessorIndex });
context.handle_sample(timestamp_raw, tid, cpu);
}
"MSNT_SystemTrace/PageFault/VirtualAlloc"
| "MSNT_SystemTrace/PageFault/VirtualFree" => {
Expand Down Expand Up @@ -316,7 +318,9 @@ fn process_trace(
}
let old_tid: u32 = parser.parse("OldThreadId");
let new_tid: u32 = parser.parse("NewThreadId");
context.handle_cswitch(timestamp_raw, old_tid, new_tid);
let cpu = u32::from(unsafe { e.BufferContext.Anonymous.ProcessorIndex });
let wait_reason: i8 = parser.parse("OldThreadWaitReason");
context.handle_cswitch(timestamp_raw, old_tid, new_tid, cpu, wait_reason);
}
"MSNT_SystemTrace/Thread/ReadyThread" => {
if !context.is_in_time_range(timestamp_raw) {
Expand Down
Loading

0 comments on commit 4b67b7c

Please sign in to comment.