Commit 2f3172f9 authored by Crystal Wood's avatar Crystal Wood Committed by Steven Rostedt (Google)
Browse files

tools/rtla: Consolidate code between osnoise/timerlat and hist/top

Currently a lot of code is duplicated between the different rtla tools,
making maintenance more difficult, and encouraging divergence such as
features that are only implemented for certain tools even though they
could be more broadly applicable.

Merge the various main() functions into a common run_tool() with an ops
struct for tool-specific details.

Implement enough support for actions on osnoise to not need to keep the
old params->trace_output path.

Cc: John Kacur <jkacur@redhat.com>
Cc: Costa Shulyupin <costa.shul@redhat.com>
Link: https://lore.kernel.org/20250907022325.243930-5-crwood@redhat.com


Reviewed-by: default avatarTomas Glozar <tglozar@redhat.com>
Signed-off-by: default avatarCrystal Wood <crwood@redhat.com>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent 263d7eac
Loading
Loading
Loading
Loading
+281 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE

#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include "common.h"

struct trace_instance *trace_inst;
int stop_tracing;

static void stop_trace(int sig)
{
	if (stop_tracing) {
		/*
		 * Stop requested twice in a row; abort event processing and
		 * exit immediately
		 */
		tracefs_iterate_stop(trace_inst->inst);
		return;
	}
	stop_tracing = 1;
	if (trace_inst)
		trace_instance_stop(trace_inst);
}

/*
 * set_signals - handles the signal to stop the tool
 */
static void set_signals(struct common_params *params)
{
	signal(SIGINT, stop_trace);
	if (params->duration) {
		signal(SIGALRM, stop_trace);
		alarm(params->duration);
	}
}

/*
 * common_apply_config - apply common configs to the initialized tool
 */
@@ -61,3 +94,251 @@ common_apply_config(struct osnoise_tool *tool, struct common_params *params)
	return -1;
}


int run_tool(struct tool_ops *ops, int argc, char *argv[])
{
	struct common_params *params;
	enum result return_value = ERROR;
	struct osnoise_tool *tool;
	bool stopped;
	int retval;

	params = ops->parse_args(argc, argv);
	if (!params)
		exit(1);

	tool = ops->init_tool(params);
	if (!tool) {
		err_msg("Could not init osnoise tool\n");
		goto out_exit;
	}
	tool->ops = ops;
	tool->params = params;

	/*
	 * Save trace instance into global variable so that SIGINT can stop
	 * the timerlat tracer.
	 * Otherwise, rtla could loop indefinitely when overloaded.
	 */
	trace_inst = &tool->trace;

	retval = ops->apply_config(tool);
	if (retval) {
		err_msg("Could not apply config\n");
		goto out_free;
	}

	retval = enable_tracer_by_name(trace_inst->inst, ops->tracer);
	if (retval) {
		err_msg("Failed to enable %s tracer\n", ops->tracer);
		goto out_free;
	}

	if (params->set_sched) {
		retval = set_comm_sched_attr(ops->comm_prefix, &params->sched_param);
		if (retval) {
			err_msg("Failed to set sched parameters\n");
			goto out_free;
		}
	}

	if (params->cgroup && !params->user_data) {
		retval = set_comm_cgroup(ops->comm_prefix, params->cgroup_name);
		if (!retval) {
			err_msg("Failed to move threads to cgroup\n");
			goto out_free;
		}
	}


	if (params->threshold_actions.present[ACTION_TRACE_OUTPUT] ||
	    params->end_actions.present[ACTION_TRACE_OUTPUT]) {
		tool->record = osnoise_init_trace_tool(ops->tracer);
		if (!tool->record) {
			err_msg("Failed to enable the trace instance\n");
			goto out_free;
		}
		params->threshold_actions.trace_output_inst = tool->record->trace.inst;
		params->end_actions.trace_output_inst = tool->record->trace.inst;

		if (params->events) {
			retval = trace_events_enable(&tool->record->trace, params->events);
			if (retval)
				goto out_trace;
		}

		if (params->buffer_size > 0) {
			retval = trace_set_buffer_size(&tool->record->trace, params->buffer_size);
			if (retval)
				goto out_trace;
		}
	}

	if (params->user_workload) {
		pthread_t user_thread;

		/* rtla asked to stop */
		params->user.should_run = 1;
		/* all threads left */
		params->user.stopped_running = 0;

		params->user.set = &params->monitored_cpus;
		if (params->set_sched)
			params->user.sched_param = &params->sched_param;
		else
			params->user.sched_param = NULL;

		params->user.cgroup_name = params->cgroup_name;

		retval = pthread_create(&user_thread, NULL, timerlat_u_dispatcher, &params->user);
		if (retval)
			err_msg("Error creating timerlat user-space threads\n");
	}

	retval = ops->enable(tool);
	if (retval)
		goto out_trace;

	tool->start_time = time(NULL);
	set_signals(params);

	retval = ops->main(tool);
	if (retval)
		goto out_trace;

	if (params->user_workload && !params->user.stopped_running) {
		params->user.should_run = 0;
		sleep(1);
	}

	ops->print_stats(tool);

	actions_perform(&params->end_actions);

	return_value = PASSED;

	stopped = osnoise_trace_is_off(tool, tool->record) && !stop_tracing;
	if (stopped) {
		printf("%s hit stop tracing\n", ops->tracer);
		return_value = FAILED;
	}

	if (ops->analyze)
		ops->analyze(tool, stopped);

out_trace:
	trace_events_destroy(&tool->record->trace, params->events);
	params->events = NULL;
out_free:
	ops->free(tool);
	osnoise_destroy_tool(tool->record);
	osnoise_destroy_tool(tool);
	actions_destroy(&params->threshold_actions);
	actions_destroy(&params->end_actions);
	free(params);
out_exit:
	exit(return_value);
}

