1+ #include <stdio.h>
2+ #include <stdlib.h>
13#include <time.h>
24
35#include "utils.h"
2224bool boot_complete = false;
2325static double scale_factor ;
2426
27+ /* for testing */
28+ uint64_t count = 0 ;
29+ struct timespec boot_begin , boot_end ;
30+ double TEST_ns_per_call , TEST_predict_sec ;
31+
2532/* Calculate "x * n / d" without unnecessary overflow or loss of precision.
2633 *
2734 * Reference:
@@ -114,14 +121,18 @@ static void measure_bogomips_ns(uint64_t iterations)
114121 (double ) (elapsed_ns_2 - elapsed_ns_1 ) / (double ) iterations ;
115122
116123 /* 'semu_timer_clocksource' is called ~2e8 times per SMP. Each call's
117- * overhead ~ ns_per_call. The total overhead is ~ ns_per_call * SMP * 2e8.
118- * That overhead is about 10% of the entire boot, so effectively:
124+ * overhead ~ ns_per_call. The total overhead is ~ ns_per_call * SMP *
125+ * 2e8. That overhead is about 10% of the entire boot, so effectively:
119126 * predict_sec = ns_per_call * SMP * 2e8 * (100%/10%) / 1e9
120127 * = ns_per_call * SMP * 2.0
121128 * Then scale_factor = (desired_time) / (predict_sec).
122129 */
123130 const double predict_sec = ns_per_call * SEMU_SMP * 2.0 ;
124131 scale_factor = SEMU_BOOT_TARGET_TIME / predict_sec ;
132+
133+ /* for testing */
134+ TEST_ns_per_call = ns_per_call ;
135+ TEST_predict_sec = predict_sec ;
125136}
126137
127138/* The main function that returns the "emulated time" in ticks.
@@ -132,6 +143,8 @@ static void measure_bogomips_ns(uint64_t iterations)
132143 */
133144static uint64_t semu_timer_clocksource (semu_timer_t * timer )
134145{
146+ count ++ ;
147+
135148 /* After boot process complete, the timer will switch to real time. Thus,
136149 * there is an offset between the real time and the emulator time.
137150 *
@@ -157,8 +170,23 @@ static uint64_t semu_timer_clocksource(semu_timer_t *timer)
157170
158171 /* The boot is done => switch to real freq with an offset bridging. */
159172 if (first_switch ) {
173+ clock_gettime (CLOCKID , & boot_end );
174+ double boot_time = (boot_end .tv_sec - boot_begin .tv_sec ) +
175+ (boot_end .tv_nsec - boot_begin .tv_nsec ) / 1e9 ;
176+
160177 first_switch = false;
161178 offset = (int64_t ) (real_ticks - scaled_ticks );
179+ printf (
180+ "\033[1;31m[SEMU LOG]: Boot time: %.5f seconds, called %ld "
181+ "times semu_timer_total_ticks\033[0m\n" ,
182+ boot_time , count );
183+
184+ printf (
185+ "\033[1;31m[SEMU LOG]: ns_per_call = %.5f, predict_sec = %.5f, "
186+ "scale_factor = %.5f\033[0m\n" ,
187+ TEST_ns_per_call , TEST_predict_sec , scale_factor );
188+
189+ exit (0 );
162190 }
163191 return (uint64_t ) ((int64_t ) real_ticks - offset );
164192
@@ -196,6 +224,7 @@ void semu_timer_init(semu_timer_t *timer, uint64_t freq)
196224 */
197225 measure_bogomips_ns (freq );
198226
227+ clock_gettime (CLOCKID , & boot_begin );
199228 timer -> freq = freq ;
200229 semu_timer_rebase (timer , 0 );
201230}
0 commit comments