summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Guittot <vincent.guittot@linaro.org>2015-08-11 09:33:40 +0200
committerVincent Guittot <vincent.guittot@linaro.org>2015-08-24 14:16:28 +0200
commit743afaa928f0e52f6459afe9d980f91c050bd466 (patch)
tree5ceda1bca3f269e86a640d9dc883fad29551faec
parent1eba97039c3f991e35e6004a971506e770e89ac7 (diff)
rt-app: add log buffer in memory
With the new mechanism that is used to describe a scenario, it becomes more complex to estimate how many logs will be generated during the execution of a use case. As a result, the record of the logs in temporary buffer had been disable and the logs were saved directly in files. The potential side effect of such mecanism is to block threads on io access, which disturbs the use case behavior. A new parameter is added to define the saving policy of the logs. You can now disable the logs, save them directly in a file like previously, define the size of a temporary buffer but with the risk to lost some logs if the buffer overflow. You can also ask rt-app to evaluate how many logs will be generated and allocate the temporary buffer accordingly. This last mode is not yet implemented and it will be part of a dedicated patch. Full details of the new parameter is available in the update of the documentation Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
-rw-r--r--doc/tutorial.txt15
-rw-r--r--src/rt-app.c34
-rw-r--r--src/rt-app_parse_config.c51
-rw-r--r--src/rt-app_types.h1
4 files changed, 84 insertions, 17 deletions
diff --git a/doc/tutorial.txt b/doc/tutorial.txt
index 12aba47..8341b2e 100644
--- a/doc/tutorial.txt
+++ b/doc/tutorial.txt
@@ -61,6 +61,20 @@ the current directory (./).
* log_basename : Text. Prefix used for all log files of the use case.
"rt-app-" is used by default.
+* log_size : String or Integer. A Integer defines a fix size in MB of the
+temporary buffer (size per thread) that will be used to store the log data
+before saving them in a file. This temporary buffer is used as a cicular
+buffer so the oldest data will be lost in case of overflow. A string is used
+to set a predifined behavior:
+ - "file" will be used to store the log data directly in the file without
+ using a temporary buffer.
+ - "Disable" will disable the log mecahnism.
+ - "Auto" will let rt-app compute the buffer size to not overflow the latter
+ during the use case.
+The use of a temporary buffer prevents the threads of unexpected wait during
+io access. The "Auto" mode is not implemented yet and fallback to "file" mode
+for the moment.
+
* ftrace: Boolean. If enable, rt-app logs in ftrace the main events of the use
case. Default value is False.
@@ -75,6 +89,7 @@ each threads (see gnuplot section for more details). Default value is False.
"pi_enabled" : false,
"lock_pages" : false,
"logdir" : "./",
+ "log_size" : "file",
"log_basename" : "rt-app",
"ftrace" : false,
"gnuplot" : false,
diff --git a/src/rt-app.c b/src/rt-app.c
index 20383a2..7f9dda0 100644
--- a/src/rt-app.c
+++ b/src/rt-app.c
@@ -343,10 +343,11 @@ void *thread_body(void *arg)
timing_point_t *curr_timing;
timing_point_t *timings;
timing_point_t tmp_timing;
+ unsigned int timings_size, timing_loop;
pid_t tid;
struct sched_attr attr;
unsigned int flags = 0;
- int ret, i, j, loop;
+ int ret, i, j, loop, idx;
/* Set thread name */
ret = pthread_setname_np(pthread_self(), data->name);
@@ -440,6 +441,15 @@ void *thread_body(void *arg)
exit(EXIT_FAILURE);
}
+ if (opts.logsize > 0) {
+ timings = malloc(opts.logsize);
+ timings_size = opts.logsize / sizeof(timing_point_t);
+ } else {
+ timings = NULL;
+ timings_size = 0;
+ }
+ timing_loop = 0;
+
/* Lock pages */
if (data->lock_pages == 1)
{
@@ -454,8 +464,6 @@ void *thread_body(void *arg)
log_notice("[%d] starting thread ...\n", data->ind);
- timings = NULL;
-
fprintf(data->log_handler, "#idx\tperf\trun\tperiod\tstart\t\tend\t\trel_st\n");
if (opts.ftrace)
@@ -478,7 +486,7 @@ void *thread_body(void *arg)
}
}
#endif
- i = j = loop = 0;
+ i = j = loop = idx = 0;
while (continue_running && (i != data->loop)) {
struct timespec t_diff, t_rel_start;
@@ -493,7 +501,7 @@ void *thread_body(void *arg)
clock_gettime(CLOCK_MONOTONIC, &t_end);
if (timings)
- curr_timing = &timings[loop];
+ curr_timing = &timings[idx];
else
curr_timing = &tmp_timing;
@@ -508,7 +516,7 @@ void *thread_body(void *arg)
curr_timing->duration = duration;
curr_timing->perf = perf;
- if (!timings)
+ if (opts.logsize && !timings)
log_timing(data->log_handler, curr_timing);
if (opts.ftrace)
@@ -527,6 +535,12 @@ void *thread_body(void *arg)
pdata = &data->phases[j];
}
+
+ idx++;
+ if (idx >= timings_size) {
+ timing_loop = 1;
+ idx = 0;
+ }
}
param.sched_priority = 0;
@@ -539,9 +553,13 @@ void *thread_body(void *arg)
exit(EXIT_FAILURE);
}
- if (timings)
- for (j=0; j < loop; j++)
+ if (timings) {
+ for (j = idx; timing_loop && (j < timings_size); j++)
+ log_timing(data->log_handler, &timings[j]);
+ for (j = 0; j < idx; j++)
log_timing(data->log_handler, &timings[j]);
+ }
+
if (opts.ftrace)
log_ftrace(ft_data.marker_fd, "[%d] exiting", data->ind);
diff --git a/src/rt-app_parse_config.c b/src/rt-app_parse_config.c
index 96e5517..c2407dc 100644
--- a/src/rt-app_parse_config.c
+++ b/src/rt-app_parse_config.c
@@ -692,8 +692,8 @@ parse_tasks(struct json_object *tasks, rtapp_options_t *opts)
static void
parse_global(struct json_object *global, rtapp_options_t *opts)
{
- char *policy, *cal_str;
- struct json_object *cal_obj;
+ char *policy, *tmp_str;
+ struct json_object *tmp_obj;
int scan_cnt;
log_info(PFX "Parsing global section");
@@ -708,6 +708,7 @@ parse_global(struct json_object *global, rtapp_options_t *opts)
opts->logdir = strdup("./");
opts->lock_pages = 1;
opts->logbasename = strdup("rt-app");
+ opts->logsize = 0;
opts->ftrace = 0;
opts->pi_enabled = 0;
return;
@@ -727,27 +728,27 @@ parse_global(struct json_object *global, rtapp_options_t *opts)
*/
free(policy);
- cal_obj = get_in_object(global, "calibration", TRUE);
- if (cal_obj == NULL) {
+ tmp_obj = get_in_object(global, "calibration", TRUE);
+ if (tmp_obj == NULL) {
/* no setting ? Calibrate CPU0 */
opts->calib_cpu = 0;
opts->calib_ns_per_loop = 0;
log_error("missing calibration setting force CPU0");
} else {
- if (json_object_is_type(cal_obj, json_type_int)) {
+ if (json_object_is_type(tmp_obj, json_type_int)) {
/* integer (no " ") detected. */
- opts->calib_ns_per_loop = json_object_get_int(cal_obj);
+ opts->calib_ns_per_loop = json_object_get_int(tmp_obj);
log_debug("ns_per_loop %d", opts->calib_ns_per_loop);
} else {
/* Get CPU number */
- cal_str = get_string_value_from(global, "calibration",
+ tmp_str = get_string_value_from(global, "calibration",
TRUE, "CPU0");
- scan_cnt = sscanf(cal_str, "CPU%d", &opts->calib_cpu);
+ scan_cnt = sscanf(tmp_str, "CPU%d", &opts->calib_cpu);
/*
* get_string_value_from allocate the string so with have to free it
* once useless
*/
- free(cal_str);
+ free(tmp_str);
if (!scan_cnt) {
log_critical(PFX "Invalid calibration CPU%d", opts->calib_cpu);
exit(EXIT_INV_CONFIG);
@@ -756,6 +757,38 @@ parse_global(struct json_object *global, rtapp_options_t *opts)
}
}
+ tmp_obj = get_in_object(global, "log_size", TRUE);
+ if (tmp_obj == NULL) {
+ /* no size ? use file system */
+ opts->logsize = -2;
+ } else {
+ if (json_object_is_type(tmp_obj, json_type_int)) {
+ /* integer (no " ") detected. */
+ /* buffer size is set in MB */
+ opts->logsize = json_object_get_int(tmp_obj) << 20;
+ log_notice("Log buffer size fixed to %dMB per threads", (opts->logsize >> 20));
+ } else {
+ /* Get CPU number */
+ tmp_str = get_string_value_from(global, "log_size",
+ TRUE, "disable");
+
+ if (strcmp(tmp_str, "disable"))
+ opts->logsize = 0;
+ else if (strcmp(tmp_str, "file"))
+ opts->logsize = -2;
+ else if (strcmp(tmp_str, "auto"))
+ opts->logsize = -2; /* Automatic buffer size computation is not supported yet so we fall back on file system mode */
+
+ log_debug("Log buffer set to %s mode", tmp_str);
+
+ /*
+ * get_string_value_from allocate the string so with have to free it
+ * once useless
+ */
+ free(tmp_str);
+ }
+ }
+
opts->logdir = get_string_value_from(global, "logdir", TRUE, "./");
opts->lock_pages = get_bool_value_from(global, "lock_pages", TRUE, 1);
opts->logbasename = get_string_value_from(global, "log_basename",
diff --git a/src/rt-app_types.h b/src/rt-app_types.h
index 1075f64..eca8ff1 100644
--- a/src/rt-app_types.h
+++ b/src/rt-app_types.h
@@ -156,6 +156,7 @@ typedef struct _rtapp_options_t {
char *logdir;
char *logbasename;
+ int logsize;
int gnuplot;
int calib_cpu;
int calib_ns_per_loop;