@@ -62,3 +62,46 @@ pub fn get_working_perf_executable() -> Option<OsString> {
6262 debug ! ( "perf is installed but not functioning correctly" ) ;
6363 None
6464}
65+
66+ /// Detects if the required perf events are available on this system.
67+ /// Returns Some("-e {cycles,cache-references,cache-misses}") if all three events are available,
68+ /// None otherwise.
69+ pub fn get_event_flags ( perf_executable : & OsString ) -> anyhow:: Result < Option < String > > {
70+ const CYCLES_EVENT_NAME : & str = "cycles" ;
71+ const CACHE_REFERENCES_EVENT_NAME : & str = "cache-references" ;
72+ const CACHE_MISSES_EVENT_NAME : & str = "cache-misses" ;
73+
74+ let perf_events = [
75+ CYCLES_EVENT_NAME ,
76+ CACHE_REFERENCES_EVENT_NAME ,
77+ CACHE_MISSES_EVENT_NAME ,
78+ ] ;
79+
80+ let output = Command :: new ( perf_executable)
81+ . arg ( "list" )
82+ . output ( )
83+ . context ( "Failed to run perf list" ) ?;
84+
85+ let stdout = String :: from_utf8_lossy ( & output. stdout ) ;
86+
87+ // Check if all required events are available
88+ let missing_events: Vec < & str > = perf_events
89+ . iter ( )
90+ . filter ( |& & event| !stdout. lines ( ) . any ( |line| line. trim ( ) . starts_with ( event) ) )
91+ . copied ( )
92+ . collect ( ) ;
93+
94+ if !missing_events. is_empty ( ) {
95+ debug ! (
96+ "Not all required perf events available. Missing: [{}], using default events" ,
97+ missing_events. join( ", " )
98+ ) ;
99+ return Ok ( None ) ;
100+ }
101+
102+ debug ! (
103+ "All required perf events available: {}" ,
104+ perf_events. join( ", " )
105+ ) ;
106+ Ok ( Some ( format ! ( "-e {{{}}}" , perf_events. join( "," ) ) ) )
107+ }
0 commit comments