diff options
Diffstat (limited to 'tools/tracing/rtla/src/common.c')
| -rw-r--r-- | tools/tracing/rtla/src/common.c | 167 |
1 files changed, 137 insertions, 30 deletions
diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c index b197037fc58b..8c7f5e75b2ec 100644 --- a/tools/tracing/rtla/src/common.c +++ b/tools/tracing/rtla/src/common.c @@ -4,11 +4,15 @@ #include <pthread.h> #include <signal.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> +#include <sys/sysinfo.h> + #include "common.h" -struct trace_instance *trace_inst; -int stop_tracing; +struct osnoise_tool *trace_tool; +volatile int stop_tracing; +int nr_cpus; static void stop_trace(int sig) { @@ -17,12 +21,16 @@ static void stop_trace(int sig) * Stop requested twice in a row; abort event processing and * exit immediately */ - tracefs_iterate_stop(trace_inst->inst); + if (trace_tool) + tracefs_iterate_stop(trace_tool->trace.inst); return; } stop_tracing = 1; - if (trace_inst) - trace_instance_stop(trace_inst); + if (trace_tool) { + trace_instance_stop(&trace_tool->trace); + if (trace_tool->record) + trace_instance_stop(&trace_tool->record->trace); + } } /* @@ -38,6 +46,18 @@ static void set_signals(struct common_params *params) } /* + * unset_signals - unsets the signals to stop the tool + */ +static void unset_signals(struct common_params *params) +{ + signal(SIGINT, SIG_DFL); + if (params->duration) { + alarm(0); + signal(SIGALRM, SIG_DFL); + } +} + +/* * common_apply_config - apply common configs to the initialized tool */ int @@ -55,7 +75,7 @@ common_apply_config(struct osnoise_tool *tool, struct common_params *params) } if (!params->cpus) { - for (i = 0; i < sysconf(_SC_NPROCESSORS_CONF); i++) + for (i = 0; i < nr_cpus; i++) CPU_SET(i, ¶ms->monitored_cpus); } @@ -95,6 +115,38 @@ out_err: } +/** + * common_threshold_handler - handle latency threshold overflow + * @tool: pointer to the osnoise_tool instance containing trace contexts + * + * Executes the configured threshold actions (e.g., saving trace, printing, + * sending signals). If the continue flag is set (--on-threshold continue), + * restarts the auxiliary trace instances to continue monitoring. + * + * Return: 0 for success, -1 for error. + */ +int +common_threshold_handler(const struct osnoise_tool *tool) +{ + actions_perform(&tool->params->threshold_actions); + + if (!should_continue_tracing(tool->params)) + /* continue flag not set, break */ + return 0; + + /* continue action reached, re-enable tracing */ + if (tool->record && trace_instance_start(&tool->record->trace)) + goto err; + if (tool->aa && trace_instance_start(&tool->aa->trace)) + goto err; + + return 0; + +err: + err_msg("Error restarting trace\n"); + return -1; +} + int run_tool(struct tool_ops *ops, int argc, char *argv[]) { struct common_params *params; @@ -103,6 +155,7 @@ int run_tool(struct tool_ops *ops, int argc, char *argv[]) bool stopped; int retval; + nr_cpus = get_nprocs_conf(); params = ops->parse_args(argc, argv); if (!params) exit(1); @@ -116,11 +169,10 @@ int run_tool(struct tool_ops *ops, int argc, char *argv[]) tool->params = params; /* - * Save trace instance into global variable so that SIGINT can stop - * the timerlat tracer. + * Expose the tool to signal handlers so they can stop the trace. * Otherwise, rtla could loop indefinitely when overloaded. */ - trace_inst = &tool->trace; + trace_tool = tool; retval = ops->apply_config(tool); if (retval) { @@ -128,7 +180,7 @@ int run_tool(struct tool_ops *ops, int argc, char *argv[]) goto out_free; } - retval = enable_tracer_by_name(trace_inst->inst, ops->tracer); + retval = enable_tracer_by_name(tool->trace.inst, ops->tracer); if (retval) { err_msg("Failed to enable %s tracer\n", ops->tracer); goto out_free; @@ -191,8 +243,10 @@ int run_tool(struct tool_ops *ops, int argc, char *argv[]) params->user.cgroup_name = params->cgroup_name; retval = pthread_create(&user_thread, NULL, timerlat_u_dispatcher, ¶ms->user); - if (retval) + if (retval) { err_msg("Error creating timerlat user-space threads\n"); + goto out_trace; + } } retval = ops->enable(tool); @@ -204,7 +258,7 @@ int run_tool(struct tool_ops *ops, int argc, char *argv[]) retval = ops->main(tool); if (retval) - goto out_trace; + goto out_signals; if (params->user_workload && !params->user.stopped_running) { params->user.should_run = 0; @@ -226,6 +280,8 @@ int run_tool(struct tool_ops *ops, int argc, char *argv[]) if (ops->analyze) ops->analyze(tool, stopped); +out_signals: + unset_signals(params); out_trace: trace_events_destroy(&tool->record->trace, params->events); params->events = NULL; @@ -272,17 +328,14 @@ int top_main_loop(struct osnoise_tool *tool) /* stop tracing requested, do not perform actions */ return 0; - actions_perform(¶ms->threshold_actions); + retval = common_threshold_handler(tool); + if (retval) + return retval; + - if (!params->threshold_actions.continue_flag) - /* continue flag not set, break */ + if (!should_continue_tracing(params)) return 0; - /* continue action reached, re-enable tracing */ - if (record) - trace_instance_start(&record->trace); - if (tool->aa) - trace_instance_start(&tool->aa->trace); trace_instance_start(trace); } @@ -323,18 +376,14 @@ int hist_main_loop(struct osnoise_tool *tool) /* stop tracing requested, do not perform actions */ break; - actions_perform(¶ms->threshold_actions); + retval = common_threshold_handler(tool); + if (retval) + return retval; - if (!params->threshold_actions.continue_flag) - /* continue flag not set, break */ - break; + if (!should_continue_tracing(params)) + return 0; - /* continue action reached, re-enable tracing */ - if (tool->record) - trace_instance_start(&tool->record->trace); - if (tool->aa) - trace_instance_start(&tool->aa->trace); - trace_instance_start(&tool->trace); + trace_instance_start(trace); } /* is there still any user-threads ? */ @@ -348,3 +397,61 @@ int hist_main_loop(struct osnoise_tool *tool) return retval; } + +int osn_set_stop(struct osnoise_tool *tool) +{ + struct common_params *params = tool->params; + int retval; + + retval = osnoise_set_stop_us(tool->context, params->stop_us); + if (retval) { + err_msg("Failed to set stop us\n"); + return retval; + } + + retval = osnoise_set_stop_total_us(tool->context, params->stop_total_us); + if (retval) { + err_msg("Failed to set stop total us\n"); + return retval; + } + + return 0; +} + +static void print_msg_array(const char * const *msgs) +{ + if (!msgs) + return; + + for (int i = 0; msgs[i]; i++) + fprintf(stderr, "%s\n", msgs[i]); +} + +/* + * common_usage - print complete usage information + */ +void common_usage(const char *tool, const char *mode, + const char *desc, const char * const *start_msgs, const char * const *opt_msgs) +{ + static const char * const common_options[] = { + " -h/--help: print this menu", + NULL + }; + fprintf(stderr, "rtla %s", tool); + if (strcmp(mode, "")) + fprintf(stderr, " %s", mode); + fprintf(stderr, ": %s (version %s)\n\n", desc, VERSION); + fprintf(stderr, " usage: [rtla] %s ", tool); + + if (strcmp(mode, "top") == 0) + fprintf(stderr, "[top] [-h] "); + else + fprintf(stderr, "%s [-h] ", mode); + + print_msg_array(start_msgs); + fprintf(stderr, "\n"); + print_msg_array(common_options); + print_msg_array(opt_msgs); + + exit(EXIT_SUCCESS); +} |
