X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=libust%2Ftrace_event.c;h=854a7676b3586d10b84ece785eb97cb65f2aec3d;hb=HEAD;hp=26157e245e032b8c9618b63ba2e437ab926756e4;hpb=3b297856588b77dcd20ad7497ee46ab68c94c4d9;p=ust.git diff --git a/libust/trace_event.c b/libust/trace_event.c index 26157e2..854a767 100644 --- a/libust/trace_event.c +++ b/libust/trace_event.c @@ -3,8 +3,8 @@ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * License as published by the Free Software Foundation; + * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,31 +17,45 @@ * */ +#define _LGPL_SOURCE #include #include +#include #include #include -#include "usterr.h" - -#define _LGPL_SOURCE #include +#include "usterr_signal_safe.h" + /* libraries that contain trace_events (struct trace_event_lib) */ static CDS_LIST_HEAD(libs); - +/* + * Nested mutex is not required here, but provide the same guaranteed + * for start/stop iteration vs nested ops as markers and tracepoints. + */ +static __thread int nested_mutex; static DEFINE_MUTEX(trace_events_mutex); +static +int trace_event_get_iter_range(struct trace_event * const **trace_event, + struct trace_event * const *begin, + struct trace_event * const *end); + +static void lock_trace_events(void) { - pthread_mutex_lock(&trace_events_mutex); + if (!(nested_mutex++)) + pthread_mutex_lock(&trace_events_mutex); } +static void unlock_trace_events(void) { - pthread_mutex_unlock(&trace_events_mutex); + if (!(--nested_mutex)) + pthread_mutex_unlock(&trace_events_mutex); } - +static int lib_get_iter_trace_events(struct trace_event_iter *iter) { struct trace_event_lib *iter_lib; @@ -71,7 +85,9 @@ int lib_get_iter_trace_events(struct trace_event_iter *iter) * * Returns whether a next trace_event has been found (1) or not (0). * Will return the first trace_event in the range if the input trace_event is NULL. + * Called with trace event mutex held. */ +static int trace_event_get_iter_range(struct trace_event * const **trace_event, struct trace_event * const *begin, struct trace_event * const *end) @@ -99,9 +115,13 @@ static void trace_event_get_iter(struct trace_event_iter *iter) void trace_event_iter_start(struct trace_event_iter *iter) { + lock_trace_events(); trace_event_get_iter(iter); } +/* + * Called with trace event mutex held. + */ void trace_event_iter_next(struct trace_event_iter *iter) { iter->trace_event++; @@ -113,6 +133,11 @@ void trace_event_iter_next(struct trace_event_iter *iter) trace_event_get_iter(iter); } +void trace_event_iter_stop(struct trace_event_iter *iter) +{ + unlock_trace_events(); +} + void trace_event_iter_reset(struct trace_event_iter *iter) { iter->lib = NULL; @@ -129,8 +154,7 @@ int trace_event_register_lib(struct trace_event * const *trace_events_start, pl->trace_events_start = trace_events_start; pl->trace_events_count = trace_events_count; - /* FIXME: maybe protect this with its own mutex? */ - pthread_mutex_lock(&trace_events_mutex); + lock_trace_events(); /* * We sort the libs by struct lib pointer address. */ @@ -145,7 +169,7 @@ int trace_event_register_lib(struct trace_event * const *trace_events_start, /* We should be added at the head of the list */ cds_list_add(&pl->list, &libs); lib_added: - pthread_mutex_unlock(&trace_events_mutex); + unlock_trace_events(); /* trace_events_count - 1: skip dummy */ DBG("just registered a trace_events section from %p and having %d trace_events (minus dummy trace_event)", trace_events_start, trace_events_count); @@ -157,8 +181,7 @@ int trace_event_unregister_lib(struct trace_event * const *trace_events_start) { struct trace_event_lib *lib; - pthread_mutex_lock(&trace_events_mutex); - + unlock_trace_events(); cds_list_for_each_entry(lib, &libs, list) { if(lib->trace_events_start == trace_events_start) { struct trace_event_lib *lib2free = lib; @@ -167,8 +190,7 @@ int trace_event_unregister_lib(struct trace_event * const *trace_events_start) break; } } - - pthread_mutex_unlock(&trace_events_mutex); + unlock_trace_events(); return 0; }