diff --git a/init/bootchart.c b/init/bootchart.c index f72fcaaca..a514261f3 100644 --- a/init/bootchart.c +++ b/init/bootchart.c @@ -119,6 +119,18 @@ file_buff_done( FileBuff buff ) } } +static long long +get_uptime_jiffies() +{ + char buff[64]; + long long jiffies = 0; + + if (proc_read("/proc/uptime", buff, sizeof(buff)) > 0) + jiffies = 100LL*strtod(buff,NULL); + + return jiffies; +} + static void log_header(void) { @@ -185,22 +197,11 @@ static void do_log_uptime(FileBuff log) { char buff[65]; - int fd, ret, len; + int len; - fd = open("/proc/uptime",O_RDONLY); - if (fd >= 0) { - int ret; - ret = unix_read(fd, buff, 64); - close(fd); - buff[64] = 0; - if (ret >= 0) { - long long jiffies = 100LL*strtod(buff,NULL); - int len; - snprintf(buff,sizeof(buff),"%lld\n",jiffies); - len = strlen(buff); - file_buff_write(log, buff, len); - } - } + snprintf(buff,sizeof(buff),"%lld\n",get_uptime_jiffies()); + len = strlen(buff); + file_buff_write(log, buff, len); } static void @@ -376,3 +377,9 @@ void bootchart_finish( void ) file_buff_done(log_procs); acct(NULL); } + +/* called to get time (in ms) used by bootchart */ +long long bootchart_gettime( void ) +{ + return 10LL*get_uptime_jiffies(); +} diff --git a/init/bootchart.h b/init/bootchart.h index 39d2d4f20..ed65e8a9d 100644 --- a/init/bootchart.h +++ b/init/bootchart.h @@ -26,6 +26,7 @@ extern int bootchart_init(void); extern int bootchart_step(void); extern void bootchart_finish(void); +extern long long bootchart_gettime(void); # define BOOTCHART_POLLING_MS 200 /* polling period in ms */ # define BOOTCHART_DEFAULT_TIME_SEC (2*60) /* default polling time in seconds */ diff --git a/init/init.c b/init/init.c index bd1db7a58..99474e6f9 100644 --- a/init/init.c +++ b/init/init.c @@ -65,6 +65,7 @@ static int property_triggers_enabled = 0; #if BOOTCHART static int bootchart_count; +static long long bootchart_time = 0; #endif static char console[32]; @@ -1147,11 +1148,29 @@ int main(int argc, char **argv) #if BOOTCHART if (bootchart_count > 0) { - if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) - timeout = BOOTCHART_POLLING_MS; - if (bootchart_step() < 0 || --bootchart_count == 0) { - bootchart_finish(); - bootchart_count = 0; + long long current_time; + int elapsed_time, remaining_time; + + current_time = bootchart_gettime(); + elapsed_time = current_time - bootchart_time; + + if (elapsed_time >= BOOTCHART_POLLING_MS) { + /* count missed samples */ + while (elapsed_time >= BOOTCHART_POLLING_MS) { + elapsed_time -= BOOTCHART_POLLING_MS; + bootchart_count--; + } + /* count may be negative, take a sample anyway */ + bootchart_time = current_time; + if (bootchart_step() < 0 || bootchart_count <= 0) { + bootchart_finish(); + bootchart_count = 0; + } + } + if (bootchart_count > 0) { + remaining_time = BOOTCHART_POLLING_MS - elapsed_time; + if (timeout < 0 || timeout > remaining_time) + timeout = remaining_time; } } #endif