int top_main_loop(struct osnoise_tool *tool)
{
	struct common_params *params = tool->params;
	struct trace_instance *trace = &tool->trace;
	struct osnoise_tool *record = tool->record;
	int retval;

	while (!stop_tracing) {
		sleep(params->sleep_time);

		if (params->aa_only && !osnoise_trace_is_off(tool, record))
			continue;

		retval = tracefs_iterate_raw_events(trace->tep,
						    trace->inst,
						    NULL,
						    0,
						    collect_registered_events,
						    trace);
		if (retval < 0) {
			err_msg("Error iterating on events\n");
			return retval;
		}

		if (!params->quiet)
			tool->ops->print_stats(tool);

		if (osnoise_trace_is_off(tool, record)) {
			actions_perform(&params->threshold_actions);

			if (!params->threshold_actions.continue_flag)
				/* continue flag not set, break */
				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);
		}

		/* is there still any user-threads ? */
		if (params->user_workload) {
			if (params->user.stopped_running) {
				debug_msg("timerlat user space threads stopped!\n");
				break;
			}
		}
	}

	return 0;
}

int hist_main_loop(struct osnoise_tool *tool)
{
	struct common_params *params = tool->params;
	struct trace_instance *trace = &tool->trace;
	int retval = 0;

	while (!stop_tracing) {
		sleep(params->sleep_time);

		retval = tracefs_iterate_raw_events(trace->tep,
						    trace->inst,
						    NULL,
						    0,
						    collect_registered_events,
						    trace);
		if (retval < 0) {
			err_msg("Error iterating on events\n");
			break;
		}

		if (osnoise_trace_is_off(tool, tool->record)) {
			actions_perform(&params->threshold_actions);

			if (!params->threshold_actions.continue_flag) {
				/* continue flag not set, break */
				break;

				/* 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);
			}
			break;
		}

		/* is there still any user-threads ? */
		if (params->user_workload) {
			if (params->user.stopped_running) {
				debug_msg("user-space threads stopped!\n");
				break;
			}
		}
	}

	return retval;
}
+50 −10
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
#pragma once

#include "actions.h"
#include "timerlat_u.h"
#include "trace.h"
#include "utils.h"

@@ -51,16 +53,8 @@ struct osnoise_context {
	int			opt_workload;
};

/*
 * osnoise_tool -  osnoise based tool definition.
 */
struct osnoise_tool {
	struct trace_instance		trace;
	struct osnoise_context		*context;
	void				*data;
	void				*params;
	time_t				start_time;
};
extern struct trace_instance *trace_inst;
extern int stop_tracing;

struct hist_params {
	char			no_irq;
@@ -103,7 +97,46 @@ struct common_params {
	int			output_divisor;
	int			pretty_output;
	int			quiet;
	int			user_workload;
	int			kernel_workload;
	int			user_data;
	int			aa_only;

	struct actions		threshold_actions;
	struct actions		end_actions;
	struct timerlat_u_params user;
};

struct tool_ops;

/*
 * osnoise_tool -  osnoise based tool definition.
 *
 * Only the "trace" and "context" fields are used for
 * the additional trace instances (record and aa).
 */
struct osnoise_tool {
	struct tool_ops			*ops;
	struct trace_instance		trace;
	struct osnoise_context		*context;
	void				*data;
	struct common_params		*params;
	time_t				start_time;
	struct osnoise_tool		*record;
	struct osnoise_tool		*aa;
};

struct tool_ops {
	const char *tracer;
	const char *comm_prefix;
	struct common_params *(*parse_args)(int argc, char *argv[]);
	struct osnoise_tool *(*init_tool)(struct common_params *params);
	int (*apply_config)(struct osnoise_tool *tool);
	int (*enable)(struct osnoise_tool *tool);
	int (*main)(struct osnoise_tool *tool);
	void (*print_stats)(struct osnoise_tool *tool);
	void (*analyze)(struct osnoise_tool *tool, bool stopped);
	void (*free)(struct osnoise_tool *tool);
};

int osnoise_set_cpus(struct osnoise_context *context, char *cpus);
@@ -111,4 +144,11 @@ void osnoise_restore_cpus(struct osnoise_context *context);

int osnoise_set_workload(struct osnoise_context *context, bool onoff);

void osnoise_destroy_tool(struct osnoise_tool *top);
struct osnoise_tool *osnoise_init_tool(char *tool_name);
struct osnoise_tool *osnoise_init_trace_tool(const char *tracer);
bool osnoise_trace_is_off(struct osnoise_tool *tool, struct osnoise_tool *record);

int common_apply_config(struct osnoise_tool *tool, struct common_params *params);
int top_main_loop(struct osnoise_tool *tool);
int hist_main_loop(struct osnoise_tool *tool);
+44 −22
Original line number Diff line number Diff line
@@ -906,22 +906,6 @@ static void osnoise_put_workload(struct osnoise_context *context)
	context->orig_opt_workload = OSNOISE_OPTION_INIT_VAL;
}

/*
 * enable_osnoise - enable osnoise tracer in the trace_instance
 */
int enable_osnoise(struct trace_instance *trace)
{
	return enable_tracer_by_name(trace->inst, "osnoise");
}

/*
 * enable_timerlat - enable timerlat tracer in the trace_instance
 */
int enable_timerlat(struct trace_instance *trace)
{
	return enable_tracer_by_name(trace->inst, "timerlat");
}

enum {
	FLAG_CONTEXT_NEWLY_CREATED	= (1 << 0),
	FLAG_CONTEXT_DELETED		= (1 << 1),
@@ -1056,7 +1040,7 @@ struct osnoise_tool *osnoise_init_tool(char *tool_name)
/*
 * osnoise_init_trace_tool - init a tracer instance to trace osnoise events
 */
struct osnoise_tool *osnoise_init_trace_tool(char *tracer)
struct osnoise_tool *osnoise_init_trace_tool(const char *tracer)
{
	struct osnoise_tool *trace;
	int retval;
@@ -1168,6 +1152,44 @@ osnoise_apply_config(struct osnoise_tool *tool, struct osnoise_params *params)
	return -1;
}

int osnoise_enable(struct osnoise_tool *tool)
{
	struct osnoise_params *params = to_osnoise_params(tool->params);
	int retval;

	/*
	 * Start the tracer here, after having set all instances.
	 *
	 * Let the trace instance start first for the case of hitting a stop
	 * tracing while enabling other instances. The trace instance is the
	 * one with most valuable information.
	 */
	if (tool->record)
		trace_instance_start(&tool->record->trace);
	trace_instance_start(&tool->trace);

	if (params->common.warmup > 0) {
		debug_msg("Warming up for %d seconds\n", params->common.warmup);
		sleep(params->common.warmup);
		if (stop_tracing)
			return -1;

		/*
		 * Clean up the buffer. The osnoise workload do not run
		 * with tracing off to avoid creating a performance penalty
		 * when not needed.
		 */
		retval = tracefs_instance_file_write(tool->trace.inst, "trace", "");
		if (retval < 0) {
			debug_msg("Error cleaning up the buffer");
			return retval;
		}

	}

	return 0;
}

static void osnoise_usage(int err)
{
	int i;
@@ -1201,7 +1223,7 @@ int osnoise_main(int argc, char *argv[])
	 * default cmdline.
	 */
	if (argc == 1) {
		osnoise_top_main(argc, argv);
		run_tool(&osnoise_top_ops, argc, argv);
		exit(0);
	}

@@ -1209,13 +1231,13 @@ int osnoise_main(int argc, char *argv[])
		osnoise_usage(0);
	} else if (strncmp(argv[1], "-", 1) == 0) {
		/* the user skipped the tool, call the default one */
		osnoise_top_main(argc, argv);
		run_tool(&osnoise_top_ops, argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "top") == 0) {
		osnoise_top_main(argc-1, &argv[1]);
		run_tool(&osnoise_top_ops, argc-1, &argv[1]);
		exit(0);
	} else if (strcmp(argv[1], "hist") == 0) {
		osnoise_hist_main(argc-1, &argv[1]);
		run_tool(&osnoise_hist_ops, argc-1, &argv[1]);
		exit(0);
	}

@@ -1226,6 +1248,6 @@ int osnoise_main(int argc, char *argv[])

int hwnoise_main(int argc, char *argv[])
{
	osnoise_top_main(argc, argv);
	run_tool(&osnoise_top_ops, argc, argv);
	exit(0);
}
+9 −5
Original line number Diff line number Diff line
@@ -10,13 +10,14 @@ enum osnoise_mode {

struct osnoise_params {
	struct common_params	common;
	char			*trace_output;
	unsigned long long	runtime;
	unsigned long long	period;
	long long		threshold;
	enum osnoise_mode	mode;
};

#define to_osnoise_params(ptr) container_of(ptr, struct osnoise_params, common)

/*
 * *_INIT_VALs are also invalid values, they are used to
 * communicate errors.
@@ -54,14 +55,17 @@ int osnoise_set_print_stack(struct osnoise_context *context,
			    long long print_stack);

int osnoise_set_irq_disable(struct osnoise_context *context, bool onoff);
void osnoise_destroy_tool(struct osnoise_tool *top);
struct osnoise_tool *osnoise_init_tool(char *tool_name);
struct osnoise_tool *osnoise_init_trace_tool(char *tracer);
void osnoise_report_missed_events(struct osnoise_tool *tool);
bool osnoise_trace_is_off(struct osnoise_tool *tool, struct osnoise_tool *record);
int osnoise_apply_config(struct osnoise_tool *tool, struct osnoise_params *params);

int osnoise_hist_main(int argc, char *argv[]);
int osnoise_top_main(int argc, char **argv);
int osnoise_enable(struct osnoise_tool *tool);
int osnoise_main(int argc, char **argv);
int hwnoise_main(int argc, char **argv);

extern struct tool_ops timerlat_top_ops, timerlat_hist_ops;
extern struct tool_ops osnoise_top_ops, osnoise_hist_ops;

int run_tool(struct tool_ops *ops, int argc, char *argv[]);
int hist_main_loop(struct osnoise_tool *tool);
+50 −184
Original line number Diff line number Diff line
@@ -54,6 +54,11 @@ osnoise_free_histogram(struct osnoise_hist_data *data)
	free(data);
}

static void osnoise_free_hist_tool(struct osnoise_tool *tool)
{
	osnoise_free_histogram(tool->data);
}

/*
 * osnoise_alloc_histogram - alloc runtime data
 */
@@ -95,7 +100,7 @@ static struct osnoise_hist_data
static void osnoise_hist_update_multiple(struct osnoise_tool *tool, int cpu,
					 unsigned long long duration, int count)
{
	struct osnoise_params *params = tool->params;
	struct osnoise_params *params = to_osnoise_params(tool->params);
	struct osnoise_hist_data *data = tool->data;
	unsigned long long total_duration;
	int entries = data->entries;
@@ -137,7 +142,7 @@ static void osnoise_destroy_trace_hist(struct osnoise_tool *tool)
 */
static int osnoise_init_trace_hist(struct osnoise_tool *tool)
{
	struct osnoise_params *params = tool->params;
	struct osnoise_params *params = to_osnoise_params(tool->params);
	struct osnoise_hist_data *data = tool->data;
	int bucket_size;
	char buff[128];
@@ -222,7 +227,7 @@ static void osnoise_read_trace_hist(struct osnoise_tool *tool)
 */
static void osnoise_hist_header(struct osnoise_tool *tool)
{
	struct osnoise_params *params = tool->params;
	struct osnoise_params *params = to_osnoise_params(tool->params);
	struct osnoise_hist_data *data = tool->data;
	struct trace_seq *s = tool->trace.seq;
	char duration[26];
@@ -339,8 +344,9 @@ osnoise_print_summary(struct osnoise_params *params,
 * osnoise_print_stats - print data for all CPUs
 */
static void
osnoise_print_stats(struct osnoise_params *params, struct osnoise_tool *tool)
osnoise_print_stats(struct osnoise_tool *tool)
{
	struct osnoise_params *params = to_osnoise_params(tool->params);
	struct osnoise_hist_data *data = tool->data;
	struct trace_instance *trace = &tool->trace;
	int has_samples = 0;
@@ -477,18 +483,22 @@ static void osnoise_hist_usage(char *usage)
/*
 * osnoise_hist_parse_args - allocs, parse and fill the cmd line parameters
 */
static struct osnoise_params
static struct common_params
*osnoise_hist_parse_args(int argc, char *argv[])
{
	struct osnoise_params *params;
	struct trace_events *tevent;
	int retval;
	int c;
	char *trace_output = NULL;

	params = calloc(1, sizeof(*params));
	if (!params)
		exit(1);

	actions_init(&params->common.threshold_actions);
	actions_init(&params->common.end_actions);

	/* display data in microseconds */
	params->common.output_divisor = 1000;
	params->common.hist.bucket_size = 1;
@@ -543,7 +553,7 @@ static struct osnoise_params
			params->threshold = 1;

			/* set trace */
			params->trace_output = "osnoise_trace.txt";
			trace_output = "osnoise_trace.txt";

			break;
		case 'b':
@@ -634,13 +644,13 @@ static struct osnoise_params
		case 't':
			if (optarg) {
				if (optarg[0] == '=')
					params->trace_output = &optarg[1];
					trace_output = &optarg[1];
				else
					params->trace_output = &optarg[0];
					trace_output = &optarg[0];
			} else if (optind < argc && argv[optind][0] != '0')
				params->trace_output = argv[optind];
				trace_output = argv[optind];
			else
				params->trace_output = "osnoise_trace.txt";
				trace_output = "osnoise_trace.txt";
			break;
		case '0': /* no header */
			params->common.hist.no_header = 1;
@@ -687,6 +697,9 @@ static struct osnoise_params
		}
	}

	if (trace_output)
		actions_add_trace_output(&params->common.threshold_actions, trace_output);

	if (geteuid()) {
		err_msg("rtla needs root permission\n");
		exit(EXIT_FAILURE);
@@ -695,32 +708,23 @@ static struct osnoise_params
	if (params->common.hist.no_index && !params->common.hist.with_zeros)
		osnoise_hist_usage("no-index set and with-zeros not set - it does not make sense");

	return params;
	return &params->common;
}

/*
 * osnoise_hist_apply_config - apply the hist configs to the initialized tool
 */
static int
osnoise_hist_apply_config(struct osnoise_tool *tool, struct osnoise_params *params)
osnoise_hist_apply_config(struct osnoise_tool *tool)
{
	int retval;

	retval = osnoise_apply_config(tool, params);
	if (retval)
		goto out_err;

	return 0;

out_err:
	return -1;
	return osnoise_apply_config(tool, to_osnoise_params(tool->params));
}

/*
 * osnoise_init_hist - initialize a osnoise hist tool with parameters
 */
static struct osnoise_tool
*osnoise_init_hist(struct osnoise_params *params)
*osnoise_init_hist(struct common_params *params)
{
	struct osnoise_tool *tool;
	int nr_cpus;
@@ -731,13 +735,11 @@ static struct osnoise_tool
	if (!tool)
		return NULL;

	tool->data = osnoise_alloc_histogram(nr_cpus, params->common.hist.entries,
					     params->common.hist.bucket_size);
	tool->data = osnoise_alloc_histogram(nr_cpus, params->hist.entries,
					     params->hist.bucket_size);
	if (!tool->data)
		goto out_err;

	tool->params = params;

	return tool;

out_err:
@@ -745,171 +747,35 @@ static struct osnoise_tool
	return NULL;
}

static int stop_tracing;
static void stop_hist(int sig)
static int osnoise_hist_enable(struct osnoise_tool *tool)
{
	stop_tracing = 1;
}

/*
 * osnoise_hist_set_signals - handles the signal to stop the tool
 */
static void
osnoise_hist_set_signals(struct osnoise_params *params)
{
	signal(SIGINT, stop_hist);
	if (params->common.duration) {
		signal(SIGALRM, stop_hist);
		alarm(params->common.duration);
	}
}

int osnoise_hist_main(int argc, char *argv[])
{
	struct osnoise_params *params;
	struct osnoise_tool *record = NULL;
	struct osnoise_tool *tool = NULL;
	enum result return_value = ERROR;
	struct trace_instance *trace;
	int retval;

	params = osnoise_hist_parse_args(argc, argv);
	if (!params)
		exit(1);

	tool = osnoise_init_hist(params);
	if (!tool) {
		err_msg("Could not init osnoise hist\n");
		goto out_exit;
	}

	retval = osnoise_hist_apply_config(tool, params);
	if (retval) {
		err_msg("Could not apply config\n");
		goto out_destroy;
	}

	trace = &tool->trace;

	retval = enable_osnoise(trace);
	if (retval) {
		err_msg("Failed to enable osnoise tracer\n");
		goto out_destroy;
	}

	retval = osnoise_init_trace_hist(tool);
	if (retval)
		goto out_destroy;

	if (params->common.set_sched) {
		retval = set_comm_sched_attr("osnoise/", &params->common.sched_param);
		if (retval) {
			err_msg("Failed to set sched parameters\n");
			goto out_free;
		}
	}

	if (params->common.cgroup) {
		retval = set_comm_cgroup("timerlat/", params->common.cgroup_name);
		if (!retval) {
			err_msg("Failed to move threads to cgroup\n");
			goto out_free;
		}
	}

	if (params->trace_output) {
		record = osnoise_init_trace_tool("osnoise");
		if (!record) {
			err_msg("Failed to enable the trace instance\n");
			goto out_free;
		}

		if (params->common.events) {
			retval = trace_events_enable(&record->trace, params->common.events);
			if (retval)
				goto out_hist;
		}
		return retval;

		if (params->common.buffer_size > 0) {
			retval = trace_set_buffer_size(&record->trace, params->common.buffer_size);
			if (retval)
				goto out_hist;
	return osnoise_enable(tool);
}
	}

	/*
	 * Start the tracer here, after having set all instances.
	 *
	 * Let the trace instance start first for the case of hitting a stop
	 * tracing while enabling other instances. The trace instance is the
	 * one with most valuable information.
	 */
	if (params->trace_output)
		trace_instance_start(&record->trace);
	trace_instance_start(trace);

	if (params->common.warmup > 0) {
		debug_msg("Warming up for %d seconds\n", params->common.warmup);
		sleep(params->common.warmup);
		if (stop_tracing)
			goto out_hist;

		/*
		 * Clean up the buffer. The osnoise workload do not run
		 * with tracing off to avoid creating a performance penalty
		 * when not needed.
		 */
		retval = tracefs_instance_file_write(trace->inst, "trace", "");
		if (retval < 0) {
			debug_msg("Error cleaning up the buffer");
			goto out_hist;
		}

	}

	tool->start_time = time(NULL);
	osnoise_hist_set_signals(params);

	while (!stop_tracing) {
		sleep(params->common.sleep_time);

		retval = tracefs_iterate_raw_events(trace->tep,
						    trace->inst,
						    NULL,
						    0,
						    collect_registered_events,
						    trace);
		if (retval < 0) {
			err_msg("Error iterating on events\n");
			goto out_hist;
		}

		if (osnoise_trace_is_off(tool, record))
			break;
	}
static int osnoise_hist_main_loop(struct osnoise_tool *tool)
{
	int retval;

	retval = hist_main_loop(tool);
	osnoise_read_trace_hist(tool);

	osnoise_print_stats(params, tool);

	return_value = PASSED;

	if (osnoise_trace_is_off(tool, record)) {
		printf("rtla osnoise hit stop tracing\n");
		save_trace_to_file(record ? record->trace.inst : NULL,
				   params->trace_output);
		return_value = FAILED;
	return retval;
}

out_hist:
	trace_events_destroy(&record->trace, params->common.events);
	params->common.events = NULL;
out_free:
	osnoise_free_histogram(tool->data);
out_destroy:
	osnoise_destroy_tool(record);
	osnoise_destroy_tool(tool);
	free(params);
out_exit:
	exit(return_value);
}
struct tool_ops osnoise_hist_ops = {
	.tracer = "osnoise",
	.comm_prefix = "osnoise/",
	.parse_args = osnoise_hist_parse_args,
	.init_tool = osnoise_init_hist,
	.apply_config = osnoise_hist_apply_config,
	.enable = osnoise_hist_enable,
	.main = osnoise_hist_main_loop,
	.print_stats = osnoise_print_stats,
	.free = osnoise_free_hist_tool,
};
Loading