@@ -22,6 +22,11 @@ use simics::{
2222 debug, get_processor_number, info, trace, warn,
2323} ;
2424
25+ enum IterationControl {
26+ Continue ,
27+ StopRequested ,
28+ }
29+
2530impl Tsffs {
2631 fn on_simulation_stopped_magic_start ( & mut self , magic_number : MagicNumber ) -> Result < ( ) > {
2732 if !self . have_initial_snapshot ( ) {
@@ -91,6 +96,73 @@ impl Tsffs {
9196 self . on_simulation_stopped_solution ( SolutionKind :: Manual )
9297 }
9398
99+ fn finish_iteration (
100+ & mut self ,
101+ exit_kind : ExitKind ,
102+ count_as_timeout : Option < bool > ,
103+ missing_start_info_message : & str ,
104+ ) -> Result < IterationControl > {
105+ self . iterations += 1 ;
106+
107+ if self . iteration_limit != 0 && self . iterations >= self . iteration_limit {
108+ let duration = SystemTime :: now ( ) . duration_since (
109+ * self
110+ . start_time
111+ . get ( )
112+ . ok_or_else ( || anyhow ! ( "Start time was not set" ) ) ?,
113+ ) ?;
114+
115+ // Set the log level so this message always prints
116+ set_log_level ( self . as_conf_object_mut ( ) , LogLevel :: Info ) ?;
117+
118+ info ! (
119+ self . as_conf_object( ) ,
120+ "Configured iteration count {} reached. Stopping after {} seconds ({} exec/s)." ,
121+ self . iterations,
122+ duration. as_secs_f32( ) ,
123+ self . iterations as f32 / duration. as_secs_f32( )
124+ ) ;
125+
126+ self . send_shutdown ( ) ?;
127+
128+ if self . quit_on_iteration_limit {
129+ quit ( 0 ) ?;
130+ } else {
131+ return Ok ( IterationControl :: StopRequested ) ;
132+ }
133+ }
134+
135+ if let Some ( is_timeout) = count_as_timeout {
136+ if is_timeout {
137+ self . timeouts += 1 ;
138+ } else {
139+ self . solutions += 1 ;
140+ }
141+ }
142+
143+ let fuzzer_tx = self
144+ . fuzzer_tx
145+ . get ( )
146+ . ok_or_else ( || anyhow ! ( "No fuzzer tx channel" ) ) ?;
147+
148+ fuzzer_tx. send ( exit_kind) ?;
149+
150+ if self . should_restore_snapshot_this_iteration ( ) {
151+ self . restore_initial_snapshot ( ) ?;
152+ }
153+ self . coverage_prev_loc = 0 ;
154+
155+ if self . start_info . get ( ) . is_some ( ) {
156+ self . get_and_write_testcase ( ) ?;
157+ } else {
158+ debug ! ( self . as_conf_object( ) , "{missing_start_info_message}" ) ;
159+ }
160+
161+ self . post_timeout_event ( ) ?;
162+
163+ Ok ( IterationControl :: Continue )
164+ }
165+
94166 fn on_simulation_stopped_magic_stop ( & mut self ) -> Result < ( ) > {
95167 if !self . have_initial_snapshot ( ) {
96168 warn ! (
@@ -117,58 +189,13 @@ impl Tsffs {
117189 return Ok ( ( ) ) ;
118190 }
119191
120- self . iterations += 1 ;
121-
122- if self . iteration_limit != 0 && self . iterations >= self . iteration_limit {
123- let duration = SystemTime :: now ( ) . duration_since (
124- * self
125- . start_time
126- . get ( )
127- . ok_or_else ( || anyhow ! ( "Start time was not set" ) ) ?,
128- ) ?;
129-
130- // Set the log level so this message always prints
131- set_log_level ( self . as_conf_object_mut ( ) , LogLevel :: Info ) ?;
132-
133- info ! (
134- self . as_conf_object( ) ,
135- "Configured iteration count {} reached. Stopping after {} seconds ({} exec/s)." ,
136- self . iterations,
137- duration. as_secs_f32( ) ,
138- self . iterations as f32 / duration. as_secs_f32( )
139- ) ;
140-
141- self . send_shutdown ( ) ?;
142-
143- if self . quit_on_iteration_limit {
144- quit ( 0 ) ?;
145- } else {
146- return Ok ( ( ) ) ;
147- }
148- }
149-
150- let fuzzer_tx = self
151- . fuzzer_tx
152- . get ( )
153- . ok_or_else ( || anyhow ! ( "No fuzzer tx channel" ) ) ?;
154-
155- fuzzer_tx. send ( ExitKind :: Ok ) ?;
156-
157- if self . should_restore_snapshot_this_iteration ( ) {
158- self . restore_initial_snapshot ( ) ?;
159- }
160- self . coverage_prev_loc = 0 ;
161-
162- if self . start_info . get ( ) . is_some ( ) {
163- self . get_and_write_testcase ( ) ?;
164- } else {
165- debug ! (
166- self . as_conf_object( ) ,
167- "Missing start buffer or size, not writing testcase."
168- ) ;
192+ if let IterationControl :: StopRequested = self . finish_iteration (
193+ ExitKind :: Ok ,
194+ None ,
195+ "Missing start buffer or size, not writing testcase." ,
196+ ) ? {
197+ return Ok ( ( ) ) ;
169198 }
170-
171- self . post_timeout_event ( ) ?;
172199 }
173200
174201 if self . save_all_execution_traces {
@@ -330,58 +357,13 @@ impl Tsffs {
330357 return Ok ( ( ) ) ;
331358 }
332359
333- self . iterations += 1 ;
334-
335- if self . iteration_limit != 0 && self . iterations >= self . iteration_limit {
336- let duration = SystemTime :: now ( ) . duration_since (
337- * self
338- . start_time
339- . get ( )
340- . ok_or_else ( || anyhow ! ( "Start time was not set" ) ) ?,
341- ) ?;
342-
343- // Set the log level so this message always prints
344- set_log_level ( self . as_conf_object_mut ( ) , LogLevel :: Info ) ?;
345-
346- info ! (
347- self . as_conf_object( ) ,
348- "Configured iteration count {} reached. Stopping after {} seconds ({} exec/s)." ,
349- self . iterations,
350- duration. as_secs_f32( ) ,
351- self . iterations as f32 / duration. as_secs_f32( )
352- ) ;
353-
354- self . send_shutdown ( ) ?;
355-
356- if self . quit_on_iteration_limit {
357- quit ( 0 ) ?;
358- } else {
359- return Ok ( ( ) ) ;
360- }
361- }
362-
363- let fuzzer_tx = self
364- . fuzzer_tx
365- . get ( )
366- . ok_or_else ( || anyhow ! ( "No fuzzer tx channel" ) ) ?;
367-
368- fuzzer_tx. send ( ExitKind :: Ok ) ?;
369-
370- if self . should_restore_snapshot_this_iteration ( ) {
371- self . restore_initial_snapshot ( ) ?;
372- }
373- self . coverage_prev_loc = 0 ;
374-
375- if self . start_info . get ( ) . is_some ( ) {
376- self . get_and_write_testcase ( ) ?;
377- } else {
378- debug ! (
379- self . as_conf_object( ) ,
380- "Missing start buffer or size, not writing testcase. This may be due to using manual no-buffer harnessing."
381- ) ;
360+ if let IterationControl :: StopRequested = self . finish_iteration (
361+ ExitKind :: Ok ,
362+ None ,
363+ "Missing start buffer or size, not writing testcase. This may be due to using manual no-buffer harnessing." ,
364+ ) ? {
365+ return Ok ( ( ) ) ;
382366 }
383-
384- self . post_timeout_event ( ) ?;
385367 }
386368
387369 if self . save_all_execution_traces {
@@ -428,67 +410,20 @@ impl Tsffs {
428410 return Ok ( ( ) ) ;
429411 }
430412
431- self . iterations += 1 ;
432-
433- if self . iteration_limit != 0 && self . iterations >= self . iteration_limit {
434- let duration = SystemTime :: now ( ) . duration_since (
435- * self
436- . start_time
437- . get ( )
438- . ok_or_else ( || anyhow ! ( "Start time was not set" ) ) ?,
439- ) ?;
440-
441- // Set the log level so this message always prints
442- set_log_level ( self . as_conf_object_mut ( ) , LogLevel :: Info ) ?;
443-
444- info ! (
445- self . as_conf_object( ) ,
446- "Configured iteration count {} reached. Stopping after {} seconds ({} exec/s)." ,
447- self . iterations,
448- duration. as_secs_f32( ) ,
449- self . iterations as f32 / duration. as_secs_f32( )
450- ) ;
451-
452- self . send_shutdown ( ) ?;
453-
454- if self . quit_on_iteration_limit {
455- quit ( 0 ) ?;
456- } else {
457- return Ok ( ( ) ) ;
458- }
459- }
460-
461- let fuzzer_tx = self
462- . fuzzer_tx
463- . get ( )
464- . ok_or_else ( || anyhow ! ( "No fuzzer tx channel" ) ) ?;
465-
466- match kind {
467- SolutionKind :: Timeout => {
468- self . timeouts += 1 ;
469- fuzzer_tx. send ( ExitKind :: Timeout ) ?
470- }
413+ let ( exit_kind, count_as_timeout) = match kind {
414+ SolutionKind :: Timeout => ( ExitKind :: Timeout , true ) ,
471415 SolutionKind :: Exception | SolutionKind :: Breakpoint | SolutionKind :: Manual => {
472- self . solutions += 1 ;
473- fuzzer_tx. send ( ExitKind :: Crash ) ?
416+ ( ExitKind :: Crash , false )
474417 }
475- }
476-
477- if self . should_restore_snapshot_this_iteration ( ) {
478- self . restore_initial_snapshot ( ) ?;
479- }
480- self . coverage_prev_loc = 0 ;
418+ } ;
481419
482- if self . start_info . get ( ) . is_some ( ) {
483- self . get_and_write_testcase ( ) ?;
484- } else {
485- debug ! (
486- self . as_conf_object( ) ,
487- "Missing start buffer or size, not writing testcase."
488- ) ;
420+ if let IterationControl :: StopRequested = self . finish_iteration (
421+ exit_kind,
422+ Some ( count_as_timeout) ,
423+ "Missing start buffer or size, not writing testcase." ,
424+ ) ? {
425+ return Ok ( ( ) ) ;
489426 }
490-
491- self . post_timeout_event ( ) ?;
492427 }
493428
494429 if self . save_all_execution_traces {
0 commit comments