Because tracepoint state is updated by lttng-ust threads, and read by
application threads, we need to perform a volatile load of that state.
Not having the volatile load can cause the compiler to optimize away the
reload of that state, keeping a local copy instead. For instance, a main
program consisting of a loop could keep the tracepoint state on its
stack or in registers without ever reloading it from memory.
Perform a volatile load (CMM_LOAD_SHARED()) of the tracepoint state.
Add the matching volatile store (CMM_STORE_SHARED()) in tracepoint.c for
the state update.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
#include <lttng/tracepoint-types.h>
#include <lttng/tracepoint-rcu.h>
#include <urcu/compiler.h>
+#include <urcu/system.h>
#include <dlfcn.h> /* for dlopen */
#include <string.h> /* for memset */
#include <lttng/ust-config.h> /* for sdt */
#endif
#define tracepoint_enabled(provider, name) \
- caa_unlikely(__tracepoint_##provider##___##name.state)
+ caa_unlikely(CMM_LOAD_SHARED(__tracepoint_##provider##___##name.state))
#define do_tracepoint(provider, name, ...) \
__tracepoint_cb_##provider##___##name(__VA_ARGS__)
#include <urcu/hlist.h>
#include <urcu/uatomic.h>
#include <urcu/compiler.h>
+#include <urcu/system.h>
#include <lttng/tracepoint.h>
#include <lttng/ust-abi.h> /* for LTTNG_UST_SYM_NAME_LEN */
* is used.
*/
rcu_assign_pointer(elem->probes, (*entry)->probes);
- elem->state = active;
+ CMM_STORE_SHARED(elem->state, active);
}
/*
*/
static void disable_tracepoint(struct lttng_ust_tracepoint *elem)
{
- elem->state = 0;
+ CMM_STORE_SHARED(elem->state, 0);
rcu_assign_pointer(elem->probes, NULL);
}