Move include/ust/ to include/lttng/
[lttng-ust.git] / libust / tracepoint.c
index 3bc5795afc17ce2f811e69015ac338b62ecd5519..8bf875281a97769ed26f2d96974343427f7aa314 100644 (file)
 
 #define _LGPL_SOURCE
 #include <errno.h>
-#include <ust/tracepoint.h>
-#include <ust/tracepoint-internal.h>
-#include <ust/core.h>
-#include <ust/kcompat/kcompat.h>
+#include <lttng/tracepoint.h>
+#include <lttng/tracepoint-internal.h>
+#include <lttng/core.h>
+#include <lttng/kcompat/kcompat.h>
 #include <urcu-bp.h>
 #include <urcu/hlist.h>
+#include <urcu/uatomic.h>
 
-#include "usterr_signal_safe.h"
-
-extern struct tracepoint * const __start___tracepoints_ptrs[]
-       __attribute__((visibility("hidden")));
-extern struct tracepoint * const __stop___tracepoints_ptrs[]
-       __attribute__((visibility("hidden")));
-
-static struct tracepoint * __tracepoint_ptr_dummy
-       __attribute__((used, section("__tracepoints_ptrs")));
+#include <lttng/usterr-signal-safe.h>
+#include "ltt-tracer-core.h"
 
 /* Set to 1 to enable tracepoint debug output */
 static const int tracepoint_debug;
@@ -47,29 +41,12 @@ static void (*new_tracepoint_cb)(struct tracepoint *);
 static CDS_LIST_HEAD(libs);
 
 /*
- * Allow nested mutex for mutex listing and nested enable.
- */
-static __thread int nested_mutex;
-
-/*
- * Tracepoints mutex protects the library tracepoints, the hash table,
- * and the library list.
+ * The UST lock protects the library tracepoints, the hash table, and
+ * the library list.
+ * All calls to the tracepoint API must be protected by the UST lock,
+ * excepts calls to tracepoint_register_lib and
+ * tracepoint_unregister_lib, which take the UST lock themselves.
  */
