diff options
Diffstat (limited to 'init/bootchart.cpp')
-rw-r--r-- | init/bootchart.cpp | 98 |
1 files changed, 75 insertions, 23 deletions
diff --git a/init/bootchart.cpp b/init/bootchart.cpp index d275096..ff4c0cf 100644 --- a/init/bootchart.cpp +++ b/init/bootchart.cpp @@ -21,6 +21,8 @@ */ #include "bootchart.h" +#include "keywords.h" +#include "log.h" #include <dirent.h> #include <errno.h> @@ -32,6 +34,10 @@ #include <time.h> #include <unistd.h> +#define BOOTCHART_POLLING_MS 200 /* polling period in ms */ +#define BOOTCHART_DEFAULT_TIME_SEC (2*60) /* default polling time in seconds */ +#define BOOTCHART_MAX_TIME_SEC (10*60) /* max polling time in seconds */ + #define VERSION "0.8" #define SAMPLE_PERIOD 0.2 #define LOG_ROOT "/data/bootchart" @@ -41,8 +47,23 @@ #define LOG_HEADER LOG_ROOT"/header" #define LOG_ACCT LOG_ROOT"/kernel_pacct" -#define LOG_STARTFILE "/data/bootchart-start" -#define LOG_STOPFILE "/data/bootchart-stop" +#define LOG_STARTFILE LOG_ROOT"/start" +#define LOG_STOPFILE LOG_ROOT"/stop" + +#define FILE_BUFF_SIZE 65536 + +struct FileBuff { + int count; + int fd; + char data[FILE_BUFF_SIZE]; +}; + +static long long last_bootchart_time; +static int g_remaining_samples; + +static FileBuff log_stat[1]; +static FileBuff log_procs[1]; +static FileBuff log_disks[1]; static int proc_read(const char* filename, char* buff, size_t buffsize) @@ -57,19 +78,11 @@ proc_read(const char* filename, char* buff, size_t buffsize) return len; } -#define FILE_BUFF_SIZE 65536 - -struct FileBuff { - int count; - int fd; - char data[FILE_BUFF_SIZE]; -}; - static void file_buff_open( FileBuff* buff, const char* path ) { buff->count = 0; - buff->fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0755); + buff->fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0755); } static void @@ -248,9 +261,19 @@ do_log_procs(FileBuff* log) do_log_ln(log); } -static FileBuff log_stat[1]; -static FileBuff log_procs[1]; -static FileBuff log_disks[1]; +int do_bootchart_init(int nargs, char **args) +{ + g_remaining_samples = bootchart_init(); + if (g_remaining_samples < 0) { + ERROR("bootcharting init failure\n"); + } else if (g_remaining_samples > 0) { + NOTICE("bootcharting started (will run for %d ms)\n", g_remaining_samples*BOOTCHART_POLLING_MS); + } else { + NOTICE("bootcharting ignored\n"); + } + + return 0; +} /* called to setup bootcharting */ int bootchart_init( void ) @@ -307,14 +330,13 @@ int bootchart_init( void ) return count; } -/* called each time you want to perform a bootchart sampling op */ -int bootchart_step( void ) +static int bootchart_step( void ) { do_log_file(log_stat, "/proc/stat"); do_log_file(log_disks, "/proc/diskstats"); do_log_procs(log_procs); - /* we stop when /data/bootchart-stop contains 1 */ + /* we stop when /data/bootchart/stop contains 1 */ { char buff[2]; if (proc_read(LOG_STOPFILE,buff,sizeof(buff)) > 0 && buff[0] == '1') { @@ -325,6 +347,42 @@ int bootchart_step( void ) return 0; } +/* called to get time (in ms) used by bootchart */ +static long long bootchart_gettime() { + return 10LL*get_uptime_jiffies(); +} + +/* called each time you want to perform a bootchart sampling op */ +void bootchart_sample(int* timeout) { + if (g_remaining_samples > 0) { + long long current_time; + int elapsed_time, remaining_time; + + current_time = bootchart_gettime(); + elapsed_time = current_time - last_bootchart_time; + + if (elapsed_time >= BOOTCHART_POLLING_MS) { + /* count missed samples */ + while (elapsed_time >= BOOTCHART_POLLING_MS) { + elapsed_time -= BOOTCHART_POLLING_MS; + g_remaining_samples--; + } + /* count may be negative, take a sample anyway */ + last_bootchart_time = current_time; + if (bootchart_step() < 0 || g_remaining_samples <= 0) { + bootchart_finish(); + g_remaining_samples = 0; + } + } + if (g_remaining_samples > 0) { + remaining_time = BOOTCHART_POLLING_MS - elapsed_time; + if (*timeout < 0 || *timeout > remaining_time) { + *timeout = remaining_time; + } + } + } +} + void bootchart_finish( void ) { unlink( LOG_STOPFILE ); @@ -333,9 +391,3 @@ 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(); -} |