From: Mathieu Desnoyers Date: Fri, 20 May 2011 17:11:42 +0000 (-0400) Subject: Tracepoints and markers: cleanup init, add missing mutex lock/unlock X-Git-Tag: v0.14~14 X-Git-Url: http://git.liburcu.org/?p=ust.git;a=commitdiff_plain;h=b27f8e75a6e762ed01b889560431476516786d9f Tracepoints and markers: cleanup init, add missing mutex lock/unlock Signed-off-by: Mathieu Desnoyers --- diff --git a/include/ust/marker-internal.h b/include/ust/marker-internal.h index 6a71ebe..6a11e56 100644 --- a/include/ust/marker-internal.h +++ b/include/ust/marker-internal.h @@ -68,9 +68,6 @@ #define ust_marker_tp(name, tp_name, tp_cb, format, args...) \ __ust_marker_tp(ust, name, NULL, tp_name, tp_cb, format, ## args) -extern void lock_ust_marker(void); -extern void unlock_ust_marker(void); - extern void ust_marker_compact_event_ids(void); /* @@ -118,4 +115,7 @@ extern int is_ust_marker_enabled(const char *channel, const char *name); extern void ust_marker_set_new_ust_marker_cb(void (*cb)(struct ust_marker *)); extern void init_ust_marker(void); +void lock_ust_marker(void); +void unlock_ust_marker(void); + #endif /* _UST_MARKER_INTERNAL_H */ diff --git a/include/ust/tracepoint-internal.h b/include/ust/tracepoint-internal.h index 31b9b86..6b159b4 100644 --- a/include/ust/tracepoint-internal.h +++ b/include/ust/tracepoint-internal.h @@ -34,9 +34,6 @@ #include #include -extern void tracepoint_update_probe_range(struct tracepoint * const *begin, - struct tracepoint * const *end); - extern int tracepoint_probe_register_noupdate(const char *name, void *probe, void *data); extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe, @@ -84,4 +81,6 @@ extern int trace_event_get_iter_range(struct trace_event * const **trace_event, extern void trace_event_update_process(void); extern int is_trace_event_enabled(const char *channel, const char *name); +extern void init_tracepoint(void); + #endif /* _UST_TRACEPOINT_INTERNAL_H */ diff --git a/libust/marker-control.c b/libust/marker-control.c index e83ee1a..4b3096c 100644 --- a/libust/marker-control.c +++ b/libust/marker-control.c @@ -403,14 +403,10 @@ static char initialized = 0; void __attribute__((constructor)) init_ust_marker_control(void) { - if(!initialized) { + if (!initialized) { int ret; -//ust// pentry = create_proc_entry("ltt", S_IRUSR|S_IWUSR, NULL); -//ust// if (!pentry) -//ust// return -EBUSY; -//ust// ust_markers_loaded_cachep = KMEM_CACHE(ltt_active_ust_marker, 0); - + init_ust_marker(); ret = ltt_probe_register(&default_probe); BUG_ON(ret); ret = ltt_ust_marker_connect("metadata", "core_marker_format", @@ -418,18 +414,14 @@ void __attribute__((constructor)) init_ust_marker_control(void) BUG_ON(ret); ret = ltt_ust_marker_connect("metadata", "core_marker_id", DEFAULT_PROBE); BUG_ON(ret); -//ust// pentry->proc_fops = <t_fops; - initialized = 1; } } -//ust// module_init(ust_marker_control_init); static void __attribute__((destructor)) ust_marker_control_exit(void) { int ret; -//ust// remove_proc_entry("ltt", NULL); ret = ltt_ust_marker_disconnect("metadata", "core_marker_format", DEFAULT_PROBE); BUG_ON(ret); @@ -439,11 +431,5 @@ static void __attribute__((destructor)) ust_marker_control_exit(void) ret = ltt_probe_unregister(&default_probe); BUG_ON(ret); disconnect_all_ust_markers(); -//ust// kmem_cache_destroy(ust_markers_loaded_cachep); -//ust// ust_marker_synchronize_unregister(); + ust_marker_synchronize_unregister(); } -//ust// module_exit(ust_marker_control_exit); - -//ust// MODULE_LICENSE("GPL"); -//ust// MODULE_AUTHOR("Mathieu Desnoyers"); -//ust// MODULE_DESCRIPTION("Linux Trace Toolkit Marker Control"); diff --git a/libust/marker.c b/libust/marker.c index 3c3a5b7..f9acab6 100644 --- a/libust/marker.c +++ b/libust/marker.c @@ -19,6 +19,7 @@ #define _LGPL_SOURCE #include #include +#include #include #include #include @@ -39,6 +40,8 @@ extern struct ust_marker * const __stop___ust_marker_ptrs[] __attribute__((visib /* Set to 1 to enable ust_marker debug output */ static const int ust_marker_debug; +static int initialized; +static void (*new_ust_marker_cb)(struct ust_marker *); /* * ust_marker mutex protects the builtin and module ust_marker and the @@ -47,14 +50,21 @@ static const int ust_marker_debug; static DEFINE_MUTEX(ust_marker_mutex); static CDS_LIST_HEAD(ust_marker_libs); +/* + * Allow nested mutex for mutex listing and nested enable. + */ +static __thread int nested_mutex; + void lock_ust_marker(void) { - pthread_mutex_lock(&ust_marker_mutex); + if (!(nested_mutex++)) + pthread_mutex_lock(&ust_marker_mutex); } void unlock_ust_marker(void) { - pthread_mutex_unlock(&ust_marker_mutex); + if (!(--nested_mutex)) + pthread_mutex_unlock(&ust_marker_mutex); } /* @@ -638,9 +648,9 @@ int is_ust_marker_enabled(const char *channel, const char *name) { struct ust_marker_entry *entry; - pthread_mutex_lock(&ust_marker_mutex); + lock_ust_marker(); entry = get_ust_marker(channel, name); - pthread_mutex_unlock(&ust_marker_mutex); + unlock_ust_marker(); return entry && !!entry->refcount; } @@ -678,11 +688,11 @@ static void lib_update_ust_marker(void) { struct ust_marker_lib *lib; - pthread_mutex_lock(&ust_marker_mutex); + lock_ust_marker(); cds_list_for_each_entry(lib, &ust_marker_libs, list) ust_marker_update_probe_range(lib->ust_marker_start, lib->ust_marker_start + lib->ust_marker_count); - pthread_mutex_unlock(&ust_marker_mutex); + unlock_ust_marker(); } /* @@ -729,7 +739,7 @@ int ust_marker_probe_register(const char *channel, const char *name, struct ust_marker_probe_array *old; int first_probe = 0; - pthread_mutex_lock(&ust_marker_mutex); + lock_ust_marker(); entry = get_ust_marker(channel, name); if (!entry) { first_probe = 1; @@ -774,7 +784,7 @@ int ust_marker_probe_register(const char *channel, const char *name, else goto end; } - pthread_mutex_unlock(&ust_marker_mutex); + unlock_ust_marker(); /* Activate ust_marker if necessary */ ust_marker_update_probes(); @@ -792,7 +802,7 @@ error_remove_ust_marker: ret_err = remove_ust_marker(channel, name); WARN_ON(ret_err); end: - pthread_mutex_unlock(&ust_marker_mutex); + unlock_ust_marker(); return ret; } @@ -816,14 +826,14 @@ int ust_marker_probe_unregister(const char *channel, const char *name, struct ust_marker_probe_array *old; int ret = 0; - pthread_mutex_lock(&ust_marker_mutex); + lock_ust_marker(); entry = get_ust_marker(channel, name); if (!entry) { ret = -ENOENT; goto end; } old = ust_marker_entry_remove_probe(entry, probe, probe_private); - pthread_mutex_unlock(&ust_marker_mutex); + unlock_ust_marker(); ust_marker_update_probes(); @@ -834,7 +844,7 @@ int ust_marker_probe_unregister(const char *channel, const char *name, return ret; end: - pthread_mutex_unlock(&ust_marker_mutex); + unlock_ust_marker(); return ret; } @@ -891,7 +901,7 @@ int ust_marker_probe_unregister_private_data(ust_marker_probe_func *probe, struct ust_marker_probe_array *old; char *channel = NULL, *name = NULL; - pthread_mutex_lock(&ust_marker_mutex); + lock_ust_marker(); entry = get_ust_marker_from_private_data(probe, probe_private); if (!entry) { ret = -ENOENT; @@ -902,7 +912,7 @@ int ust_marker_probe_unregister_private_data(ust_marker_probe_func *probe, name = strdup(entry->name); /* Ignore busy error message */ remove_ust_marker(channel, name); - pthread_mutex_unlock(&ust_marker_mutex); + unlock_ust_marker(); ust_marker_update_probes(); @@ -913,7 +923,7 @@ int ust_marker_probe_unregister_private_data(ust_marker_probe_func *probe, goto end; unlock: - pthread_mutex_unlock(&ust_marker_mutex); + unlock_ust_marker(); end: free(channel); free(name); @@ -1032,9 +1042,9 @@ static void ust_marker_get_iter(struct ust_marker_iter *iter) ust_marker_iter_reset(iter); } -/* Called with markers mutex held. */ void ust_marker_iter_start(struct ust_marker_iter *iter) { + lock_ust_marker(); ust_marker_get_iter(iter); } @@ -1050,12 +1060,11 @@ void ust_marker_iter_next(struct ust_marker_iter *iter) ust_marker_get_iter(iter); } -/* Called with markers mutex held. */ void ust_marker_iter_stop(struct ust_marker_iter *iter) { + unlock_ust_marker(); } -/* Called with markers mutex held. */ void ust_marker_iter_reset(struct ust_marker_iter *iter) { iter->lib = NULL; @@ -1070,7 +1079,7 @@ void ltt_dump_ust_marker_state(struct ust_trace *trace) struct cds_hlist_node *node; unsigned int i; - pthread_mutex_lock(&ust_marker_mutex); + lock_ust_marker(); call_data.trace = trace; call_data.serializer = NULL; @@ -1098,11 +1107,9 @@ void ltt_dump_ust_marker_state(struct ust_trace *trace) entry->format); } } - pthread_mutex_unlock(&ust_marker_mutex); + unlock_ust_marker(); } -static void (*new_ust_marker_cb)(struct ust_marker *) = NULL; - void ust_marker_set_new_ust_marker_cb(void (*cb)(struct ust_marker *)) { new_ust_marker_cb = cb; @@ -1114,7 +1121,7 @@ static void new_ust_marker(struct ust_marker * const *start, if (new_ust_marker_cb) { struct ust_marker * const *m; - for(m = start; m < end; m++) { + for (m = start; m < end; m++) { if (*m) new_ust_marker_cb(*m); } @@ -1177,11 +1184,10 @@ int ust_marker_unregister_lib(struct ust_marker * const *ust_marker_start) return 0; } -static int initialized = 0; - void __attribute__((constructor)) init_ust_marker(void) { if (!initialized) { + init_tracepoint(); ust_marker_register_lib(__start___ust_marker_ptrs, __stop___ust_marker_ptrs - __start___ust_marker_ptrs); diff --git a/libust/tracectl.c b/libust/tracectl.c index bd640c3..ef7184f 100644 --- a/libust/tracectl.c +++ b/libust/tracectl.c @@ -104,7 +104,6 @@ static void print_ust_marker(FILE *fp) { struct ust_marker_iter iter; - lock_ust_marker(); ust_marker_iter_reset(&iter); ust_marker_iter_start(&iter); @@ -120,7 +119,7 @@ static void print_ust_marker(FILE *fp) */ ust_marker_iter_next(&iter); } - unlock_ust_marker(); + ust_marker_iter_stop(&iter); } static void print_trace_events(FILE *fp) @@ -1315,18 +1314,17 @@ static void __attribute__((constructor)) init() DBG("UST traces will not be synchronized with LTTng traces"); } + if (getenv("UST_TRACE") || getenv("UST_AUTOPROBE")) { + /* Ensure ust_marker control is initialized */ + init_ust_marker_control(); + } + autoprobe_val = getenv("UST_AUTOPROBE"); if (autoprobe_val) { struct ust_marker_iter iter; DBG("Autoprobe enabled."); - /* Ensure ust_marker are initialized */ - //init_ust_marker(); - - /* Ensure ust_marker control is initialized, for the probe */ - init_ust_marker_control(); - /* first, set the callback that will connect the * probe on new ust_marker */ @@ -1358,6 +1356,7 @@ static void __attribute__((constructor)) init() auto_probe_connect(*iter.ust_marker); ust_marker_iter_next(&iter); } + ust_marker_iter_stop(&iter); } if (getenv("UST_OVERWRITE")) { @@ -1401,12 +1400,6 @@ static void __attribute__((constructor)) init() DBG("starting early tracing"); - /* Ensure ust_marker control is initialized */ - init_ust_marker_control(); - - /* Ensure ust_marker are initialized */ - init_ust_marker(); - /* Ensure buffers are initialized, for the transport to be available. * We are about to set a trace type and it will fail without this. */ diff --git a/libust/tracepoint.c b/libust/tracepoint.c index 6a8795b..3bc5795 100644 --- a/libust/tracepoint.c +++ b/libust/tracepoint.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Mathieu Desnoyers + * Copyright (C) 2008-2011 Mathieu Desnoyers * Copyright (C) 2009 Pierre-Marc Fournier * * This library is free software; you can redistribute it and/or @@ -30,20 +30,46 @@ #include "usterr_signal_safe.h" -//extern struct tracepoint __start___tracepoints[] __attribute__((visibility("hidden"))); -//extern struct tracepoint __stop___tracepoints[] __attribute__((visibility("hidden"))); +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"))); /* Set to 1 to enable tracepoint debug output */ static const int tracepoint_debug; +static int initialized; +static void (*new_tracepoint_cb)(struct tracepoint *); /* libraries that contain tracepoints (struct tracepoint_lib) */ static CDS_LIST_HEAD(libs); /* - * tracepoints_mutex nests inside module_mutex. Tracepoints mutex protects the - * builtin and module tracepoints and the hash table. + * Allow nested mutex for mutex listing and nested enable. */ -static DEFINE_MUTEX(tracepoints_mutex); +static __thread int nested_mutex; + +/* + * Tracepoints mutex protects the library tracepoints, the hash table, + * and the library list. + */ +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. @@ -53,6 +79,9 @@ static DEFINE_MUTEX(tracepoints_mutex); #define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS) static struct cds_hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE]; +static CDS_LIST_HEAD(old_probes); +static int need_update; + /* * Note about RCU : * It is used to to delay the free of multiple probes array until a quiescent @@ -68,7 +97,6 @@ struct tracepoint_entry { struct tp_probes { union { -//ust// struct rcu_head rcu; struct cds_list_head list; } u; struct tracepoint_probe probes[0]; @@ -81,17 +109,11 @@ static inline void *allocate_probes(int count) return p == NULL ? NULL : p->probes; } -//ust// static void rcu_free_old_probes(struct rcu_head *head) -//ust// { -//ust// kfree(container_of(head, struct tp_probes, u.rcu)); -//ust// } - static inline void release_probes(void *old) { if (old) { struct tp_probes *tp_probes = _ust_container_of(old, struct tp_probes, probes[0]); -//ust// call_rcu_sched(&tp_probes->u.rcu, rcu_free_old_probes); synchronize_rcu(); free(tp_probes); } @@ -288,13 +310,13 @@ static void disable_tracepoint(struct tracepoint *elem) * * Updates the probe callback corresponding to a range of tracepoints. */ +static void tracepoint_update_probe_range(struct tracepoint * const *begin, struct tracepoint * const *end) { struct tracepoint * const *iter; struct tracepoint_entry *mark_entry; - pthread_mutex_lock(&tracepoints_mutex); for (iter = begin; iter < end; iter++) { if (!*iter) continue; /* skip dummy */ @@ -310,18 +332,18 @@ void tracepoint_update_probe_range(struct tracepoint * const *begin, disable_tracepoint(*iter); } } - pthread_mutex_unlock(&tracepoints_mutex); } static void lib_update_tracepoints(void) { struct tracepoint_lib *lib; -//ust// pthread_mutex_lock(&module_mutex); - cds_list_for_each_entry(lib, &libs, list) + lock_tracepoints(); + cds_list_for_each_entry(lib, &libs, list) { tracepoint_update_probe_range(lib->tracepoints_start, lib->tracepoints_start + lib->tracepoints_count); -//ust// pthread_mutex_unlock(&module_mutex); + } + unlock_tracepoints(); } /* @@ -329,10 +351,7 @@ static void lib_update_tracepoints(void) */ static void tracepoint_update_probes(void) { - /* Core kernel tracepoints */ -//ust// tracepoint_update_probe_range(__start___tracepoints, -//ust// __stop___tracepoints); - /* tracepoints in modules. */ + /* tracepoints registered from libraries and executable. */ lib_update_tracepoints(); } @@ -366,9 +385,9 @@ int __tracepoint_probe_register(const char *name, void *probe, void *data) { void *old; - pthread_mutex_lock(&tracepoints_mutex); + lock_tracepoints(); old = tracepoint_add_probe(name, probe, data); - pthread_mutex_unlock(&tracepoints_mutex); + unlock_tracepoints(); if (IS_ERR(old)) return PTR_ERR(old); @@ -408,9 +427,9 @@ int __tracepoint_probe_unregister(const char *name, void *probe, void *data) { void *old; - pthread_mutex_lock(&tracepoints_mutex); + lock_tracepoints(); old = tracepoint_remove_probe(name, probe, data); - pthread_mutex_unlock(&tracepoints_mutex); + unlock_tracepoints(); if (IS_ERR(old)) return PTR_ERR(old); @@ -419,9 +438,6 @@ int __tracepoint_probe_unregister(const char *name, void *probe, void *data) return 0; } -static CDS_LIST_HEAD(old_probes); -static int need_update; - static void tracepoint_add_old_probes(void *old) { need_update = 1; @@ -444,17 +460,16 @@ int tracepoint_probe_register_noupdate(const char *name, void *probe, { void *old; - pthread_mutex_lock(&tracepoints_mutex); + lock_tracepoints(); old = tracepoint_add_probe(name, probe, data); if (IS_ERR(old)) { - pthread_mutex_unlock(&tracepoints_mutex); + unlock_tracepoints(); return PTR_ERR(old); } tracepoint_add_old_probes(old); - pthread_mutex_unlock(&tracepoints_mutex); + unlock_tracepoints(); return 0; } -//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_register_noupdate); /** * tracepoint_probe_unregister_noupdate - remove a probe but not disconnect @@ -468,17 +483,16 @@ int tracepoint_probe_unregister_noupdate(const char *name, void *probe, { void *old; - pthread_mutex_lock(&tracepoints_mutex); + lock_tracepoints(); old = tracepoint_remove_probe(name, probe, data); if (IS_ERR(old)) { - pthread_mutex_unlock(&tracepoints_mutex); + unlock_tracepoints(); return PTR_ERR(old); } tracepoint_add_old_probes(old); - pthread_mutex_unlock(&tracepoints_mutex); + unlock_tracepoints(); return 0; } -//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_unregister_noupdate); /** * tracepoint_probe_update_all - update tracepoints @@ -488,36 +502,35 @@ void tracepoint_probe_update_all(void) CDS_LIST_HEAD(release_probes); struct tp_probes *pos, *next; - pthread_mutex_lock(&tracepoints_mutex); + lock_tracepoints(); if (!need_update) { - pthread_mutex_unlock(&tracepoints_mutex); + unlock_tracepoints(); return; } if (!cds_list_empty(&old_probes)) cds_list_replace_init(&old_probes, &release_probes); need_update = 0; - pthread_mutex_unlock(&tracepoints_mutex); + unlock_tracepoints(); tracepoint_update_probes(); cds_list_for_each_entry_safe(pos, next, &release_probes, u.list) { cds_list_del(&pos->u.list); -//ust// call_rcu_sched(&pos->u.rcu, rcu_free_old_probes); synchronize_rcu(); free(pos); } } -//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_update_all); /* * Returns 0 if current not found. * Returns 1 if current found. + * + * Called with tracepoint mutex held */ int lib_get_iter_tracepoints(struct tracepoint_iter *iter) { struct tracepoint_lib *iter_lib; int found = 0; -//ust// pthread_mutex_lock(&module_mutex); cds_list_for_each_entry(iter_lib, &libs, list) { if (iter_lib < iter->lib) continue; @@ -531,7 +544,6 @@ int lib_get_iter_tracepoints(struct tracepoint_iter *iter) break; } } -//ust// pthread_mutex_unlock(&module_mutex); return found; } @@ -544,6 +556,7 @@ int lib_get_iter_tracepoints(struct tracepoint_iter *iter) * Returns whether a next tracepoint has been found (1) or not (0). * Will return the first tracepoint in the range if the input tracepoint is * NULL. + * Called with tracepoint mutex held. */ int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, struct tracepoint * const *begin, struct tracepoint * const *end) @@ -558,32 +571,29 @@ int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, } return 0; } -//ust// EXPORT_SYMBOL_GPL(tracepoint_get_iter_range); +/* + * Called with tracepoint mutex held. + */ static void tracepoint_get_iter(struct tracepoint_iter *iter) { int found = 0; -//ust// /* Core kernel tracepoints */ -//ust// if (!iter->module) { -//ust// found = tracepoint_get_iter_range(&iter->tracepoint, -//ust// __start___tracepoints, __stop___tracepoints); -//ust// if (found) -//ust// goto end; -//ust// } /* tracepoints in libs. */ found = lib_get_iter_tracepoints(iter); -//ust// end: if (!found) tracepoint_iter_reset(iter); } void tracepoint_iter_start(struct tracepoint_iter *iter) { + lock_tracepoints(); tracepoint_get_iter(iter); } -//ust// EXPORT_SYMBOL_GPL(tracepoint_iter_start); +/* + * Called with tracepoint mutex held. + */ void tracepoint_iter_next(struct tracepoint_iter *iter) { iter->tracepoint++; @@ -594,54 +604,16 @@ void tracepoint_iter_next(struct tracepoint_iter *iter) */ tracepoint_get_iter(iter); } -//ust// EXPORT_SYMBOL_GPL(tracepoint_iter_next); void tracepoint_iter_stop(struct tracepoint_iter *iter) { + unlock_tracepoints(); } -//ust// EXPORT_SYMBOL_GPL(tracepoint_iter_stop); void tracepoint_iter_reset(struct tracepoint_iter *iter) { -//ust// iter->module = NULL; iter->tracepoint = NULL; } -//ust// EXPORT_SYMBOL_GPL(tracepoint_iter_reset); - -//ust// #ifdef CONFIG_MODULES - -//ust// int tracepoint_module_notify(struct notifier_block *self, -//ust// unsigned long val, void *data) -//ust// { -//ust// struct module *mod = data; -//ust// -//ust// switch (val) { -//ust// case MODULE_STATE_COMING: -//ust// tracepoint_update_probe_range(mod->tracepoints, -//ust// mod->tracepoints + mod->num_tracepoints); -//ust// break; -//ust// case MODULE_STATE_GOING: -//ust// tracepoint_update_probe_range(mod->tracepoints, -//ust// mod->tracepoints + mod->num_tracepoints); -//ust// break; -//ust// } -//ust// return 0; -//ust// } - -//ust// struct notifier_block tracepoint_module_nb = { -//ust// .notifier_call = tracepoint_module_notify, -//ust// .priority = 0, -//ust// }; - -//ust// static int init_tracepoints(void) -//ust// { -//ust// return register_module_notifier(&tracepoint_module_nb); -//ust// } -//ust// __initcall(init_tracepoints); - -//ust// #endif /* CONFIG_MODULES */ - -static void (*new_tracepoint_cb)(struct tracepoint *) = NULL; void tracepoint_set_new_tracepoint_cb(void (*cb)(struct tracepoint *)) { @@ -653,14 +625,15 @@ static void new_tracepoints(struct tracepoint * const *start, struct tracepoint if (new_tracepoint_cb) { struct tracepoint * const *t; - for(t = start; t < end; t++) { + for (t = start; t < end; t++) { if (*t) new_tracepoint_cb(*t); } } } -int tracepoint_register_lib(struct tracepoint * const *tracepoints_start, int tracepoints_count) +int tracepoint_register_lib(struct tracepoint * const *tracepoints_start, + int tracepoints_count) { struct tracepoint_lib *pl, *iter; @@ -669,8 +642,7 @@ int tracepoint_register_lib(struct tracepoint * const *tracepoints_start, int tr pl->tracepoints_start = tracepoints_start; pl->tracepoints_count = tracepoints_count; - /* FIXME: maybe protect this with its own mutex? */ - pthread_mutex_lock(&tracepoints_mutex); + lock_tracepoints(); /* * We sort the libs by struct lib pointer address. */ @@ -685,11 +657,11 @@ int tracepoint_register_lib(struct tracepoint * const *tracepoints_start, int tr /* We should be added at the head of the list */ cds_list_add(&pl->list, &libs); lib_added: - pthread_mutex_unlock(&tracepoints_mutex); + unlock_tracepoints(); new_tracepoints(tracepoints_start, tracepoints_start + tracepoints_count); - /* FIXME: update just the loaded lib */ + /* TODO: update just the loaded lib */ lib_update_tracepoints(); /* tracepoints_count - 1: skip dummy */ @@ -702,8 +674,7 @@ int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start) { struct tracepoint_lib *lib; - pthread_mutex_lock(&tracepoints_mutex); - + lock_tracepoints(); cds_list_for_each_entry(lib, &libs, list) { if (lib->tracepoints_start == tracepoints_start) { struct tracepoint_lib *lib2free = lib; @@ -712,8 +683,22 @@ int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start) break; } } - - pthread_mutex_unlock(&tracepoints_mutex); + unlock_tracepoints(); return 0; } + +void __attribute__((constructor)) init_tracepoint(void) +{ + if (!initialized) { + tracepoint_register_lib(__start___tracepoints_ptrs, + __stop___tracepoints_ptrs + - __start___tracepoints_ptrs); + initialized = 1; + } +} + +void __attribute__((destructor)) destroy_tracepoint(void) +{ + tracepoint_unregister_lib(__start___tracepoints_ptrs); +} diff --git a/libustinstr-malloc/mallocwrap.c b/libustinstr-malloc/mallocwrap.c index a7730c9..6e66856 100644 --- a/libustinstr-malloc/mallocwrap.c +++ b/libustinstr-malloc/mallocwrap.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2009 Pierre-Marc Fournier +/* + * Copyright (C) 2009 Pierre-Marc Fournier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,55 +20,16 @@ #include #include #include - #include -#if 0 -INTERCEPT_PROTOTYPE(void, malloc, size_t size) -INTERCEPT_TRACE("size %d", size) -INTERCEPT_CALL_ARGS(size) -INTERCEPT() - -#define INTERCEPT_FUNC(type, name, args...) \ -__I_FUNC_TYPE(type) \ -__I_FUNC_NAME(name) \ -__I_FUNC_ARGS(args) - -#define INTERCEPT_TRACE(fmt, args...) \ -#define __I_TRACE_FMT fmt \ -#define __I_TRACE_ARGS args - -#define INTERCEPT_CALL_ARGS(args...) \ -#define __I_CALL_ARGS args - -#define INTERCEPT() \ -__I_FUNC_TYPE __I_FUNC_NAME(__I_FUNC_ARGS) \ -{ \ - static __I_FUNC_TYPE (*plibc_ ## __I_FUNC_NAME)(args) = NULL; \ - \ - if(plibc_ ## __I_FUNC_NAME == NULL) { \ - plibc_ ## __I_FUNC_NAME = dlsym(RTLD_NEXT, "malloc"); \ - if(plibc_ ## __I_FUNC_NAME == NULL) { \ - fprintf(stderr, "mallocwrap: unable to find malloc\n"); \ - return NULL; \ - } \ - } \ - \ - ust_marker(ust, __I_FUNC_NAME, __I_TRACE_FMT, __I_TRACE_ARGS); \ - \ - return plibc_ ## __I_FUNC_NAME (__I_CALL_ARGS); \ -} -#endif - void *malloc(size_t size) { static void *(*plibc_malloc)(size_t size) = NULL; - void *retval; - if(plibc_malloc == NULL) { + if (plibc_malloc == NULL) { plibc_malloc = dlsym(RTLD_NEXT, "malloc"); - if(plibc_malloc == NULL) { + if (plibc_malloc == NULL) { fprintf(stderr, "mallocwrap: unable to find malloc\n"); return NULL; } @@ -84,9 +46,9 @@ void free(void *ptr) { static void *(*plibc_free)(void *ptr) = NULL; - if(plibc_free == NULL) { + if (plibc_free == NULL) { plibc_free = dlsym(RTLD_NEXT, "free"); - if(plibc_free == NULL) { + if (plibc_free == NULL) { fprintf(stderr, "mallocwrap: unable to find free\n"); return; }