* Ported to userspace by Pierre-Marc Fournier.
*/
-//ust// #include <linux/module.h>
-//ust// #include <linux/mutex.h>
-//ust// #include <linux/types.h>
-//ust// #include <linux/jhash.h>
-//ust// #include <linux/list.h>
-//ust// #include <linux/rcupdate.h>
-//ust// #include <linux/tracepoint.h>
-//ust// #include <linux/err.h>
-//ust// #include <linux/slab.h>
-//ust// #include <linux/immediate.h>
-
#include <errno.h>
-
-#include "kernelcompat.h"
-#include "tracepoint.h"
+#include <ust/tracepoint.h>
+#include <ust/core.h>
+#include <ust/kcompat/kcompat.h>
#include "usterr.h"
-//#include "list.h"
#define _LGPL_SOURCE
-#include <urcu.h>
+#include <urcu-bp.h>
//extern struct tracepoint __start___tracepoints[] __attribute__((visibility("hidden")));
//extern struct tracepoint __stop___tracepoints[] __attribute__((visibility("hidden")));
static inline void *allocate_probes(int count)
{
- struct tp_probes *p = kmalloc(count * sizeof(void *)
- + sizeof(struct tp_probes), GFP_KERNEL);
+ struct tp_probes *p = malloc(count * sizeof(void *)
+ + sizeof(struct tp_probes));
return p == NULL ? NULL : p->probes;
}
struct tp_probes, probes[0]);
//ust// call_rcu_sched(&tp_probes->u.rcu, rcu_free_old_probes);
synchronize_rcu();
- kfree(tp_probes);
+ free(tp_probes);
}
}
return;
for (i = 0; entry->funcs[i]; i++)
- printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i]);
+ DBG("Probe %d : %p", i, entry->funcs[i]);
}
static void *
head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
hlist_for_each_entry(e, node, head, hlist) {
if (!strcmp(name, e->name)) {
- printk(KERN_NOTICE
- "tracepoint %s busy\n", name);
+ DBG("tracepoint %s busy", name);
return ERR_PTR(-EEXIST); /* Already there */
}
}
* Using kmalloc here to allocate a variable length element. Could
* cause some memory fragmentation if overused.
*/
- e = kmalloc(sizeof(struct tracepoint_entry) + name_len, GFP_KERNEL);
+ e = malloc(sizeof(struct tracepoint_entry) + name_len);
if (!e)
return ERR_PTR(-ENOMEM);
memcpy(&e->name[0], name, name_len);
static inline void remove_tracepoint(struct tracepoint_entry *e)
{
hlist_del(&e->hlist);
- kfree(e);
+ free(e);
}
/*
struct tracepoint *iter;
struct tracepoint_entry *mark_entry;
- mutex_lock(&tracepoints_mutex);
+ pthread_mutex_lock(&tracepoints_mutex);
for (iter = begin; iter < end; iter++) {
mark_entry = get_tracepoint(iter->name);
if (mark_entry) {
disable_tracepoint(iter);
}
}
- mutex_unlock(&tracepoints_mutex);
+ pthread_mutex_unlock(&tracepoints_mutex);
+}
+
+static void lib_update_tracepoints(void)
+{
+ struct tracepoint_lib *lib;
+
+//ust// pthread_mutex_lock(&module_mutex);
+ 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);
}
/*
{
void *old;
- mutex_lock(&tracepoints_mutex);
+ pthread_mutex_lock(&tracepoints_mutex);
old = tracepoint_add_probe(name, probe);
- mutex_unlock(&tracepoints_mutex);
+ pthread_mutex_unlock(&tracepoints_mutex);
if (IS_ERR(old))
return PTR_ERR(old);
{
void *old;
- mutex_lock(&tracepoints_mutex);
+ pthread_mutex_lock(&tracepoints_mutex);
old = tracepoint_remove_probe(name, probe);
- mutex_unlock(&tracepoints_mutex);
+ pthread_mutex_unlock(&tracepoints_mutex);
if (IS_ERR(old))
return PTR_ERR(old);
{
void *old;
- mutex_lock(&tracepoints_mutex);
+ pthread_mutex_lock(&tracepoints_mutex);
old = tracepoint_add_probe(name, probe);
if (IS_ERR(old)) {
- mutex_unlock(&tracepoints_mutex);
+ pthread_mutex_unlock(&tracepoints_mutex);
return PTR_ERR(old);
}
tracepoint_add_old_probes(old);
- mutex_unlock(&tracepoints_mutex);
+ pthread_mutex_unlock(&tracepoints_mutex);
return 0;
}
//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_register_noupdate);
{
void *old;
- mutex_lock(&tracepoints_mutex);
+ pthread_mutex_lock(&tracepoints_mutex);
old = tracepoint_remove_probe(name, probe);
if (IS_ERR(old)) {
- mutex_unlock(&tracepoints_mutex);
+ pthread_mutex_unlock(&tracepoints_mutex);
return PTR_ERR(old);
}
tracepoint_add_old_probes(old);
- mutex_unlock(&tracepoints_mutex);
+ pthread_mutex_unlock(&tracepoints_mutex);
return 0;
}
//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_unregister_noupdate);
LIST_HEAD(release_probes);
struct tp_probes *pos, *next;
- mutex_lock(&tracepoints_mutex);
+ pthread_mutex_lock(&tracepoints_mutex);
if (!need_update) {
- mutex_unlock(&tracepoints_mutex);
+ pthread_mutex_unlock(&tracepoints_mutex);
return;
}
if (!list_empty(&old_probes))
list_replace_init(&old_probes, &release_probes);
need_update = 0;
- mutex_unlock(&tracepoints_mutex);
+ pthread_mutex_unlock(&tracepoints_mutex);
tracepoint_update_probes();
list_for_each_entry_safe(pos, next, &release_probes, u.list) {
list_del(&pos->u.list);
//ust// call_rcu_sched(&pos->u.rcu, rcu_free_old_probes);
synchronize_rcu();
- kfree(pos);
+ free(pos);
}
}
//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_update_all);
+/*
+ * Returns 0 if current not found.
+ * Returns 1 if current found.
+ */
+int lib_get_iter_tracepoints(struct tracepoint_iter *iter)
+{
+ struct tracepoint_lib *iter_lib;
+ int found = 0;
+
+//ust// pthread_mutex_lock(&module_mutex);
+ list_for_each_entry(iter_lib, &libs, list) {
+ if (iter_lib < iter->lib)
+ continue;
+ else if (iter_lib > iter->lib)
+ iter->tracepoint = NULL;
+ found = tracepoint_get_iter_range(&iter->tracepoint,
+ iter_lib->tracepoints_start,
+ iter_lib->tracepoints_start + iter_lib->tracepoints_count);
+ if (found) {
+ iter->lib = iter_lib;
+ break;
+ }
+ }
+//ust// pthread_mutex_unlock(&module_mutex);
+ return found;
+}
+
/**
* tracepoint_get_iter_range - Get a next tracepoint iterator given a range.
* @tracepoint: current tracepoints (in), next tracepoint (out)
//ust// }
/* tracepoints in libs. */
found = lib_get_iter_tracepoints(iter);
-end:
+//ust// end:
if (!found)
tracepoint_iter_reset(iter);
}
//ust// #endif /* CONFIG_MODULES */
-/*
- * Returns 0 if current not found.
- * Returns 1 if current found.
- */
-int lib_get_iter_tracepoints(struct tracepoint_iter *iter)
-{
- struct tracepoint_lib *iter_lib;
- int found = 0;
-
-//ust// mutex_lock(&module_mutex);
- list_for_each_entry(iter_lib, &libs, list) {
- if (iter_lib < iter->lib)
- continue;
- else if (iter_lib > iter->lib)
- iter->tracepoint = NULL;
- found = marker_get_iter_range(&iter->tracepoint,
- iter_lib->tracepoints_start,
- iter_lib->tracepoints_start + iter_lib->tracepoints_count);
- if (found) {
- iter->lib = iter_lib;
- break;
- }
- }
-//ust// mutex_unlock(&module_mutex);
- return found;
-}
-
-void lib_update_tracepoints(void)
-{
- struct tracepoint_lib *lib;
-
-//ust// mutex_lock(&module_mutex);
- list_for_each_entry(lib, &libs, list)
- tracepoint_update_probe_range(lib->tracepoints_start,
- lib->tracepoints_start + lib->tracepoints_count);
-//ust// mutex_unlock(&module_mutex);
-}
-
static void (*new_tracepoint_cb)(struct tracepoint *) = NULL;
void tracepoint_set_new_tracepoint_cb(void (*cb)(struct tracepoint *))
pl->tracepoints_count = tracepoints_count;
/* FIXME: maybe protect this with its own mutex? */
- mutex_lock(&tracepoints_mutex);
+ pthread_mutex_lock(&tracepoints_mutex);
list_add(&pl->list, &libs);
- mutex_unlock(&tracepoints_mutex);
+ pthread_mutex_unlock(&tracepoints_mutex);
new_tracepoints(tracepoints_start, tracepoints_start + tracepoints_count);
return 0;
}
-int tracepoint_unregister_lib(struct tracepoint *tracepoints_start, int tracepoints_count)
+int tracepoint_unregister_lib(struct tracepoint *tracepoints_start)
{
- /*FIXME: implement; but before implementing, tracepoint_register_lib must
- have appropriate locking. */
+ struct tracepoint_lib *lib;
+
+ pthread_mutex_lock(&tracepoints_mutex);
+
+ list_for_each_entry(lib, &libs, list) {
+ if(lib->tracepoints_start == tracepoints_start) {
+ struct tracepoint_lib *lib2free = lib;
+ list_del(&lib->list);
+ free(lib2free);
+ break;
+ }
+ }
+
+ pthread_mutex_unlock(&tracepoints_mutex);
return 0;
}