self->size = action_default_size;
self->list = calloc(self->size, sizeof(struct action));
self->len = 0;
+ self->continue_flag = false;
memset(&self->present, 0, sizeof(self->present));
return 0;
}
+/*
+ * actions_add_continue - add an action to resume measurement
+ */
+int
+actions_add_continue(struct actions *self)
+{
+ struct action *action = actions_new(self);
+
+ self->present[ACTION_CONTINUE] = true;
+ action->type = ACTION_CONTINUE;
+
+ return 0;
+}
+
/*
* actions_parse - add an action based on text specification
*/
type = ACTION_SIGNAL;
else if (strcmp(token, "shell") == 0)
type = ACTION_SHELL;
+ else if (strcmp(token, "continue") == 0)
+ type = ACTION_CONTINUE;
else
/* Invalid trigger type */
return -1;
if (strlen(token) > 8 && strncmp(token, "command=", 8) == 0)
return actions_add_shell(self, token + 8);
return -1;
+ case ACTION_CONTINUE:
+ /* Takes no argument */
+ if (token != NULL)
+ return -1;
+ return actions_add_continue(self);
default:
return -1;
}
* actions_perform - perform all actions
*/
int
-actions_perform(const struct actions *self)
+actions_perform(struct actions *self)
{
int pid, retval;
const struct action *action;
if (retval)
return retval;
break;
+ case ACTION_CONTINUE:
+ self->continue_flag = true;
+ return 0;
default:
break;
}
goto out_hist;
}
- if (osnoise_trace_is_off(tool, record))
- break;
+ if (osnoise_trace_is_off(tool, record)) {
+ actions_perform(¶ms->actions);
+
+ if (!params->actions.continue_flag)
+ /* continue flag not set, break */
+ break;
+
+ /* continue action reached, re-enable tracing */
+ if (params->actions.present[ACTION_TRACE_OUTPUT])
+ trace_instance_start(&record->trace);
+ if (!params->no_aa)
+ trace_instance_start(&aa->trace);
+ trace_instance_start(trace);
+ }
/* is there still any user-threads ? */
if (params->user_workload) {
}
}
}
- } else
- timerlat_bpf_wait(-1);
+ } else {
+ while (!stop_tracing) {
+ timerlat_bpf_wait(-1);
+
+ if (!stop_tracing) {
+ /* Threshold overflow, perform actions on threshold */
+ actions_perform(¶ms->actions);
+
+ if (!params->actions.continue_flag)
+ /* continue flag not set, break */
+ break;
+
+ /* continue action reached, re-enable tracing */
+ if (params->actions.present[ACTION_TRACE_OUTPUT])
+ trace_instance_start(&record->trace);
+ if (!params->no_aa)
+ trace_instance_start(&aa->trace);
+ timerlat_bpf_restart_tracing();
+ }
+ }
+ }
if (params->mode != TRACING_MODE_TRACEFS) {
timerlat_bpf_detach();
if (!params->no_aa)
timerlat_auto_analysis(params->stop_us, params->stop_total_us);
- actions_perform(¶ms->actions);
return_value = FAILED;
}
static int
timerlat_top_main_loop(struct osnoise_tool *top,
struct osnoise_tool *record,
+ struct osnoise_tool *aa,
struct timerlat_params *params,
struct timerlat_u_params *params_u)
{
if (!params->quiet)
timerlat_print_stats(params, top);
- if (osnoise_trace_is_off(top, record))
- break;
+ if (osnoise_trace_is_off(top, record)) {
+ actions_perform(¶ms->actions);
+
+ if (!params->actions.continue_flag)
+ /* continue flag not set, break */
+ break;
+
+ /* continue action reached, re-enable tracing */
+ if (params->actions.present[ACTION_TRACE_OUTPUT])
+ trace_instance_start(&record->trace);
+ if (!params->no_aa)
+ trace_instance_start(&aa->trace);
+ trace_instance_start(trace);
+ }
/* is there still any user-threads ? */
if (params->user_workload) {
static int
timerlat_top_bpf_main_loop(struct osnoise_tool *top,
struct osnoise_tool *record,
+ struct osnoise_tool *aa,
struct timerlat_params *params,
struct timerlat_u_params *params_u)
{
return 0;
}
- if (params->quiet) {
- /* Quiet mode: wait for stop and then, print results */
- timerlat_bpf_wait(-1);
-
- retval = timerlat_top_bpf_pull_data(top);
- if (retval) {
- err_msg("Error pulling BPF data\n");
- return retval;
- }
-
- return 0;
- }
-
/* Pull and display data in a loop */
while (!stop_tracing) {
- wait_retval = timerlat_bpf_wait(params->sleep_time);
+ wait_retval = timerlat_bpf_wait(params->quiet ? -1 : params->sleep_time);
retval = timerlat_top_bpf_pull_data(top);
if (retval) {
return retval;
}
- timerlat_print_stats(params, top);
+ if (!params->quiet)
+ timerlat_print_stats(params, top);
- if (wait_retval == 1)
+ if (wait_retval == 1) {
/* Stopping requested by tracer */
- break;
+ actions_perform(¶ms->actions);
+
+ if (!params->actions.continue_flag)
+ /* continue flag not set, break */
+ break;
+
+ /* continue action reached, re-enable tracing */
+ if (params->actions.present[ACTION_TRACE_OUTPUT])
+ trace_instance_start(&record->trace);
+ if (!params->no_aa)
+ trace_instance_start(&aa->trace);
+ timerlat_bpf_restart_tracing();
+ }
/* is there still any user-threads ? */
if (params->user_workload) {
timerlat_top_set_signals(params);
if (params->mode == TRACING_MODE_TRACEFS)
- retval = timerlat_top_main_loop(top, record, params, ¶ms_u);
+ retval = timerlat_top_main_loop(top, record, aa, params, ¶ms_u);
else
- retval = timerlat_top_bpf_main_loop(top, record, params, ¶ms_u);
+ retval = timerlat_top_bpf_main_loop(top, record, aa, params, ¶ms_u);
if (retval)
goto out_top;
if (!params->no_aa)
timerlat_auto_analysis(params->stop_us, params->stop_total_us);
- actions_perform(¶ms->actions);
return_value = FAILED;
} else if (params->aa_only) {
/*