diff options
author | Yongqin Liu <yongqin.liu@linaro.org> | 2014-12-05 13:45:02 +0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2015-02-12 12:13:24 -0800 |
commit | a197ff12dd336a9945ad1164402980296f9c235c (patch) | |
tree | b01d81e0a3f06b3b239005697112de20f389ccda /init/bootchart.cpp | |
parent | ed318bff41c4515ca79a11afb97507a452e9fcd3 (diff) | |
download | system_core-a197ff12dd336a9945ad1164402980296f9c235c.zip system_core-a197ff12dd336a9945ad1164402980296f9c235c.tar.gz system_core-a197ff12dd336a9945ad1164402980296f9c235c.tar.bz2 |
bootchart: fix bootchart can not be triggered problem
bootchart uses a file on the data partition to decide if it should collect
data for bootchart, but the data partition will be mounted by the mount_all
command in the "on fs" section, and it will be only added into the action
queue when command "trigger fs" is executed, but that's after the
bootchart_init action (late_init).
This change makes bootchart_init a builtin command of init,
and make it executed as the first command of "on post-fs" section
which will be triggered after the "on fs" section.
This change also refactors the bootchart code to all be in bootchart.cpp.
Change-Id: Ia74aa34ca5b785f51fcffdd383075a549b2a99d9
Signed-off-by: Yongqin Liu <yongqin.liu@linaro.org>
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(); -} |