/* * osnoise_get_cpus - return the original "osnoise/cpus" content * * It also saves the value to be restored.
*/ char *osnoise_get_cpus(struct osnoise_context *context)
{ if (context->curr_cpus) return context->curr_cpus;
if (context->orig_cpus) return context->orig_cpus;
/* * The error value (NULL) is the same for tracefs_instance_file_read() * and this functions, so:
*/ return context->orig_cpus;
}
/* * osnoise_set_cpus - configure osnoise to run on *cpus * * "osnoise/cpus" file is used to set the cpus in which osnoise/timerlat * will run. This function opens this file, saves the current value, * and set the cpus passed as argument.
*/ int osnoise_set_cpus(struct osnoise_context *context, char *cpus)
{ char *orig_cpus = osnoise_get_cpus(context); char buffer[1024]; int retval;
if (!orig_cpus) return -1;
context->curr_cpus = strdup(cpus); if (!context->curr_cpus) return -1;
snprintf(buffer, 1024, "%s\n", cpus);
debug_msg("setting cpus to %s from %s", cpus, context->orig_cpus);
/* * osnoise_restore_cpus - restore the original "osnoise/cpus" * * osnoise_set_cpus() saves the original data for the "osnoise/cpus" * file. This function restore the original config it was previously * modified.
*/ void osnoise_restore_cpus(struct osnoise_context *context)
{ int retval;
if (!context->orig_cpus) return;
if (!context->curr_cpus) return;
/* nothing to do? */ if (!strcmp(context->orig_cpus, context->curr_cpus)) goto out_done;
debug_msg("restoring cpus to %s", context->orig_cpus);
retval = tracefs_instance_file_write(NULL, "osnoise/cpus", context->orig_cpus); if (retval < 0)
err_msg("could not restore original osnoise cpus\n");
/* * osnoise_read_ll_config - read a long long value from a config * * returns -1 on error.
*/ staticlonglong osnoise_read_ll_config(char *rel_path)
{ longlong retval; char *buffer;
buffer = tracefs_instance_file_read(NULL, rel_path, NULL); if (!buffer) return -1;
/* get_llong_from_str returns -1 on error */
retval = get_llong_from_str(buffer);
debug_msg("reading %s returned %lld\n", rel_path, retval);
free(buffer);
return retval;
}
/* * osnoise_write_ll_config - write a long long value to a config in rel_path * * returns -1 on error.
*/ staticlonglong osnoise_write_ll_config(char *rel_path, longlong value)
{ char buffer[BUFF_U64_STR_SIZE]; longlong retval;
/* * osnoise_get_runtime - return the original "osnoise/runtime_us" value * * It also saves the value to be restored.
*/ unsignedlonglong osnoise_get_runtime(struct osnoise_context *context)
{ longlong runtime_us;
if (context->runtime_us != OSNOISE_TIME_INIT_VAL) return context->runtime_us;
if (context->orig_runtime_us != OSNOISE_TIME_INIT_VAL) return context->orig_runtime_us;
runtime_us = osnoise_read_ll_config("osnoise/runtime_us"); if (runtime_us < 0) goto out_err;
/* * osnoise_get_period - return the original "osnoise/period_us" value * * It also saves the value to be restored.
*/ unsignedlonglong osnoise_get_period(struct osnoise_context *context)
{ longlong period_us;
if (context->period_us != OSNOISE_TIME_INIT_VAL) return context->period_us;
if (context->orig_period_us != OSNOISE_TIME_INIT_VAL) return context->orig_period_us;
period_us = osnoise_read_ll_config("osnoise/period_us"); if (period_us < 0) goto out_err;
staticint __osnoise_write_runtime(struct osnoise_context *context, unsignedlonglong runtime)
{ int retval;
if (context->orig_runtime_us == OSNOISE_TIME_INIT_VAL) return -1;
retval = osnoise_write_ll_config("osnoise/runtime_us", runtime); if (retval < 0) return -1;
context->runtime_us = runtime; return 0;
}
staticint __osnoise_write_period(struct osnoise_context *context, unsignedlonglong period)
{ int retval;
if (context->orig_period_us == OSNOISE_TIME_INIT_VAL) return -1;
retval = osnoise_write_ll_config("osnoise/period_us", period); if (retval < 0) return -1;
context->period_us = period; return 0;
}
/* * osnoise_set_runtime_period - set osnoise runtime and period * * Osnoise's runtime and period are related as runtime <= period. * Thus, this function saves the original values, and then tries * to set the runtime and period if they are != 0.
*/ int osnoise_set_runtime_period(struct osnoise_context *context, unsignedlonglong runtime, unsignedlonglong period)
{ unsignedlonglong curr_runtime_us; unsignedlonglong curr_period_us; int retval;
/* * osnoise_put_runtime_period - restore original values and cleanup data
*/ void osnoise_put_runtime_period(struct osnoise_context *context)
{
osnoise_restore_runtime_period(context);
if (context->orig_runtime_us != OSNOISE_TIME_INIT_VAL)
context->orig_runtime_us = OSNOISE_TIME_INIT_VAL;
if (context->orig_period_us != OSNOISE_TIME_INIT_VAL)
context->orig_period_us = OSNOISE_TIME_INIT_VAL;
}
/* * osnoise_get_timerlat_period_us - read and save the original "timerlat_period_us"
*/ staticlonglong
osnoise_get_timerlat_period_us(struct osnoise_context *context)
{ longlong timerlat_period_us;
if (context->timerlat_period_us != OSNOISE_TIME_INIT_VAL) return context->timerlat_period_us;
if (context->orig_timerlat_period_us != OSNOISE_TIME_INIT_VAL) return context->orig_timerlat_period_us;
timerlat_period_us = osnoise_read_ll_config("osnoise/timerlat_period_us"); if (timerlat_period_us < 0) goto out_err;
if (context->orig_timerlat_period_us == OSNOISE_TIME_INIT_VAL) return;
if (context->orig_timerlat_period_us == context->timerlat_period_us) goto out_done;
retval = osnoise_write_ll_config("osnoise/timerlat_period_us", context->orig_timerlat_period_us); if (retval < 0)
err_msg("Could not restore original osnoise timerlat_period_us\n");
/* * osnoise_get_stop_us - read and save the original "stop_tracing_us"
*/ staticlonglong
osnoise_get_stop_us(struct osnoise_context *context)
{ longlong stop_us;
if (context->stop_us != OSNOISE_OPTION_INIT_VAL) return context->stop_us;
if (context->orig_stop_us != OSNOISE_OPTION_INIT_VAL) return context->orig_stop_us;
stop_us = osnoise_read_ll_config("osnoise/stop_tracing_us"); if (stop_us < 0) goto out_err;
context->orig_stop_us = stop_us; return stop_us;
out_err: return OSNOISE_OPTION_INIT_VAL;
}
/* * osnoise_set_stop_us - set "stop_tracing_us"
*/ int osnoise_set_stop_us(struct osnoise_context *context, longlong stop_us)
{ longlong curr_stop_us = osnoise_get_stop_us(context); int retval;
if (curr_stop_us == OSNOISE_OPTION_INIT_VAL) return -1;
retval = osnoise_write_ll_config("osnoise/stop_tracing_us", stop_us); if (retval < 0) return -1;
context->stop_us = stop_us;
return 0;
}
/* * osnoise_restore_stop_us - restore the original "stop_tracing_us"
*/ void osnoise_restore_stop_us(struct osnoise_context *context)
{ int retval;
if (context->orig_stop_us == OSNOISE_OPTION_INIT_VAL) return;
if (context->orig_stop_us == context->stop_us) goto out_done;
retval = osnoise_write_ll_config("osnoise/stop_tracing_us", context->orig_stop_us); if (retval < 0)
err_msg("Could not restore original osnoise stop_us\n");
/* * osnoise_get_stop_total_us - read and save the original "stop_tracing_total_us"
*/ staticlonglong
osnoise_get_stop_total_us(struct osnoise_context *context)
{ longlong stop_total_us;
if (context->stop_total_us != OSNOISE_OPTION_INIT_VAL) return context->stop_total_us;
if (context->orig_stop_total_us != OSNOISE_OPTION_INIT_VAL) return context->orig_stop_total_us;
stop_total_us = osnoise_read_ll_config("osnoise/stop_tracing_total_us"); if (stop_total_us < 0) goto out_err;
/* * osnoise_set_stop_total_us - set "stop_tracing_total_us"
*/ int osnoise_set_stop_total_us(struct osnoise_context *context, longlong stop_total_us)
{ longlong curr_stop_total_us = osnoise_get_stop_total_us(context); int retval;
if (curr_stop_total_us == OSNOISE_OPTION_INIT_VAL) return -1;
retval = osnoise_write_ll_config("osnoise/stop_tracing_total_us", stop_total_us); if (retval < 0) return -1;
context->stop_total_us = stop_total_us;
return 0;
}
/* * osnoise_restore_stop_total_us - restore the original "stop_tracing_total_us"
*/ void osnoise_restore_stop_total_us(struct osnoise_context *context)
{ int retval;
if (context->orig_stop_total_us == OSNOISE_OPTION_INIT_VAL) return;
if (context->orig_stop_total_us == context->stop_total_us) goto out_done;
retval = osnoise_write_ll_config("osnoise/stop_tracing_total_us",
context->orig_stop_total_us); if (retval < 0)
err_msg("Could not restore original osnoise stop_total_us\n");
/* * osnoise_get_print_stack - read and save the original "print_stack"
*/ staticlonglong
osnoise_get_print_stack(struct osnoise_context *context)
{ longlong print_stack;
if (context->print_stack != OSNOISE_OPTION_INIT_VAL) return context->print_stack;
if (context->orig_print_stack != OSNOISE_OPTION_INIT_VAL) return context->orig_print_stack;
print_stack = osnoise_read_ll_config("osnoise/print_stack"); if (print_stack < 0) goto out_err;
/* * osnoise_set_print_stack - set "print_stack"
*/ int osnoise_set_print_stack(struct osnoise_context *context, longlong print_stack)
{ longlong curr_print_stack = osnoise_get_print_stack(context); int retval;
if (curr_print_stack == OSNOISE_OPTION_INIT_VAL) return -1;
retval = osnoise_write_ll_config("osnoise/print_stack", print_stack); if (retval < 0) return -1;
context->print_stack = print_stack;
return 0;
}
/* * osnoise_restore_print_stack - restore the original "print_stack"
*/ void osnoise_restore_print_stack(struct osnoise_context *context)
{ int retval;
if (context->orig_print_stack == OSNOISE_OPTION_INIT_VAL) return;
if (context->orig_print_stack == context->print_stack) goto out_done;
retval = osnoise_write_ll_config("osnoise/print_stack", context->orig_print_stack); if (retval < 0)
err_msg("Could not restore original osnoise print_stack\n");
/* * osnoise_get_tracing_thresh - read and save the original "tracing_thresh"
*/ staticlonglong
osnoise_get_tracing_thresh(struct osnoise_context *context)
{ longlong tracing_thresh;
if (context->tracing_thresh != OSNOISE_OPTION_INIT_VAL) return context->tracing_thresh;
if (context->orig_tracing_thresh != OSNOISE_OPTION_INIT_VAL) return context->orig_tracing_thresh;
tracing_thresh = osnoise_read_ll_config("tracing_thresh"); if (tracing_thresh < 0) goto out_err;
/* * osnoise_set_tracing_thresh - set "tracing_thresh"
*/ int osnoise_set_tracing_thresh(struct osnoise_context *context, longlong tracing_thresh)
{ longlong curr_tracing_thresh = osnoise_get_tracing_thresh(context); int retval;
if (curr_tracing_thresh == OSNOISE_OPTION_INIT_VAL) return -1;
retval = osnoise_write_ll_config("tracing_thresh", tracing_thresh); if (retval < 0) return -1;
context->tracing_thresh = tracing_thresh;
return 0;
}
/* * osnoise_restore_tracing_thresh - restore the original "tracing_thresh"
*/ void osnoise_restore_tracing_thresh(struct osnoise_context *context)
{ int retval;
if (context->orig_tracing_thresh == OSNOISE_OPTION_INIT_VAL) return;
if (context->orig_tracing_thresh == context->tracing_thresh) goto out_done;
retval = osnoise_write_ll_config("tracing_thresh", context->orig_tracing_thresh); if (retval < 0)
err_msg("Could not restore original tracing_thresh\n");
/* * Check first if the option is disabled.
*/
snprintf(no_option, sizeof(no_option), "NO_%s", option);
opt = strstr(options, no_option); if (opt) goto out_free;
/* * Now that it is not disabled, if the string is there, it is * enabled. If the string is not there, the option does not exist.
*/
opt = strstr(options, option); if (opt)
retval = 1; else
retval = OSNOISE_OPTION_INIT_VAL;
int osnoise_set_irq_disable(struct osnoise_context *context, bool onoff)
{ int opt_irq_disable = osnoise_get_irq_disable(context); int retval;
if (opt_irq_disable == OSNOISE_OPTION_INIT_VAL) return -1;
if (opt_irq_disable == onoff) return 0;
retval = osnoise_options_set_option("OSNOISE_IRQ_DISABLE", onoff); if (retval < 0) return -1;
context->opt_irq_disable = onoff;
return 0;
}
staticvoid osnoise_restore_irq_disable(struct osnoise_context *context)
{ int retval;
if (context->orig_opt_irq_disable == OSNOISE_OPTION_INIT_VAL) return;
if (context->orig_opt_irq_disable == context->opt_irq_disable) goto out_done;
retval = osnoise_options_set_option("OSNOISE_IRQ_DISABLE", context->orig_opt_irq_disable); if (retval < 0)
err_msg("Could not restore original OSNOISE_IRQ_DISABLE option\n");
int osnoise_set_workload(struct osnoise_context *context, bool onoff)
{ int opt_workload = osnoise_get_workload(context); int retval;
if (opt_workload == OSNOISE_OPTION_INIT_VAL) return -1;
if (opt_workload == onoff) return 0;
retval = osnoise_options_set_option("OSNOISE_WORKLOAD", onoff); if (retval < 0) return -2;
context->opt_workload = onoff;
return 0;
}
staticvoid osnoise_restore_workload(struct osnoise_context *context)
{ int retval;
if (context->orig_opt_workload == OSNOISE_OPTION_INIT_VAL) return;
if (context->orig_opt_workload == context->opt_workload) goto out_done;
retval = osnoise_options_set_option("OSNOISE_WORKLOAD", context->orig_opt_workload); if (retval < 0)
err_msg("Could not restore original OSNOISE_WORKLOAD option\n");
/* * osnoise_get_context - increase the usage of a context and return it
*/ int osnoise_get_context(struct osnoise_context *context)
{ int ret;
if (context->flags & FLAG_CONTEXT_DELETED) {
ret = -1;
} else {
context->ref++;
ret = 0;
}
return ret;
}
/* * osnoise_context_alloc - alloc an osnoise_context * * The osnoise context contains the information of the "osnoise/" configs. * It is used to set and restore the config.
*/ struct osnoise_context *osnoise_context_alloc(void)
{ struct osnoise_context *context;
context = calloc(1, sizeof(*context)); if (!context) return NULL;
/* * osnoise_put_context - put the osnoise_put_context * * If there is no other user for the context, the original data * is restored.
*/ void osnoise_put_context(struct osnoise_context *context)
{ if (--context->ref < 1)
context->flags |= FLAG_CONTEXT_DELETED;
if (!(context->flags & FLAG_CONTEXT_DELETED)) return;
/* * osnoise_destroy_tool - disable trace, restore configs and free data
*/ void osnoise_destroy_tool(struct osnoise_tool *top)
{ if (!top) return;
trace_instance_destroy(&top->trace);
if (top->context)
osnoise_put_context(top->context);
free(top);
}
/* * osnoise_init_tool - init an osnoise tool * * It allocs data, create a context to store data and * creates a new trace instance for the tool.
*/ struct osnoise_tool *osnoise_init_tool(char *tool_name)
{ struct osnoise_tool *top; int retval;
top = calloc(1, sizeof(*top)); if (!top) return NULL;
top->context = osnoise_context_alloc(); if (!top->context) goto out_err;
retval = trace_instance_init(&top->trace, tool_name); if (retval) goto out_err;
bool osnoise_trace_is_off(struct osnoise_tool *tool, struct osnoise_tool *record)
{ /* * The tool instance is always present, it is the one used to collect * data.
*/ if (!tracefs_trace_is_on(tool->trace.inst)) returntrue;
/* * The trace record instance is only enabled when -t is set. IOW, when the system * is tracing.
*/ return record && !tracefs_trace_is_on(record->trace.inst);
}
/* * osnoise_report_missed_events - report number of events dropped by trace * buffer
*/ void
osnoise_report_missed_events(struct osnoise_tool *tool)
{ unsignedlonglong total_events;
if (tool->trace.missed_events == UINT64_MAX)
printf("unknown number of events missed, results might not be accurate\n"); elseif (tool->trace.missed_events > 0) {
total_events = tool->trace.processed_events + tool->trace.missed_events;
printf("%lld (%.2f%%) events missed, results might not be accurate\n",
tool->trace.missed_events,
(double) tool->trace.missed_events / total_events * 100.0);
}
}
/* * osnoise_apply_config - apply common configs to the initialized tool
*/ int
osnoise_apply_config(struct osnoise_tool *tool, struct osnoise_params *params)
{ int retval;
if (!params->sleep_time)
params->sleep_time = 1;
retval = osnoise_set_cpus(tool->context, params->cpus ? params->cpus : "all"); if (retval) {
err_msg("Failed to apply CPUs config\n"); goto out_err;
}
if (retval) {
err_msg("Failed to set runtime and/or period\n"); goto out_err;
}
retval = osnoise_set_stop_us(tool->context, params->stop_us); if (retval) {
err_msg("Failed to set stop us\n"); goto out_err;
}
retval = osnoise_set_stop_total_us(tool->context, params->stop_total_us); if (retval) {
err_msg("Failed to set stop total us\n"); goto out_err;
}
retval = osnoise_set_tracing_thresh(tool->context, params->threshold); if (retval) {
err_msg("Failed to set tracing_thresh\n"); goto out_err;
}
if (params->hk_cpus) {
retval = sched_setaffinity(getpid(), sizeof(params->hk_cpu_set),
¶ms->hk_cpu_set); if (retval == -1) {
err_msg("Failed to set rtla to the house keeping CPUs\n"); goto out_err;
}
} elseif (params->cpus) { /* * Even if the user do not set a house-keeping CPU, try to * move rtla to a CPU set different to the one where the user * set the workload to run. * * No need to check results as this is an automatic attempt.
*/
auto_house_keeping(¶ms->monitored_cpus);
}
retval = osnoise_set_workload(tool->context, true); if (retval < -1) {
err_msg("Failed to set OSNOISE_WORKLOAD option\n"); goto out_err;
}
return 0;
out_err: return -1;
}
staticvoid osnoise_usage(int err)
{ int i;
staticconstchar *msg[] = { "", "osnoise version " VERSION, "", " usage: [rtla] osnoise [MODE] ...", "", " modes:", " top - prints the summary from osnoise tracer", " hist - prints a histogram of osnoise samples", "", "if no MODE is given, the top mode is called, passing the arguments",
NULL,
};
for (i = 0; msg[i]; i++)
fprintf(stderr, "%s\n", msg[i]); exit(err);
}
int osnoise_main(int argc, char *argv[])
{ if (argc == 0) goto usage;
/* * if osnoise was called without any argument, run the * default cmdline.
*/ if (argc == 1) {
osnoise_top_main(argc, argv); exit(0);
}
if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {
osnoise_usage(0);
} elseif (strncmp(argv[1], "-", 1) == 0) { /* the user skipped the tool, call the default one */
osnoise_top_main(argc, argv); exit(0);
} elseif (strcmp(argv[1], "top") == 0) {
osnoise_top_main(argc-1, &argv[1]); exit(0);
} elseif (strcmp(argv[1], "hist") == 0) {
osnoise_hist_main(argc-1, &argv[1]); exit(0);
}
usage:
osnoise_usage(1); exit(1);
}
int hwnoise_main(int argc, char *argv[])
{
osnoise_top_main(argc, argv); exit(0);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.4 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.