if (current->trace_recursion & TRACE_BRANCH_BIT) return;
/* * I would love to save just the ftrace_likely_data pointer, but * this code can also be used by modules. Ugly things can happen * if the module is unloaded, and then we go and read the * pointer. This is slower, but much safer.
*/
if (unlikely(!tr)) return;
raw_local_irq_save(flags);
current->trace_recursion |= TRACE_BRANCH_BIT; if (!tracer_tracing_is_on_cpu(tr, raw_smp_processor_id())) goto out;
staticinline void trace_likely_condition(struct ftrace_likely_data *f, int val, int expect)
{ if (!branch_tracing_enabled) return;
probe_likely_condition(f, val, expect);
}
int enable_branch_tracing(struct trace_array *tr)
{
mutex_lock(&branch_tracing_mutex);
branch_tracer = tr; /* * Must be seen before enabling. The reader is a condition * where we do not need a matching rmb()
*/
smp_wmb();
branch_tracing_enabled++;
mutex_unlock(&branch_tracing_mutex);
__init staticint init_branch_tracer(void)
{ int ret;
ret = register_trace_event(&trace_branch_event); if (!ret) {
printk(KERN_WARNING "Warning: could not register " "branch events\n"); return 1;
} return register_tracer(&branch_trace);
}
core_initcall(init_branch_tracer);
#else staticinline void trace_likely_condition(struct ftrace_likely_data *f, int val, int expect)
{
} #endif/* CONFIG_BRANCH_TRACER */
void ftrace_likely_update(struct ftrace_likely_data *f, int val, int expect, int is_constant)
{ unsignedlong flags = user_access_save();
/* A constant is always correct */ if (is_constant) {
f->constant++;
val = expect;
} /* * I would love to have a trace point here instead, but the * trace point code is so inundated with unlikely and likely * conditions that the recursive nightmare that exists is too * much to try to get working. At least for now.
*/
trace_likely_condition(f, val, expect);
/* FIXME: Make this atomic! */ if (val == expect)
f->data.correct++; else
f->data.incorrect++;
if (percent_a < percent_b) return -1; if (percent_a > percent_b) return 1;
if (a->incorrect < b->incorrect) return -1; if (a->incorrect > b->incorrect) return 1;
/* * Since the above shows worse (incorrect) cases * first, we continue that by showing best (correct) * cases last.
*/ if (a->correct > b->correct) return -1; if (a->correct < b->correct) return 1;
__init staticint all_annotated_branch_stats(void)
{ int ret;
ret = register_stat_tracer(&all_branch_stats); if (!ret) {
printk(KERN_WARNING "Warning: could not register " "all branches stats\n"); return 1;
} return 0;
}
fs_initcall(all_annotated_branch_stats); #endif/* CONFIG_PROFILE_ALL_BRANCHES */
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.