-static pthread_mutex_t tracepoints_mutex;
-
-static
-void lock_tracepoints(void)
-{
-       if (!(nested_mutex++))
-               pthread_mutex_lock(&tracepoints_mutex);
-}
-
-static
-void unlock_tracepoints(void)
-{
-       if (!(--nested_mutex))
-               pthread_mutex_unlock(&tracepoints_mutex);
-}
 
 /*
  * Tracepoint hash table, containing the active tracepoints.
@@ -264,7 +241,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
 
 /*
  * Remove the tracepoint from the tracepoint hash table. Must be called with
- * mutex_lock held.
+ * ust_lock held.
  */
 static inline void remove_tracepoint(struct tracepoint_entry *e)
 {
@@ -338,12 +315,10 @@ static void lib_update_tracepoints(void)
 {
        struct tracepoint_lib *lib;
 
-       lock_tracepoints();
        cds_list_for_each_entry(lib, &libs, list) {
                tracepoint_update_probe_range(lib->tracepoints_start,
                                lib->tracepoints_start + lib->tracepoints_count);
        }
-       unlock_tracepoints();
 }
 
 /*
@@ -380,14 +355,13 @@ tracepoint_add_probe(const char *name, void *probe, void *data)
  *
  * Returns 0 if ok, error value on error.
  * The probe address must at least be aligned on the architecture pointer size.
+ * Called with the UST lock held.
  */
 int __tracepoint_probe_register(const char *name, void *probe, void *data)
 {
        void *old;
 
-       lock_tracepoints();
        old = tracepoint_add_probe(name, probe, data);
-       unlock_tracepoints();
        if (IS_ERR(old))
                return PTR_ERR(old);
 
@@ -418,18 +392,13 @@ static void *tracepoint_remove_probe(const char *name, void *probe, void *data)
  * @probe: probe function pointer
  * @probe: probe data pointer
  *
- * We do not need to call a synchronize_sched to make sure the probes have
- * finished running before doing a module unload, because the module unload
- * itself uses stop_machine(), which insures that every preempt disabled section
- * have finished.
+ * Called with the UST lock held.
  */
 int __tracepoint_probe_unregister(const char *name, void *probe, void *data)
 {
        void *old;
 
-       lock_tracepoints();
        old = tracepoint_remove_probe(name, probe, data);
-       unlock_tracepoints();
        if (IS_ERR(old))
                return PTR_ERR(old);
 
@@ -454,20 +423,18 @@ static void tracepoint_add_old_probes(void *old)
  * @probe: probe handler
  *
  * caller must call tracepoint_probe_update_all()
+ * Called with the UST lock held.
  */
 int tracepoint_probe_register_noupdate(const char *name, void *probe,
                                       void *data)
 {
        void *old;
 
-       lock_tracepoints();
        old = tracepoint_add_probe(name, probe, data);
        if (IS_ERR(old)) {
-               unlock_tracepoints();
                return PTR_ERR(old);
        }
        tracepoint_add_old_probes(old);
-       unlock_tracepoints();
        return 0;
 }
 
@@ -477,40 +444,36 @@ int tracepoint_probe_register_noupdate(const char *name, void *probe,
  * @probe: probe function pointer
  *
  * caller must call tracepoint_probe_update_all()
+ * Called with the UST lock held.
  */
 int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
                                         void *data)
 {
        void *old;
 
-       lock_tracepoints();
        old = tracepoint_remove_probe(name, probe, data);
        if (IS_ERR(old)) {
-               unlock_tracepoints();
                return PTR_ERR(old);
        }
        tracepoint_add_old_probes(old);
-       unlock_tracepoints();
        return 0;
 }
 
 /**
  * tracepoint_probe_update_all -  update tracepoints
+ * Called with the UST lock held.
  */
 void tracepoint_probe_update_all(void)
 {
        CDS_LIST_HEAD(release_probes);
        struct tp_probes *pos, *next;
 
-       lock_tracepoints();
        if (!need_update) {
-               unlock_tracepoints();
                return;
        }
        if (!cds_list_empty(&old_probes))
                cds_list_replace_init(&old_probes, &release_probes);
        need_update = 0;
-       unlock_tracepoints();
 
        tracepoint_update_probes();
        cds_list_for_each_entry_safe(pos, next, &release_probes, u.list) {
@@ -585,14 +548,16 @@ static void tracepoint_get_iter(struct tracepoint_iter *iter)
                tracepoint_iter_reset(iter);
 }
 
+/*
+ * Called with UST lock held.
+ */
 void tracepoint_iter_start(struct tracepoint_iter *iter)
 {
-       lock_tracepoints();
        tracepoint_get_iter(iter);
 }
 
 /*
- * Called with tracepoint mutex held.
+ * Called with UST lock held.
  */
 void tracepoint_iter_next(struct tracepoint_iter *iter)
 {
@@ -605,9 +570,11 @@ void tracepoint_iter_next(struct tracepoint_iter *iter)
        tracepoint_get_iter(iter);
 }
 
+/*
+ * Called with UST lock held.
+ */
 void tracepoint_iter_stop(struct tracepoint_iter *iter)
 {
-       unlock_tracepoints();
 }
 
 void tracepoint_iter_reset(struct tracepoint_iter *iter)
@@ -637,12 +604,14 @@ int tracepoint_register_lib(struct tracepoint * const *tracepoints_start,
 {
        struct tracepoint_lib *pl, *iter;
 
+       init_tracepoint();
+
        pl = (struct tracepoint_lib *) zmalloc(sizeof(struct tracepoint_lib));
 
        pl->tracepoints_start = tracepoints_start;
        pl->tracepoints_count = tracepoints_count;
 
-       lock_tracepoints();
+       ust_lock();
        /*
         * We sort the libs by struct lib pointer address.
         */
@@ -657,15 +626,14 @@ int tracepoint_register_lib(struct tracepoint * const *tracepoints_start,
        /* We should be added at the head of the list */
        cds_list_add(&pl->list, &libs);
 lib_added:
-       unlock_tracepoints();
-
        new_tracepoints(tracepoints_start, tracepoints_start + tracepoints_count);
 
        /* TODO: update just the loaded lib */
        lib_update_tracepoints();
+       ust_unlock();
 
-       /* tracepoints_count - 1: skip dummy */
-       DBG("just registered a tracepoints section from %p and having %d tracepoints (minus dummy tracepoints)", tracepoints_start, tracepoints_count);
+       DBG("just registered a tracepoints section from %p and having %d tracepoints",
+               tracepoints_start, tracepoints_count);
 
        return 0;
 }
@@ -674,7 +642,7 @@ int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start)
 {
        struct tracepoint_lib *lib;
 
-       lock_tracepoints();
+       ust_lock();
        cds_list_for_each_entry(lib, &libs, list) {
                if (lib->tracepoints_start == tracepoints_start) {
                        struct tracepoint_lib *lib2free = lib;
@@ -683,22 +651,19 @@ int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start)
                        break;
                }
        }
-       unlock_tracepoints();
+       ust_unlock();
 
        return 0;
 }
 
-void __attribute__((constructor)) init_tracepoint(void)
+void init_tracepoint(void)
 {
-       if (!initialized) {
-               tracepoint_register_lib(__start___tracepoints_ptrs,
-                       __stop___tracepoints_ptrs
-                       - __start___tracepoints_ptrs);
-               initialized = 1;
-       }
+       if (uatomic_xchg(&initialized, 1) == 1)
+               return;
+       init_usterr();
 }
 
-void __attribute__((destructor)) destroy_tracepoint(void)
+void exit_tracepoint(void)
 {
-       tracepoint_unregister_lib(__start___tracepoints_ptrs);
+       initialized = 0;
 }
This page took 0.029341 seconds and 4 git commands to generate.