Mirror of the lttng-dev mailing list
 help / color / mirror / Atom feed
* [ltt-dev] [PATCH 1/2] Add a data pointer to all tracepoint probe callbacks
@ 2010-09-02  7:03 Nils Carlson
  2010-09-02  7:03 ` [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case Nils Carlson
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Nils Carlson @ 2010-09-02  7:03 UTC (permalink / raw)


RCU now dereferences an array of probe structs containing data pointers and
function pointers, and passes the data pointer as the first argument to the
probe.

Due to this change void prototypes are no longer allowed, which has incurred
changes to libust-initializer.c .

This patch also fixes a problem where non-existent tracepoints are present
in the __tracepoints section and with a name pointer pointing at NULL.
---
 include/ust/tracepoint.h |   68 +++++++++++++++++++++---------
 include/ust/ust_trace.h  |    5 +-
 lgpl-relicensing.txt     |    1 +
 libust-initializer.c     |    5 +-
 libust/tracepoint.c      |  103 ++++++++++++++++++++++++++-------------------
 5 files changed, 113 insertions(+), 69 deletions(-)

diff --git a/include/ust/tracepoint.h b/include/ust/tracepoint.h
index 1a91b79..9c7c091 100644
--- a/include/ust/tracepoint.h
+++ b/include/ust/tracepoint.h
@@ -33,10 +33,15 @@
 struct module;
 struct tracepoint;
 
+struct probe {
+	void *func;
+	void *data;
+};
+
 struct tracepoint {
 	const char *name;		/* Tracepoint name */
 	DEFINE_IMV(char, state);	/* State. */
-	void **funcs;
+	struct probe *probes;
 } __attribute__((aligned(32)));		/*
 					 * Aligned on 32 bytes because it is
 					 * globally visible and gcc happily
@@ -58,16 +63,20 @@ struct tracepoint {
  */
 #define __DO_TRACE(tp, proto, args)					\
 	do {								\
-		void **it_func;						\
+		struct probe *it_probe_ptr;				\
+		void *it_func;						\
+		void *__data;						\
 									\
-		rcu_read_lock(); /*ust rcu_read_lock_sched_notrace();	*/			\
-		it_func = rcu_dereference((tp)->funcs);			\
-		if (it_func) {						\
+		rcu_read_lock();					\
+		it_probe_ptr = rcu_dereference((tp)->probes);		\
+		if (it_probe_ptr) {					\
 			do {						\
-				((void(*)(proto))(*it_func))(args);	\
-			} while (*(++it_func));				\
+				it_func	= (it_probe_ptr)->func;		\
+				__data = (it_probe_ptr)->data;		\
+				((void(*)(proto))(it_func))(args);	\
+			} while ((++it_probe_ptr)->func);		\
 		}							\
-		rcu_read_unlock(); /*ust rcu_read_unlock_sched_notrace(); */			\
+		rcu_read_unlock();					\
 	} while (0)
 
 #define __CHECK_TRACE(name, generic, proto, args)			\
@@ -93,37 +102,47 @@ struct tracepoint {
  * If generic is true, a variable read is used.
  * If generic is false, immediate values are used.
  */
-#define DECLARE_TRACE(name, proto, args)				\
+#define __DECLARE_TRACE(name, proto, args, data_proto, data_args)	\
 	extern struct tracepoint __tracepoint_##name;			\
 	static inline void trace_##name(proto)				\
 	{								\
-		__CHECK_TRACE(name, 0, TP_PROTO(proto), TP_ARGS(args));	\
+		__CHECK_TRACE(name, 0, TP_PROTO(data_proto),		\
+			      TP_ARGS(data_args));			\
 	}								\
 	static inline void _trace_##name(proto)				\
 	{								\
-		__CHECK_TRACE(name, 1, TP_PROTO(proto), TP_ARGS(args));	\
+		__CHECK_TRACE(name, 1, TP_PROTO(data_proto),		\
+			      TP_ARGS(data_args));			\
 	}								\
-	static inline int register_trace_##name(void (*probe)(proto))	\
+	static inline int						\
+	register_trace_##name(void (*probe)(data_proto), void *data)	\
 	{								\
-		return tracepoint_probe_register(#name, (void *)probe);	\
+		return tracepoint_probe_register(#name, (void *)probe,	\
+						 data);			\
+									\
 	}								\
-	static inline int unregister_trace_##name(void (*probe)(proto))	\
+	static inline int						\
+	unregister_trace_##name(void (*probe)(data_proto), void *data)	\
 	{								\
-		return tracepoint_probe_unregister(#name, (void *)probe);\
+		return tracepoint_probe_unregister(#name, (void *)probe, \
+						   data);		\
 	}
 
-#define DEFINE_TRACE(name)						\
+#define DEFINE_TRACE_FN(name, reg, unreg)					\
 	static const char __tpstrtab_##name[]				\
 	__attribute__((section("__tracepoints_strings"))) = #name;	\
 	struct tracepoint __tracepoint_##name				\
 	__attribute__((section("__tracepoints"), aligned(32))) =	\
 		{ __tpstrtab_##name, 0, NULL }
 
+#define DEFINE_TRACE(name)						\
+	DEFINE_TRACE_FN(name, NULL, NULL);
+
 extern void tracepoint_update_probe_range(struct tracepoint *begin,
 	struct tracepoint *end);
 
 #else /* !CONFIG_TRACEPOINTS */
-#define DECLARE_TRACE(name, proto, args)				\
+#define __DECLARE_TRACE(name, proto, args)				\
 	static inline void trace_##name(proto)				\
 	{ }								\
 	static inline void _trace_##name(proto)				\
@@ -146,20 +165,27 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin,
 { }
 #endif /* CONFIG_TRACEPOINTS */
 
+#define DECLARE_TRACE(name, proto, args)			\
+	__DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),	\
+			PARAMS(void *__data, proto),		\
+			PARAMS(__data, args))
+
 /*
  * Connect a probe to a tracepoint.
  * Internal API, should not be used directly.
  */
-extern int tracepoint_probe_register(const char *name, void *probe);
+extern int tracepoint_probe_register(const char *name, void *probe, void *data);
 
 /*
  * Disconnect a probe from a tracepoint.
  * Internal API, should not be used directly.
  */
-extern int tracepoint_probe_unregister(const char *name, void *probe);
+extern int tracepoint_probe_unregister(const char *name, void *probe, void *data);
 
-extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
-extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
+extern int tracepoint_probe_register_noupdate(const char *name, void *probe,
+					      void *data);
+extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
+						void *data);
 extern void tracepoint_probe_update_all(void);
 
 struct tracepoint_iter {
diff --git a/include/ust/ust_trace.h b/include/ust/ust_trace.h
index 098c5f8..e1b0257 100644
--- a/include/ust/ust_trace.h
+++ b/include/ust/ust_trace.h
@@ -58,7 +58,7 @@
 	struct trace_raw_##name {					\
 		tstruct							\
 	};								\
-	static void trace_printf_##name(proto)				\
+	static void trace_printf_##name(void *dummy, proto)		\
 	{								\
 		struct trace_raw_##name entry_struct, *__entry;		\
 		__entry = &entry_struct;				\
@@ -68,8 +68,9 @@
 	}								\
 	static void __attribute__((constructor)) init_##name()		\
 	{								\
+		void *dummy;						\
 		printf("connecting tracepoint " #name "\n");		\
-		register_trace_##name(trace_printf_##name);		\
+		register_trace_##name(trace_printf_##name, dummy);	\
 	}
 
 
diff --git a/lgpl-relicensing.txt b/lgpl-relicensing.txt
index 0393851..753f453 100644
--- a/lgpl-relicensing.txt
+++ b/lgpl-relicensing.txt
@@ -10,6 +10,7 @@ Steven Rostedt		       <rostedt at goodmis.org>
 Frederic Weisbecker	       <fweisbec at gmail.com>
 Xiao Guangrong		       <xiaogunagrong at cn.fujitsu.com>
 Josh Stone		       <jistone at redhat.com>
+Lai Jiangshan		       <laijs at cn.fujitsu.com>
 
 The following copyright holders have agreed to LGPLv2.1+ re-licensing
 of their contributions to linux/include/stringify.h.
diff --git a/libust-initializer.c b/libust-initializer.c
index ec39932..390218e 100644
--- a/libust-initializer.c
+++ b/libust-initializer.c
@@ -18,13 +18,14 @@
  * avoid this.
  */
 
-DECLARE_TRACE(ust_dummytp, TP_PROTO(void), TP_ARGS());
+DECLARE_TRACE(ust_dummytp, TP_PROTO(int anint), TP_ARGS(anint));
 DEFINE_TRACE(ust_dummytp);
 
 void dummy_libust_initializer_func(void)
 {
+	int i;
 	trace_mark(ust, dummymark, MARK_NOARGS);
-	trace_ust_dummytp();
+	trace_ust_dummytp(i);
 }
 
 MARKER_LIB;
diff --git a/libust/tracepoint.c b/libust/tracepoint.c
index 6155e29..620a009 100644
--- a/libust/tracepoint.c
+++ b/libust/tracepoint.c
@@ -59,7 +59,7 @@ static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
  */
 struct tracepoint_entry {
 	struct hlist_node hlist;
-	void **funcs;
+	struct probe *probes;
 	int refcount;	/* Number of times armed. 0 if disarmed. */
 	char name[0];
 };
@@ -69,12 +69,12 @@ struct tp_probes {
 //ust//		struct rcu_head rcu;
 		struct list_head list;
 	} u;
-	void *probes[0];
+	struct probe probes[0];
 };
 
 static inline void *allocate_probes(int count)
 {
-	struct tp_probes *p  = malloc(count * sizeof(void *)
+	struct tp_probes *p  = malloc(count * sizeof(struct probe)
 			+ sizeof(struct tp_probes));
 	return p == NULL ? NULL : p->probes;
 }
@@ -99,27 +99,29 @@ static void debug_print_probes(struct tracepoint_entry *entry)
 {
 	int i;
 
-	if (!tracepoint_debug || !entry->funcs)
+	if (!tracepoint_debug || !entry->probes)
 		return;
 
-	for (i = 0; entry->funcs[i]; i++)
-		DBG("Probe %d : %p", i, entry->funcs[i]);
+	for (i = 0; entry->probes[i].func; i++)
+		DBG("Probe %d : %p", i, entry->probes[i].func);
 }
 
 static void *
-tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
+tracepoint_entry_add_probe(struct tracepoint_entry *entry,
+			   void *probe, void *data)
 {
 	int nr_probes = 0;
-	void **old, **new;
+	struct probe *old, *new;
 
 	WARN_ON(!probe);
 
 	debug_print_probes(entry);
-	old = entry->funcs;
+	old = entry->probes;
 	if (old) {
 		/* (N -> N+1), (N != 0, 1) probes */
-		for (nr_probes = 0; old[nr_probes]; nr_probes++)
-			if (old[nr_probes] == probe)
+		for (nr_probes = 0; old[nr_probes].func; nr_probes++)
+			if (old[nr_probes].func == probe &&
+			    old[nr_probes].data == data)
 				return ERR_PTR(-EEXIST);
 	}
 	/* + 2 : one for new probe, one for NULL func */
@@ -127,36 +129,40 @@ tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
 	if (new == NULL)
 		return ERR_PTR(-ENOMEM);
 	if (old)
-		memcpy(new, old, nr_probes * sizeof(void *));
-	new[nr_probes] = probe;
-	new[nr_probes + 1] = NULL;
+		memcpy(new, old, nr_probes * sizeof(struct probe));
+	new[nr_probes].func = probe;
+	new[nr_probes].data = data;
+	new[nr_probes + 1].func = NULL;
 	entry->refcount = nr_probes + 1;
-	entry->funcs = new;
+	entry->probes = new;
 	debug_print_probes(entry);
 	return old;
 }
 
 static void *
-tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
+tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe,
+			      void *data)
 {
 	int nr_probes = 0, nr_del = 0, i;
-	void **old, **new;
+	struct probe *old, *new;
 
-	old = entry->funcs;
+	old = entry->probes;
 
 	if (!old)
 		return ERR_PTR(-ENOENT);
 
 	debug_print_probes(entry);
 	/* (N -> M), (N > 1, M >= 0) probes */
-	for (nr_probes = 0; old[nr_probes]; nr_probes++) {
-		if ((!probe || old[nr_probes] == probe))
+	for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
+		if ((!probe ||
+		     old[nr_probes].func == probe &&
+		     old[nr_probes].data == data))
 			nr_del++;
 	}
 
 	if (nr_probes - nr_del == 0) {
 		/* N -> 0, (N > 1) */
-		entry->funcs = NULL;
+		entry->probes = NULL;
 		entry->refcount = 0;
 		debug_print_probes(entry);
 		return old;
@@ -167,12 +173,13 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
 		new = allocate_probes(nr_probes - nr_del + 1);
 		if (new == NULL)
 			return ERR_PTR(-ENOMEM);
-		for (i = 0; old[i]; i++)
-			if ((probe && old[i] != probe))
+		for (i = 0; old[i].func; i++)
+			if (probe &&
+			    (old[i].func != probe || old[i].data != data))
 				new[j++] = old[i];
-		new[nr_probes - nr_del] = NULL;
+		new[nr_probes - nr_del].func = NULL;
 		entry->refcount = nr_probes - nr_del;
-		entry->funcs = new;
+		entry->probes = new;
 	}
 	debug_print_probes(entry);
 	return old;
@@ -225,7 +232,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
 	if (!e)
 		return ERR_PTR(-ENOMEM);
 	memcpy(&e->name[0], name, name_len);
-	e->funcs = NULL;
+	e->probes = NULL;
 	e->refcount = 0;
 	hlist_add_head(&e->hlist, head);
 	return e;
@@ -256,7 +263,7 @@ static void set_tracepoint(struct tracepoint_entry **entry,
 	 * include/linux/tracepoints.h. A matching smp_read_barrier_depends()
 	 * is used.
 	 */
-	rcu_assign_pointer(elem->funcs, (*entry)->funcs);
+	rcu_assign_pointer(elem->probes, (*entry)->probes);
 	elem->state__imv = active;
 }
 
@@ -269,7 +276,7 @@ static void set_tracepoint(struct tracepoint_entry **entry,
 static void disable_tracepoint(struct tracepoint *elem)
 {
 	elem->state__imv = 0;
-	rcu_assign_pointer(elem->funcs, NULL);
+	rcu_assign_pointer(elem->probes, NULL);
 }
 
 /**
@@ -280,13 +287,17 @@ static void disable_tracepoint(struct tracepoint *elem)
  * Updates the probe callback corresponding to a range of tracepoints.
  */
 void tracepoint_update_probe_range(struct tracepoint *begin,
-	struct tracepoint *end)
+				   struct tracepoint *end)
 {
 	struct tracepoint *iter;
 	struct tracepoint_entry *mark_entry;
 
 	pthread_mutex_lock(&tracepoints_mutex);
 	for (iter = begin; iter < end; iter++) {
+		if (!iter->name) {
+			disable_tracepoint(iter);
+			continue;
+		}
 		mark_entry = get_tracepoint(iter->name);
 		if (mark_entry) {
 			set_tracepoint(&mark_entry, iter,
@@ -324,18 +335,19 @@ static void tracepoint_update_probes(void)
 //ust//	module_imv_update();
 }
 
-static void *tracepoint_add_probe(const char *name, void *probe)
+static struct probe *
+tracepoint_add_probe(const char *name, void *probe, void *data)
 {
 	struct tracepoint_entry *entry;
-	void *old;
+	struct probe *old;
 
 	entry = get_tracepoint(name);
 	if (!entry) {
 		entry = add_tracepoint(name);
 		if (IS_ERR(entry))
-			return entry;
+			return (struct probe *)entry;
 	}
-	old = tracepoint_entry_add_probe(entry, probe);
+	old = tracepoint_entry_add_probe(entry, probe, data);
 	if (IS_ERR(old) && !entry->refcount)
 		remove_tracepoint(entry);
 	return old;
@@ -349,12 +361,12 @@ static void *tracepoint_add_probe(const char *name, void *probe)
  * Returns 0 if ok, error value on error.
  * The probe address must at least be aligned on the architecture pointer size.
  */
-int tracepoint_probe_register(const char *name, void *probe)
+int tracepoint_probe_register(const char *name, void *probe, void *data)
 {
 	void *old;
 
 	pthread_mutex_lock(&tracepoints_mutex);
-	old = tracepoint_add_probe(name, probe);
+	old = tracepoint_add_probe(name, probe, data);
 	pthread_mutex_unlock(&tracepoints_mutex);
 	if (IS_ERR(old))
 		return PTR_ERR(old);
@@ -365,7 +377,7 @@ int tracepoint_probe_register(const char *name, void *probe)
 }
 //ust// EXPORT_SYMBOL_GPL(tracepoint_probe_register);
 
-static void *tracepoint_remove_probe(const char *name, void *probe)
+static void *tracepoint_remove_probe(const char *name, void *probe, void *data)
 {
 	struct tracepoint_entry *entry;
 	void *old;
@@ -373,7 +385,7 @@ static void *tracepoint_remove_probe(const char *name, void *probe)
 	entry = get_tracepoint(name);
 	if (!entry)
 		return ERR_PTR(-ENOENT);
-	old = tracepoint_entry_remove_probe(entry, probe);
+	old = tracepoint_entry_remove_probe(entry, probe, data);
 	if (IS_ERR(old))
 		return old;
 	if (!entry->refcount)
@@ -385,18 +397,19 @@ static void *tracepoint_remove_probe(const char *name, void *probe)
  * tracepoint_probe_unregister -  Disconnect a probe from a tracepoint
  * @name: tracepoint name
  * @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.
  */
-int tracepoint_probe_unregister(const char *name, void *probe)
+int tracepoint_probe_unregister(const char *name, void *probe, void *data)
 {
 	void *old;
 
 	pthread_mutex_lock(&tracepoints_mutex);
-	old = tracepoint_remove_probe(name, probe);
+	old = tracepoint_remove_probe(name, probe, data);
 	pthread_mutex_unlock(&tracepoints_mutex);
 	if (IS_ERR(old))
 		return PTR_ERR(old);
@@ -427,12 +440,13 @@ static void tracepoint_add_old_probes(void *old)
  *
  * caller must call tracepoint_probe_update_all()
  */
-int tracepoint_probe_register_noupdate(const char *name, void *probe)
+int tracepoint_probe_register_noupdate(const char *name, void *probe,
+				       void *data)
 {
 	void *old;
 
 	pthread_mutex_lock(&tracepoints_mutex);
-	old = tracepoint_add_probe(name, probe);
+	old = tracepoint_add_probe(name, probe, data);
 	if (IS_ERR(old)) {
 		pthread_mutex_unlock(&tracepoints_mutex);
 		return PTR_ERR(old);
@@ -450,12 +464,13 @@ int tracepoint_probe_register_noupdate(const char *name, void *probe)
  *
  * caller must call tracepoint_probe_update_all()
  */
-int tracepoint_probe_unregister_noupdate(const char *name, void *probe)
+int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
+					 void *data)
 {
 	void *old;
 
 	pthread_mutex_lock(&tracepoints_mutex);
-	old = tracepoint_remove_probe(name, probe);
+	old = tracepoint_remove_probe(name, probe, data);
 	if (IS_ERR(old)) {
 		pthread_mutex_unlock(&tracepoints_mutex);
 		return PTR_ERR(old);
@@ -662,7 +677,7 @@ int tracepoint_register_lib(struct tracepoint *tracepoints_start, int tracepoint
 	lib_update_tracepoints();
 
 	DBG("just registered a tracepoints section from %p and having %d tracepoints", tracepoints_start, tracepoints_count);
-	
+
 	return 0;
 }
 
-- 
1.7.1





^ permalink raw reply	[flat|nested] 8+ messages in thread

* [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case
  2010-09-02  7:03 [ltt-dev] [PATCH 1/2] Add a data pointer to all tracepoint probe callbacks Nils Carlson
@ 2010-09-02  7:03 ` Nils Carlson
  2010-09-02 14:09   ` Mathieu Desnoyers
  2010-09-02  9:08 ` [ltt-dev] [PATCH 1/2] Add a data pointer to all tracepoint probe callbacks Nils Carlson
  2010-09-02 13:52 ` Mathieu Desnoyers
  2 siblings, 1 reply; 8+ messages in thread
From: Nils Carlson @ 2010-09-02  7:03 UTC (permalink / raw)


Update the test-case for probes to handle a new data pointer
in the probe function. Also add a new test-case that stress-tests
probe registration and unregistration.
---
 configure.ac                        |    1 +
 tests/Makefile.am                   |    2 +-
 tests/hello/hello.c                 |    2 +-
 tests/hello/tp.c                    |   18 +++++--
 tests/register_test/Makefile.am     |    5 ++
 tests/register_test/register_test.c |   97 +++++++++++++++++++++++++++++++++++
 tests/register_test/tp.h            |   22 ++++++++
 7 files changed, 141 insertions(+), 6 deletions(-)
 create mode 100644 tests/register_test/Makefile.am
 create mode 100644 tests/register_test/register_test.c
 create mode 100644 tests/register_test/tp.h

diff --git a/configure.ac b/configure.ac
index dee974f..10a02e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -122,6 +122,7 @@ AC_CONFIG_FILES([
 	tests/dlopen/Makefile
 	tests/same_line_marker/Makefile
 	tests/trace_event/Makefile
+	tests/register_test/Makefile
 	libustinstr-malloc/Makefile
 	libustfork/Makefile
 	libustd/Makefile
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ab13cd7..1d31c3f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = hello hello2 basic basic_long fork simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event
+SUBDIRS = hello hello2 basic basic_long fork simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event register_test
 
 dist_noinst_SCRIPTS = test_loop runtests trace_matches
diff --git a/tests/hello/hello.c b/tests/hello/hello.c
index 86c5c71..8147860 100644
--- a/tests/hello/hello.c
+++ b/tests/hello/hello.c
@@ -26,8 +26,8 @@
 
 #include <ust/marker.h>
 #include "usterr.h"
-#include "tp.h"
 #include "tracer.h"
+#include "tp.h"
 
 void inthandler(int sig)
 {
diff --git a/tests/hello/tp.c b/tests/hello/tp.c
index be10615..3a4c6fc 100644
--- a/tests/hello/tp.c
+++ b/tests/hello/tp.c
@@ -19,16 +19,26 @@
 #include <ust/marker.h>
 #include "usterr.h"
 
+struct hello_trace_struct {
+	char *message;
+};
+
+struct hello_trace_struct hello_struct = {
+	.message = "ehlo\n",
+};
+
 DEFINE_TRACE(hello_tptest);
 
-void tptest_probe(int anint)
+void tptest_probe(void *data, int anint)
 {
+	struct hello_trace_struct *hello;
+	hello=(struct hello_trace_struct *)data;
 	DBG("in tracepoint probe...");
-	trace_mark(ust, tptest, "anint %d", anint);
+	printf("this is the message: %s\n", hello->message);
 }
 
 static void __attribute__((constructor)) init()
 {
-	DBG("connecting tracepoint...");
-	register_trace_hello_tptest(tptest_probe);
+	DBG("connecting tracepoint...\n");
+	register_trace_hello_tptest(tptest_probe, &hello_struct);
 }
diff --git a/tests/register_test/Makefile.am b/tests/register_test/Makefile.am
new file mode 100644
index 0000000..ff25e08
--- /dev/null
+++ b/tests/register_test/Makefile.am
@@ -0,0 +1,5 @@
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libust
+
+noinst_PROGRAMS = register_test
+register_test_SOURCES = register_test.c tp.h
+register_test_LDADD = $(top_builddir)/libust/libust.la $(top_builddir)/libust-initializer.o
diff --git a/tests/register_test/register_test.c b/tests/register_test/register_test.c
new file mode 100644
index 0000000..8b65ffb
--- /dev/null
+++ b/tests/register_test/register_test.c
@@ -0,0 +1,97 @@
+/* Copyright (C) 2010 Nils Carlson
+ *
+ * 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/timerfd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pthread.h>
+
+#include <ust/marker.h>
+#include "usterr.h"
+#include "tracer.h"
+#include "tp.h"
+
+DEFINE_TRACE(hello_tptest);
+
+
+struct hello_trace_struct {
+	char *message;
+};
+
+struct hello_trace_struct hello_struct = {
+	.message = "ehlo\n",
+};
+
+void tptest_probe(void *data, int anint)
+{
+	struct hello_trace_struct *hello;
+	char message[30];
+	hello=(struct hello_trace_struct *)data;
+	//printf("this is the message: %s\n", hello->message);
+	snprintf(message, 30, "this is the %s\n", hello->message);
+}
+
+
+#define HELLO_LENGTH 100
+
+static void * register_thread_main(void *data)
+{
+	int ret, i, j = 0;
+
+	struct hello_trace_struct hello[HELLO_LENGTH];
+
+	for (i=0; i<HELLO_LENGTH; i++) {
+		hello[i].message = malloc(6*sizeof(char));
+		hello[i].message[0] = 'a'+i%25;
+		memcpy(&hello[i].message[1], "ello", 5);
+	}
+
+	for (i=0; i<1000; i++) {
+		while (!register_trace_hello_tptest(tptest_probe,
+						    &hello[j%HELLO_LENGTH])) {
+			usleep(10);
+			j++;
+		}
+		printf("Registered all\n");
+		while (!unregister_trace_hello_tptest(tptest_probe,
+						      &hello[j%HELLO_LENGTH])) {
+			usleep(10);
+			j++;
+		}
+		printf("Unregistered all\n");
+	}
+}
+
+
+int main()
+{
+	pthread_t register_thread;
+	int i;
+
+	pthread_create(&register_thread, NULL, register_thread_main, NULL);
+	for(i=0; i<1000000; i++) {
+		trace_hello_tptest(i);
+	}
+
+	return 0;
+}
diff --git a/tests/register_test/tp.h b/tests/register_test/tp.h
new file mode 100644
index 0000000..f34f305
--- /dev/null
+++ b/tests/register_test/tp.h
@@ -0,0 +1,22 @@
+/* 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <ust/tracepoint.h>
+
+DECLARE_TRACE(hello_tptest,
+	      TP_PROTO(int anint),
+	      TP_ARGS(anint));
-- 
1.7.1




^ permalink raw reply	[flat|nested] 8+ messages in thread

* [ltt-dev] [PATCH 1/2] Add a data pointer to all tracepoint probe callbacks
  2010-09-02  7:03 [ltt-dev] [PATCH 1/2] Add a data pointer to all tracepoint probe callbacks Nils Carlson
  2010-09-02  7:03 ` [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case Nils Carlson
@ 2010-09-02  9:08 ` Nils Carlson
  2010-09-02 13:52 ` Mathieu Desnoyers
  2 siblings, 0 replies; 8+ messages in thread
From: Nils Carlson @ 2010-09-02  9:08 UTC (permalink / raw)


This is just a clean up of the earlier patch, removed some things that 
aren't necessary yet.

Should have labeled v2. Sorry. :-/

/Nils

On Thu, 2 Sep 2010, Nils Carlson wrote:

> RCU now dereferences an array of probe structs containing data pointers and
> function pointers, and passes the data pointer as the first argument to the
> probe.
>
> Due to this change void prototypes are no longer allowed, which has incurred
> changes to libust-initializer.c .
>
> This patch also fixes a problem where non-existent tracepoints are present
> in the __tracepoints section and with a name pointer pointing at NULL.
> ---
> include/ust/tracepoint.h |   68 +++++++++++++++++++++---------
> include/ust/ust_trace.h  |    5 +-
> lgpl-relicensing.txt     |    1 +
> libust-initializer.c     |    5 +-
> libust/tracepoint.c      |  103 ++++++++++++++++++++++++++-------------------
> 5 files changed, 113 insertions(+), 69 deletions(-)
>
> diff --git a/include/ust/tracepoint.h b/include/ust/tracepoint.h
> index 1a91b79..9c7c091 100644
> --- a/include/ust/tracepoint.h
> +++ b/include/ust/tracepoint.h
> @@ -33,10 +33,15 @@
> struct module;
> struct tracepoint;
>
> +struct probe {
> +       void *func;
> +       void *data;
> +};
> +
> struct tracepoint {
>        const char *name;               /* Tracepoint name */
>        DEFINE_IMV(char, state);        /* State. */
> -       void **funcs;
> +       struct probe *probes;
> } __attribute__((aligned(32)));                /*
>                                         * Aligned on 32 bytes because it is
>                                         * globally visible and gcc happily
> @@ -58,16 +63,20 @@ struct tracepoint {
>  */
> #define __DO_TRACE(tp, proto, args)                                    \
>        do {                                                            \
> -               void **it_func;                                         \
> +               struct probe *it_probe_ptr;                             \
> +               void *it_func;                                          \
> +               void *__data;                                           \
>                                                                        \
> -               rcu_read_lock(); /*ust rcu_read_lock_sched_notrace();   */                      \
> -               it_func = rcu_dereference((tp)->funcs);                 \
> -               if (it_func) {                                          \
> +               rcu_read_lock();                                        \
> +               it_probe_ptr = rcu_dereference((tp)->probes);           \
> +               if (it_probe_ptr) {                                     \
>                        do {                                            \
> -                               ((void(*)(proto))(*it_func))(args);     \
> -                       } while (*(++it_func));                         \
> +                               it_func = (it_probe_ptr)->func;         \
> +                               __data = (it_probe_ptr)->data;          \
> +                               ((void(*)(proto))(it_func))(args);      \
> +                       } while ((++it_probe_ptr)->func);               \
>                }                                                       \
> -               rcu_read_unlock(); /*ust rcu_read_unlock_sched_notrace(); */                    \
> +               rcu_read_unlock();                                      \
>        } while (0)
>
> #define __CHECK_TRACE(name, generic, proto, args)                      \
> @@ -93,37 +102,47 @@ struct tracepoint {
>  * If generic is true, a variable read is used.
>  * If generic is false, immediate values are used.
>  */
> -#define DECLARE_TRACE(name, proto, args)                               \
> +#define __DECLARE_TRACE(name, proto, args, data_proto, data_args)      \
>        extern struct tracepoint __tracepoint_##name;                   \
>        static inline void trace_##name(proto)                          \
>        {                                                               \
> -               __CHECK_TRACE(name, 0, TP_PROTO(proto), TP_ARGS(args)); \
> +               __CHECK_TRACE(name, 0, TP_PROTO(data_proto),            \
> +                             TP_ARGS(data_args));                      \
>        }                                                               \
>        static inline void _trace_##name(proto)                         \
>        {                                                               \
> -               __CHECK_TRACE(name, 1, TP_PROTO(proto), TP_ARGS(args)); \
> +               __CHECK_TRACE(name, 1, TP_PROTO(data_proto),            \
> +                             TP_ARGS(data_args));                      \
>        }                                                               \
> -       static inline int register_trace_##name(void (*probe)(proto))   \
> +       static inline int                                               \
> +       register_trace_##name(void (*probe)(data_proto), void *data)    \
>        {                                                               \
> -               return tracepoint_probe_register(#name, (void *)probe); \
> +               return tracepoint_probe_register(#name, (void *)probe,  \
> +                                                data);                 \
> +                                                                       \
>        }                                                               \
> -       static inline int unregister_trace_##name(void (*probe)(proto)) \
> +       static inline int                                               \
> +       unregister_trace_##name(void (*probe)(data_proto), void *data)  \
>        {                                                               \
> -               return tracepoint_probe_unregister(#name, (void *)probe);\
> +               return tracepoint_probe_unregister(#name, (void *)probe, \
> +                                                  data);               \
>        }
>
> -#define DEFINE_TRACE(name)                                             \
> +#define DEFINE_TRACE_FN(name, reg, unreg)                                      \
>        static const char __tpstrtab_##name[]                           \
>        __attribute__((section("__tracepoints_strings"))) = #name;      \
>        struct tracepoint __tracepoint_##name                           \
>        __attribute__((section("__tracepoints"), aligned(32))) =        \
>                { __tpstrtab_##name, 0, NULL }
>
> +#define DEFINE_TRACE(name)                                             \
> +       DEFINE_TRACE_FN(name, NULL, NULL);
> +
> extern void tracepoint_update_probe_range(struct tracepoint *begin,
>        struct tracepoint *end);
>
> #else /* !CONFIG_TRACEPOINTS */
> -#define DECLARE_TRACE(name, proto, args)                               \
> +#define __DECLARE_TRACE(name, proto, args)                             \
>        static inline void trace_##name(proto)                          \
>        { }                                                             \
>        static inline void _trace_##name(proto)                         \
> @@ -146,20 +165,27 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin,
> { }
> #endif /* CONFIG_TRACEPOINTS */
>
> +#define DECLARE_TRACE(name, proto, args)                       \
> +       __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),      \
> +                       PARAMS(void *__data, proto),            \
> +                       PARAMS(__data, args))
> +
> /*
>  * Connect a probe to a tracepoint.
>  * Internal API, should not be used directly.
>  */
> -extern int tracepoint_probe_register(const char *name, void *probe);
> +extern int tracepoint_probe_register(const char *name, void *probe, void *data);
>
> /*
>  * Disconnect a probe from a tracepoint.
>  * Internal API, should not be used directly.
>  */
> -extern int tracepoint_probe_unregister(const char *name, void *probe);
> +extern int tracepoint_probe_unregister(const char *name, void *probe, void *data);
>
> -extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
> -extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
> +extern int tracepoint_probe_register_noupdate(const char *name, void *probe,
> +                                             void *data);
> +extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
> +                                               void *data);
> extern void tracepoint_probe_update_all(void);
>
> struct tracepoint_iter {
> diff --git a/include/ust/ust_trace.h b/include/ust/ust_trace.h
> index 098c5f8..e1b0257 100644
> --- a/include/ust/ust_trace.h
> +++ b/include/ust/ust_trace.h
> @@ -58,7 +58,7 @@
>        struct trace_raw_##name {                                       \
>                tstruct                                                 \
>        };                                                              \
> -       static void trace_printf_##name(proto)                          \
> +       static void trace_printf_##name(void *dummy, proto)             \
>        {                                                               \
>                struct trace_raw_##name entry_struct, *__entry;         \
>                __entry = &entry_struct;                                \
> @@ -68,8 +68,9 @@
>        }                                                               \
>        static void __attribute__((constructor)) init_##name()          \
>        {                                                               \
> +               void *dummy;                                            \
>                printf("connecting tracepoint " #name "\n");            \
> -               register_trace_##name(trace_printf_##name);             \
> +               register_trace_##name(trace_printf_##name, dummy);      \
>        }
>
>
> diff --git a/lgpl-relicensing.txt b/lgpl-relicensing.txt
> index 0393851..753f453 100644
> --- a/lgpl-relicensing.txt
> +++ b/lgpl-relicensing.txt
> @@ -10,6 +10,7 @@ Steven Rostedt                       <rostedt at goodmis.org>
> Frederic Weisbecker           <fweisbec at gmail.com>
> Xiao Guangrong                <xiaogunagrong at cn.fujitsu.com>
> Josh Stone                    <jistone at redhat.com>
> +Lai Jiangshan                 <laijs at cn.fujitsu.com>
>
> The following copyright holders have agreed to LGPLv2.1+ re-licensing
> of their contributions to linux/include/stringify.h.
> diff --git a/libust-initializer.c b/libust-initializer.c
> index ec39932..390218e 100644
> --- a/libust-initializer.c
> +++ b/libust-initializer.c
> @@ -18,13 +18,14 @@
>  * avoid this.
>  */
>
> -DECLARE_TRACE(ust_dummytp, TP_PROTO(void), TP_ARGS());
> +DECLARE_TRACE(ust_dummytp, TP_PROTO(int anint), TP_ARGS(anint));
> DEFINE_TRACE(ust_dummytp);
>
> void dummy_libust_initializer_func(void)
> {
> +       int i;
>        trace_mark(ust, dummymark, MARK_NOARGS);
> -       trace_ust_dummytp();
> +       trace_ust_dummytp(i);
> }
>
> MARKER_LIB;
> diff --git a/libust/tracepoint.c b/libust/tracepoint.c
> index 6155e29..620a009 100644
> --- a/libust/tracepoint.c
> +++ b/libust/tracepoint.c
> @@ -59,7 +59,7 @@ static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
>  */
> struct tracepoint_entry {
>        struct hlist_node hlist;
> -       void **funcs;
> +       struct probe *probes;
>        int refcount;   /* Number of times armed. 0 if disarmed. */
>        char name[0];
> };
> @@ -69,12 +69,12 @@ struct tp_probes {
> //ust//                struct rcu_head rcu;
>                struct list_head list;
>        } u;
> -       void *probes[0];
> +       struct probe probes[0];
> };
>
> static inline void *allocate_probes(int count)
> {
> -       struct tp_probes *p  = malloc(count * sizeof(void *)
> +       struct tp_probes *p  = malloc(count * sizeof(struct probe)
>                        + sizeof(struct tp_probes));
>        return p == NULL ? NULL : p->probes;
> }
> @@ -99,27 +99,29 @@ static void debug_print_probes(struct tracepoint_entry *entry)
> {
>        int i;
>
> -       if (!tracepoint_debug || !entry->funcs)
> +       if (!tracepoint_debug || !entry->probes)
>                return;
>
> -       for (i = 0; entry->funcs[i]; i++)
> -               DBG("Probe %d : %p", i, entry->funcs[i]);
> +       for (i = 0; entry->probes[i].func; i++)
> +               DBG("Probe %d : %p", i, entry->probes[i].func);
> }
>
> static void *
> -tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
> +tracepoint_entry_add_probe(struct tracepoint_entry *entry,
> +                          void *probe, void *data)
> {
>        int nr_probes = 0;
> -       void **old, **new;
> +       struct probe *old, *new;
>
>        WARN_ON(!probe);
>
>        debug_print_probes(entry);
> -       old = entry->funcs;
> +       old = entry->probes;
>        if (old) {
>                /* (N -> N+1), (N != 0, 1) probes */
> -               for (nr_probes = 0; old[nr_probes]; nr_probes++)
> -                       if (old[nr_probes] == probe)
> +               for (nr_probes = 0; old[nr_probes].func; nr_probes++)
> +                       if (old[nr_probes].func == probe &&
> +                           old[nr_probes].data == data)
>                                return ERR_PTR(-EEXIST);
>        }
>        /* + 2 : one for new probe, one for NULL func */
> @@ -127,36 +129,40 @@ tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
>        if (new == NULL)
>                return ERR_PTR(-ENOMEM);
>        if (old)
> -               memcpy(new, old, nr_probes * sizeof(void *));
> -       new[nr_probes] = probe;
> -       new[nr_probes + 1] = NULL;
> +               memcpy(new, old, nr_probes * sizeof(struct probe));
> +       new[nr_probes].func = probe;
> +       new[nr_probes].data = data;
> +       new[nr_probes + 1].func = NULL;
>        entry->refcount = nr_probes + 1;
> -       entry->funcs = new;
> +       entry->probes = new;
>        debug_print_probes(entry);
>        return old;
> }
>
> static void *
> -tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
> +tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe,
> +                             void *data)
> {
>        int nr_probes = 0, nr_del = 0, i;
> -       void **old, **new;
> +       struct probe *old, *new;
>
> -       old = entry->funcs;
> +       old = entry->probes;
>
>        if (!old)
>                return ERR_PTR(-ENOENT);
>
>        debug_print_probes(entry);
>        /* (N -> M), (N > 1, M >= 0) probes */
> -       for (nr_probes = 0; old[nr_probes]; nr_probes++) {
> -               if ((!probe || old[nr_probes] == probe))
> +       for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
> +               if ((!probe ||
> +                    old[nr_probes].func == probe &&
> +                    old[nr_probes].data == data))
>                        nr_del++;
>        }
>
>        if (nr_probes - nr_del == 0) {
>                /* N -> 0, (N > 1) */
> -               entry->funcs = NULL;
> +               entry->probes = NULL;
>                entry->refcount = 0;
>                debug_print_probes(entry);
>                return old;
> @@ -167,12 +173,13 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
>                new = allocate_probes(nr_probes - nr_del + 1);
>                if (new == NULL)
>                        return ERR_PTR(-ENOMEM);
> -               for (i = 0; old[i]; i++)
> -                       if ((probe && old[i] != probe))
> +               for (i = 0; old[i].func; i++)
> +                       if (probe &&
> +                           (old[i].func != probe || old[i].data != data))
>                                new[j++] = old[i];
> -               new[nr_probes - nr_del] = NULL;
> +               new[nr_probes - nr_del].func = NULL;
>                entry->refcount = nr_probes - nr_del;
> -               entry->funcs = new;
> +               entry->probes = new;
>        }
>        debug_print_probes(entry);
>        return old;
> @@ -225,7 +232,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
>        if (!e)
>                return ERR_PTR(-ENOMEM);
>        memcpy(&e->name[0], name, name_len);
> -       e->funcs = NULL;
> +       e->probes = NULL;
>        e->refcount = 0;
>        hlist_add_head(&e->hlist, head);
>        return e;
> @@ -256,7 +263,7 @@ static void set_tracepoint(struct tracepoint_entry **entry,
>         * include/linux/tracepoints.h. A matching smp_read_barrier_depends()
>         * is used.
>         */
> -       rcu_assign_pointer(elem->funcs, (*entry)->funcs);
> +       rcu_assign_pointer(elem->probes, (*entry)->probes);
>        elem->state__imv = active;
> }
>
> @@ -269,7 +276,7 @@ static void set_tracepoint(struct tracepoint_entry **entry,
> static void disable_tracepoint(struct tracepoint *elem)
> {
>        elem->state__imv = 0;
> -       rcu_assign_pointer(elem->funcs, NULL);
> +       rcu_assign_pointer(elem->probes, NULL);
> }
>
> /**
> @@ -280,13 +287,17 @@ static void disable_tracepoint(struct tracepoint *elem)
>  * Updates the probe callback corresponding to a range of tracepoints.
>  */
> void tracepoint_update_probe_range(struct tracepoint *begin,
> -       struct tracepoint *end)
> +                                  struct tracepoint *end)
> {
>        struct tracepoint *iter;
>        struct tracepoint_entry *mark_entry;
>
>        pthread_mutex_lock(&tracepoints_mutex);
>        for (iter = begin; iter < end; iter++) {
> +               if (!iter->name) {
> +                       disable_tracepoint(iter);
> +                       continue;
> +               }
>                mark_entry = get_tracepoint(iter->name);
>                if (mark_entry) {
>                        set_tracepoint(&mark_entry, iter,
> @@ -324,18 +335,19 @@ static void tracepoint_update_probes(void)
> //ust//        module_imv_update();
> }
>
> -static void *tracepoint_add_probe(const char *name, void *probe)
> +static struct probe *
> +tracepoint_add_probe(const char *name, void *probe, void *data)
> {
>        struct tracepoint_entry *entry;
> -       void *old;
> +       struct probe *old;
>
>        entry = get_tracepoint(name);
>        if (!entry) {
>                entry = add_tracepoint(name);
>                if (IS_ERR(entry))
> -                       return entry;
> +                       return (struct probe *)entry;
>        }
> -       old = tracepoint_entry_add_probe(entry, probe);
> +       old = tracepoint_entry_add_probe(entry, probe, data);
>        if (IS_ERR(old) && !entry->refcount)
>                remove_tracepoint(entry);
>        return old;
> @@ -349,12 +361,12 @@ static void *tracepoint_add_probe(const char *name, void *probe)
>  * Returns 0 if ok, error value on error.
>  * The probe address must at least be aligned on the architecture pointer size.
>  */
> -int tracepoint_probe_register(const char *name, void *probe)
> +int tracepoint_probe_register(const char *name, void *probe, void *data)
> {
>        void *old;
>
>        pthread_mutex_lock(&tracepoints_mutex);
> -       old = tracepoint_add_probe(name, probe);
> +       old = tracepoint_add_probe(name, probe, data);
>        pthread_mutex_unlock(&tracepoints_mutex);
>        if (IS_ERR(old))
>                return PTR_ERR(old);
> @@ -365,7 +377,7 @@ int tracepoint_probe_register(const char *name, void *probe)
> }
> //ust// EXPORT_SYMBOL_GPL(tracepoint_probe_register);
>
> -static void *tracepoint_remove_probe(const char *name, void *probe)
> +static void *tracepoint_remove_probe(const char *name, void *probe, void *data)
> {
>        struct tracepoint_entry *entry;
>        void *old;
> @@ -373,7 +385,7 @@ static void *tracepoint_remove_probe(const char *name, void *probe)
>        entry = get_tracepoint(name);
>        if (!entry)
>                return ERR_PTR(-ENOENT);
> -       old = tracepoint_entry_remove_probe(entry, probe);
> +       old = tracepoint_entry_remove_probe(entry, probe, data);
>        if (IS_ERR(old))
>                return old;
>        if (!entry->refcount)
> @@ -385,18 +397,19 @@ static void *tracepoint_remove_probe(const char *name, void *probe)
>  * tracepoint_probe_unregister -  Disconnect a probe from a tracepoint
>  * @name: tracepoint name
>  * @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.
>  */
> -int tracepoint_probe_unregister(const char *name, void *probe)
> +int tracepoint_probe_unregister(const char *name, void *probe, void *data)
> {
>        void *old;
>
>        pthread_mutex_lock(&tracepoints_mutex);
> -       old = tracepoint_remove_probe(name, probe);
> +       old = tracepoint_remove_probe(name, probe, data);
>        pthread_mutex_unlock(&tracepoints_mutex);
>        if (IS_ERR(old))
>                return PTR_ERR(old);
> @@ -427,12 +440,13 @@ static void tracepoint_add_old_probes(void *old)
>  *
>  * caller must call tracepoint_probe_update_all()
>  */
> -int tracepoint_probe_register_noupdate(const char *name, void *probe)
> +int tracepoint_probe_register_noupdate(const char *name, void *probe,
> +                                      void *data)
> {
>        void *old;
>
>        pthread_mutex_lock(&tracepoints_mutex);
> -       old = tracepoint_add_probe(name, probe);
> +       old = tracepoint_add_probe(name, probe, data);
>        if (IS_ERR(old)) {
>                pthread_mutex_unlock(&tracepoints_mutex);
>                return PTR_ERR(old);
> @@ -450,12 +464,13 @@ int tracepoint_probe_register_noupdate(const char *name, void *probe)
>  *
>  * caller must call tracepoint_probe_update_all()
>  */
> -int tracepoint_probe_unregister_noupdate(const char *name, void *probe)
> +int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
> +                                        void *data)
> {
>        void *old;
>
>        pthread_mutex_lock(&tracepoints_mutex);
> -       old = tracepoint_remove_probe(name, probe);
> +       old = tracepoint_remove_probe(name, probe, data);
>        if (IS_ERR(old)) {
>                pthread_mutex_unlock(&tracepoints_mutex);
>                return PTR_ERR(old);
> @@ -662,7 +677,7 @@ int tracepoint_register_lib(struct tracepoint *tracepoints_start, int tracepoint
>        lib_update_tracepoints();
>
>        DBG("just registered a tracepoints section from %p and having %d tracepoints", tracepoints_start, tracepoints_count);
> -
> +
>        return 0;
> }
>
> --
> 1.7.1
>
>




^ permalink raw reply	[flat|nested] 8+ messages in thread

* [ltt-dev] [PATCH 1/2] Add a data pointer to all tracepoint probe callbacks
  2010-09-02  7:03 [ltt-dev] [PATCH 1/2] Add a data pointer to all tracepoint probe callbacks Nils Carlson
  2010-09-02  7:03 ` [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case Nils Carlson
  2010-09-02  9:08 ` [ltt-dev] [PATCH 1/2] Add a data pointer to all tracepoint probe callbacks Nils Carlson
@ 2010-09-02 13:52 ` Mathieu Desnoyers
  2 siblings, 0 replies; 8+ messages in thread
From: Mathieu Desnoyers @ 2010-09-02 13:52 UTC (permalink / raw)


* Nils Carlson (nils.carlson at ericsson.com) wrote:
> RCU now dereferences an array of probe structs containing data pointers and
> function pointers, and passes the data pointer as the first argument to the
> probe.
> 
> Due to this change void prototypes are no longer allowed, which has incurred
> changes to libust-initializer.c .
> 
> This patch also fixes a problem where non-existent tracepoints are present
> in the __tracepoints section and with a name pointer pointing at NULL.

Thanks!

Acked-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>

> ---
>  include/ust/tracepoint.h |   68 +++++++++++++++++++++---------
>  include/ust/ust_trace.h  |    5 +-
>  lgpl-relicensing.txt     |    1 +
>  libust-initializer.c     |    5 +-
>  libust/tracepoint.c      |  103 ++++++++++++++++++++++++++-------------------
>  5 files changed, 113 insertions(+), 69 deletions(-)
> 
> diff --git a/include/ust/tracepoint.h b/include/ust/tracepoint.h
> index 1a91b79..9c7c091 100644
> --- a/include/ust/tracepoint.h
> +++ b/include/ust/tracepoint.h
> @@ -33,10 +33,15 @@
>  struct module;
>  struct tracepoint;
>  
> +struct probe {
> +	void *func;
> +	void *data;
> +};
> +
>  struct tracepoint {
>  	const char *name;		/* Tracepoint name */
>  	DEFINE_IMV(char, state);	/* State. */
> -	void **funcs;
> +	struct probe *probes;
>  } __attribute__((aligned(32)));		/*
>  					 * Aligned on 32 bytes because it is
>  					 * globally visible and gcc happily
> @@ -58,16 +63,20 @@ struct tracepoint {
>   */
>  #define __DO_TRACE(tp, proto, args)					\
>  	do {								\
> -		void **it_func;						\
> +		struct probe *it_probe_ptr;				\
> +		void *it_func;						\
> +		void *__data;						\
>  									\
> -		rcu_read_lock(); /*ust rcu_read_lock_sched_notrace();	*/			\
> -		it_func = rcu_dereference((tp)->funcs);			\
> -		if (it_func) {						\
> +		rcu_read_lock();					\
> +		it_probe_ptr = rcu_dereference((tp)->probes);		\
> +		if (it_probe_ptr) {					\
>  			do {						\
> -				((void(*)(proto))(*it_func))(args);	\
> -			} while (*(++it_func));				\
> +				it_func	= (it_probe_ptr)->func;		\
> +				__data = (it_probe_ptr)->data;		\
> +				((void(*)(proto))(it_func))(args);	\
> +			} while ((++it_probe_ptr)->func);		\
>  		}							\
> -		rcu_read_unlock(); /*ust rcu_read_unlock_sched_notrace(); */			\
> +		rcu_read_unlock();					\
>  	} while (0)
>  
>  #define __CHECK_TRACE(name, generic, proto, args)			\
> @@ -93,37 +102,47 @@ struct tracepoint {
>   * If generic is true, a variable read is used.
>   * If generic is false, immediate values are used.
>   */
> -#define DECLARE_TRACE(name, proto, args)				\
> +#define __DECLARE_TRACE(name, proto, args, data_proto, data_args)	\
>  	extern struct tracepoint __tracepoint_##name;			\
>  	static inline void trace_##name(proto)				\
>  	{								\
> -		__CHECK_TRACE(name, 0, TP_PROTO(proto), TP_ARGS(args));	\
> +		__CHECK_TRACE(name, 0, TP_PROTO(data_proto),		\
> +			      TP_ARGS(data_args));			\
>  	}								\
>  	static inline void _trace_##name(proto)				\
>  	{								\
> -		__CHECK_TRACE(name, 1, TP_PROTO(proto), TP_ARGS(args));	\
> +		__CHECK_TRACE(name, 1, TP_PROTO(data_proto),		\
> +			      TP_ARGS(data_args));			\
>  	}								\
> -	static inline int register_trace_##name(void (*probe)(proto))	\
> +	static inline int						\
> +	register_trace_##name(void (*probe)(data_proto), void *data)	\
>  	{								\
> -		return tracepoint_probe_register(#name, (void *)probe);	\
> +		return tracepoint_probe_register(#name, (void *)probe,	\
> +						 data);			\
> +									\
>  	}								\
> -	static inline int unregister_trace_##name(void (*probe)(proto))	\
> +	static inline int						\
> +	unregister_trace_##name(void (*probe)(data_proto), void *data)	\
>  	{								\
> -		return tracepoint_probe_unregister(#name, (void *)probe);\
> +		return tracepoint_probe_unregister(#name, (void *)probe, \
> +						   data);		\
>  	}
>  
> -#define DEFINE_TRACE(name)						\
> +#define DEFINE_TRACE_FN(name, reg, unreg)					\
>  	static const char __tpstrtab_##name[]				\
>  	__attribute__((section("__tracepoints_strings"))) = #name;	\
>  	struct tracepoint __tracepoint_##name				\
>  	__attribute__((section("__tracepoints"), aligned(32))) =	\
>  		{ __tpstrtab_##name, 0, NULL }
>  
> +#define DEFINE_TRACE(name)						\
> +	DEFINE_TRACE_FN(name, NULL, NULL);
> +
>  extern void tracepoint_update_probe_range(struct tracepoint *begin,
>  	struct tracepoint *end);
>  
>  #else /* !CONFIG_TRACEPOINTS */
> -#define DECLARE_TRACE(name, proto, args)				\
> +#define __DECLARE_TRACE(name, proto, args)				\
>  	static inline void trace_##name(proto)				\
>  	{ }								\
>  	static inline void _trace_##name(proto)				\
> @@ -146,20 +165,27 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin,
>  { }
>  #endif /* CONFIG_TRACEPOINTS */
>  
> +#define DECLARE_TRACE(name, proto, args)			\
> +	__DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),	\
> +			PARAMS(void *__data, proto),		\
> +			PARAMS(__data, args))
> +
>  /*
>   * Connect a probe to a tracepoint.
>   * Internal API, should not be used directly.
>   */
> -extern int tracepoint_probe_register(const char *name, void *probe);
> +extern int tracepoint_probe_register(const char *name, void *probe, void *data);
>  
>  /*
>   * Disconnect a probe from a tracepoint.
>   * Internal API, should not be used directly.
>   */
> -extern int tracepoint_probe_unregister(const char *name, void *probe);
> +extern int tracepoint_probe_unregister(const char *name, void *probe, void *data);
>  
> -extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
> -extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
> +extern int tracepoint_probe_register_noupdate(const char *name, void *probe,
> +					      void *data);
> +extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
> +						void *data);
>  extern void tracepoint_probe_update_all(void);
>  
>  struct tracepoint_iter {
> diff --git a/include/ust/ust_trace.h b/include/ust/ust_trace.h
> index 098c5f8..e1b0257 100644
> --- a/include/ust/ust_trace.h
> +++ b/include/ust/ust_trace.h
> @@ -58,7 +58,7 @@
>  	struct trace_raw_##name {					\
>  		tstruct							\
>  	};								\
> -	static void trace_printf_##name(proto)				\
> +	static void trace_printf_##name(void *dummy, proto)		\
>  	{								\
>  		struct trace_raw_##name entry_struct, *__entry;		\
>  		__entry = &entry_struct;				\
> @@ -68,8 +68,9 @@
>  	}								\
>  	static void __attribute__((constructor)) init_##name()		\
>  	{								\
> +		void *dummy;						\
>  		printf("connecting tracepoint " #name "\n");		\
> -		register_trace_##name(trace_printf_##name);		\
> +		register_trace_##name(trace_printf_##name, dummy);	\
>  	}
>  
>  
> diff --git a/lgpl-relicensing.txt b/lgpl-relicensing.txt
> index 0393851..753f453 100644
> --- a/lgpl-relicensing.txt
> +++ b/lgpl-relicensing.txt
> @@ -10,6 +10,7 @@ Steven Rostedt		       <rostedt at goodmis.org>
>  Frederic Weisbecker	       <fweisbec at gmail.com>
>  Xiao Guangrong		       <xiaogunagrong at cn.fujitsu.com>
>  Josh Stone		       <jistone at redhat.com>
> +Lai Jiangshan		       <laijs at cn.fujitsu.com>
>  
>  The following copyright holders have agreed to LGPLv2.1+ re-licensing
>  of their contributions to linux/include/stringify.h.
> diff --git a/libust-initializer.c b/libust-initializer.c
> index ec39932..390218e 100644
> --- a/libust-initializer.c
> +++ b/libust-initializer.c
> @@ -18,13 +18,14 @@
>   * avoid this.
>   */
>  
> -DECLARE_TRACE(ust_dummytp, TP_PROTO(void), TP_ARGS());
> +DECLARE_TRACE(ust_dummytp, TP_PROTO(int anint), TP_ARGS(anint));
>  DEFINE_TRACE(ust_dummytp);
>  
>  void dummy_libust_initializer_func(void)
>  {
> +	int i;
>  	trace_mark(ust, dummymark, MARK_NOARGS);
> -	trace_ust_dummytp();
> +	trace_ust_dummytp(i);
>  }
>  
>  MARKER_LIB;
> diff --git a/libust/tracepoint.c b/libust/tracepoint.c
> index 6155e29..620a009 100644
> --- a/libust/tracepoint.c
> +++ b/libust/tracepoint.c
> @@ -59,7 +59,7 @@ static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
>   */
>  struct tracepoint_entry {
>  	struct hlist_node hlist;
> -	void **funcs;
> +	struct probe *probes;
>  	int refcount;	/* Number of times armed. 0 if disarmed. */
>  	char name[0];
>  };
> @@ -69,12 +69,12 @@ struct tp_probes {
>  //ust//		struct rcu_head rcu;
>  		struct list_head list;
>  	} u;
> -	void *probes[0];
> +	struct probe probes[0];
>  };
>  
>  static inline void *allocate_probes(int count)
>  {
> -	struct tp_probes *p  = malloc(count * sizeof(void *)
> +	struct tp_probes *p  = malloc(count * sizeof(struct probe)
>  			+ sizeof(struct tp_probes));
>  	return p == NULL ? NULL : p->probes;
>  }
> @@ -99,27 +99,29 @@ static void debug_print_probes(struct tracepoint_entry *entry)
>  {
>  	int i;
>  
> -	if (!tracepoint_debug || !entry->funcs)
> +	if (!tracepoint_debug || !entry->probes)
>  		return;
>  
> -	for (i = 0; entry->funcs[i]; i++)
> -		DBG("Probe %d : %p", i, entry->funcs[i]);
> +	for (i = 0; entry->probes[i].func; i++)
> +		DBG("Probe %d : %p", i, entry->probes[i].func);
>  }
>  
>  static void *
> -tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
> +tracepoint_entry_add_probe(struct tracepoint_entry *entry,
> +			   void *probe, void *data)
>  {
>  	int nr_probes = 0;
> -	void **old, **new;
> +	struct probe *old, *new;
>  
>  	WARN_ON(!probe);
>  
>  	debug_print_probes(entry);
> -	old = entry->funcs;
> +	old = entry->probes;
>  	if (old) {
>  		/* (N -> N+1), (N != 0, 1) probes */
> -		for (nr_probes = 0; old[nr_probes]; nr_probes++)
> -			if (old[nr_probes] == probe)
> +		for (nr_probes = 0; old[nr_probes].func; nr_probes++)
> +			if (old[nr_probes].func == probe &&
> +			    old[nr_probes].data == data)
>  				return ERR_PTR(-EEXIST);
>  	}
>  	/* + 2 : one for new probe, one for NULL func */
> @@ -127,36 +129,40 @@ tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
>  	if (new == NULL)
>  		return ERR_PTR(-ENOMEM);
>  	if (old)
> -		memcpy(new, old, nr_probes * sizeof(void *));
> -	new[nr_probes] = probe;
> -	new[nr_probes + 1] = NULL;
> +		memcpy(new, old, nr_probes * sizeof(struct probe));
> +	new[nr_probes].func = probe;
> +	new[nr_probes].data = data;
> +	new[nr_probes + 1].func = NULL;
>  	entry->refcount = nr_probes + 1;
> -	entry->funcs = new;
> +	entry->probes = new;
>  	debug_print_probes(entry);
>  	return old;
>  }
>  
>  static void *
> -tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
> +tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe,
> +			      void *data)
>  {
>  	int nr_probes = 0, nr_del = 0, i;
> -	void **old, **new;
> +	struct probe *old, *new;
>  
> -	old = entry->funcs;
> +	old = entry->probes;
>  
>  	if (!old)
>  		return ERR_PTR(-ENOENT);
>  
>  	debug_print_probes(entry);
>  	/* (N -> M), (N > 1, M >= 0) probes */
> -	for (nr_probes = 0; old[nr_probes]; nr_probes++) {
> -		if ((!probe || old[nr_probes] == probe))
> +	for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
> +		if ((!probe ||
> +		     old[nr_probes].func == probe &&
> +		     old[nr_probes].data == data))
>  			nr_del++;
>  	}
>  
>  	if (nr_probes - nr_del == 0) {
>  		/* N -> 0, (N > 1) */
> -		entry->funcs = NULL;
> +		entry->probes = NULL;
>  		entry->refcount = 0;
>  		debug_print_probes(entry);
>  		return old;
> @@ -167,12 +173,13 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
>  		new = allocate_probes(nr_probes - nr_del + 1);
>  		if (new == NULL)
>  			return ERR_PTR(-ENOMEM);
> -		for (i = 0; old[i]; i++)
> -			if ((probe && old[i] != probe))
> +		for (i = 0; old[i].func; i++)
> +			if (probe &&
> +			    (old[i].func != probe || old[i].data != data))
>  				new[j++] = old[i];
> -		new[nr_probes - nr_del] = NULL;
> +		new[nr_probes - nr_del].func = NULL;
>  		entry->refcount = nr_probes - nr_del;
> -		entry->funcs = new;
> +		entry->probes = new;
>  	}
>  	debug_print_probes(entry);
>  	return old;
> @@ -225,7 +232,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
>  	if (!e)
>  		return ERR_PTR(-ENOMEM);
>  	memcpy(&e->name[0], name, name_len);
> -	e->funcs = NULL;
> +	e->probes = NULL;
>  	e->refcount = 0;
>  	hlist_add_head(&e->hlist, head);
>  	return e;
> @@ -256,7 +263,7 @@ static void set_tracepoint(struct tracepoint_entry **entry,
>  	 * include/linux/tracepoints.h. A matching smp_read_barrier_depends()
>  	 * is used.
>  	 */
> -	rcu_assign_pointer(elem->funcs, (*entry)->funcs);
> +	rcu_assign_pointer(elem->probes, (*entry)->probes);
>  	elem->state__imv = active;
>  }
>  
> @@ -269,7 +276,7 @@ static void set_tracepoint(struct tracepoint_entry **entry,
>  static void disable_tracepoint(struct tracepoint *elem)
>  {
>  	elem->state__imv = 0;
> -	rcu_assign_pointer(elem->funcs, NULL);
> +	rcu_assign_pointer(elem->probes, NULL);
>  }
>  
>  /**
> @@ -280,13 +287,17 @@ static void disable_tracepoint(struct tracepoint *elem)
>   * Updates the probe callback corresponding to a range of tracepoints.
>   */
>  void tracepoint_update_probe_range(struct tracepoint *begin,
> -	struct tracepoint *end)
> +				   struct tracepoint *end)
>  {
>  	struct tracepoint *iter;
>  	struct tracepoint_entry *mark_entry;
>  
>  	pthread_mutex_lock(&tracepoints_mutex);
>  	for (iter = begin; iter < end; iter++) {
> +		if (!iter->name) {
> +			disable_tracepoint(iter);
> +			continue;
> +		}
>  		mark_entry = get_tracepoint(iter->name);
>  		if (mark_entry) {
>  			set_tracepoint(&mark_entry, iter,
> @@ -324,18 +335,19 @@ static void tracepoint_update_probes(void)
>  //ust//	module_imv_update();
>  }
>  
> -static void *tracepoint_add_probe(const char *name, void *probe)
> +static struct probe *
> +tracepoint_add_probe(const char *name, void *probe, void *data)
>  {
>  	struct tracepoint_entry *entry;
> -	void *old;
> +	struct probe *old;
>  
>  	entry = get_tracepoint(name);
>  	if (!entry) {
>  		entry = add_tracepoint(name);
>  		if (IS_ERR(entry))
> -			return entry;
> +			return (struct probe *)entry;
>  	}
> -	old = tracepoint_entry_add_probe(entry, probe);
> +	old = tracepoint_entry_add_probe(entry, probe, data);
>  	if (IS_ERR(old) && !entry->refcount)
>  		remove_tracepoint(entry);
>  	return old;
> @@ -349,12 +361,12 @@ static void *tracepoint_add_probe(const char *name, void *probe)
>   * Returns 0 if ok, error value on error.
>   * The probe address must at least be aligned on the architecture pointer size.
>   */
> -int tracepoint_probe_register(const char *name, void *probe)
> +int tracepoint_probe_register(const char *name, void *probe, void *data)
>  {
>  	void *old;
>  
>  	pthread_mutex_lock(&tracepoints_mutex);
> -	old = tracepoint_add_probe(name, probe);
> +	old = tracepoint_add_probe(name, probe, data);
>  	pthread_mutex_unlock(&tracepoints_mutex);
>  	if (IS_ERR(old))
>  		return PTR_ERR(old);
> @@ -365,7 +377,7 @@ int tracepoint_probe_register(const char *name, void *probe)
>  }
>  //ust// EXPORT_SYMBOL_GPL(tracepoint_probe_register);
>  
> -static void *tracepoint_remove_probe(const char *name, void *probe)
> +static void *tracepoint_remove_probe(const char *name, void *probe, void *data)
>  {
>  	struct tracepoint_entry *entry;
>  	void *old;
> @@ -373,7 +385,7 @@ static void *tracepoint_remove_probe(const char *name, void *probe)
>  	entry = get_tracepoint(name);
>  	if (!entry)
>  		return ERR_PTR(-ENOENT);
> -	old = tracepoint_entry_remove_probe(entry, probe);
> +	old = tracepoint_entry_remove_probe(entry, probe, data);
>  	if (IS_ERR(old))
>  		return old;
>  	if (!entry->refcount)
> @@ -385,18 +397,19 @@ static void *tracepoint_remove_probe(const char *name, void *probe)
>   * tracepoint_probe_unregister -  Disconnect a probe from a tracepoint
>   * @name: tracepoint name
>   * @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.
>   */
> -int tracepoint_probe_unregister(const char *name, void *probe)
> +int tracepoint_probe_unregister(const char *name, void *probe, void *data)
>  {
>  	void *old;
>  
>  	pthread_mutex_lock(&tracepoints_mutex);
> -	old = tracepoint_remove_probe(name, probe);
> +	old = tracepoint_remove_probe(name, probe, data);
>  	pthread_mutex_unlock(&tracepoints_mutex);
>  	if (IS_ERR(old))
>  		return PTR_ERR(old);
> @@ -427,12 +440,13 @@ static void tracepoint_add_old_probes(void *old)
>   *
>   * caller must call tracepoint_probe_update_all()
>   */
> -int tracepoint_probe_register_noupdate(const char *name, void *probe)
> +int tracepoint_probe_register_noupdate(const char *name, void *probe,
> +				       void *data)
>  {
>  	void *old;
>  
>  	pthread_mutex_lock(&tracepoints_mutex);
> -	old = tracepoint_add_probe(name, probe);
> +	old = tracepoint_add_probe(name, probe, data);
>  	if (IS_ERR(old)) {
>  		pthread_mutex_unlock(&tracepoints_mutex);
>  		return PTR_ERR(old);
> @@ -450,12 +464,13 @@ int tracepoint_probe_register_noupdate(const char *name, void *probe)
>   *
>   * caller must call tracepoint_probe_update_all()
>   */
> -int tracepoint_probe_unregister_noupdate(const char *name, void *probe)
> +int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
> +					 void *data)
>  {
>  	void *old;
>  
>  	pthread_mutex_lock(&tracepoints_mutex);
> -	old = tracepoint_remove_probe(name, probe);
> +	old = tracepoint_remove_probe(name, probe, data);
>  	if (IS_ERR(old)) {
>  		pthread_mutex_unlock(&tracepoints_mutex);
>  		return PTR_ERR(old);
> @@ -662,7 +677,7 @@ int tracepoint_register_lib(struct tracepoint *tracepoints_start, int tracepoint
>  	lib_update_tracepoints();
>  
>  	DBG("just registered a tracepoints section from %p and having %d tracepoints", tracepoints_start, tracepoints_count);
> -	
> +
>  	return 0;
>  }
>  
> -- 
> 1.7.1
> 
> 
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
> 

-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com




^ permalink raw reply	[flat|nested] 8+ messages in thread

* [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case
  2010-09-02  7:03 ` [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case Nils Carlson
@ 2010-09-02 14:09   ` Mathieu Desnoyers
  2010-09-02 14:50     ` Nils Carlson
  0 siblings, 1 reply; 8+ messages in thread
From: Mathieu Desnoyers @ 2010-09-02 14:09 UTC (permalink / raw)


* Nils Carlson (nils.carlson at ericsson.com) wrote:
> Update the test-case for probes to handle a new data pointer
> in the probe function. Also add a new test-case that stress-tests
> probe registration and unregistration.

Does it test reg. of multiple probes on a tracepoint ?

Mathieu

> ---
>  configure.ac                        |    1 +
>  tests/Makefile.am                   |    2 +-
>  tests/hello/hello.c                 |    2 +-
>  tests/hello/tp.c                    |   18 +++++--
>  tests/register_test/Makefile.am     |    5 ++
>  tests/register_test/register_test.c |   97 +++++++++++++++++++++++++++++++++++
>  tests/register_test/tp.h            |   22 ++++++++
>  7 files changed, 141 insertions(+), 6 deletions(-)
>  create mode 100644 tests/register_test/Makefile.am
>  create mode 100644 tests/register_test/register_test.c
>  create mode 100644 tests/register_test/tp.h
> 
> diff --git a/configure.ac b/configure.ac
> index dee974f..10a02e0 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -122,6 +122,7 @@ AC_CONFIG_FILES([
>  	tests/dlopen/Makefile
>  	tests/same_line_marker/Makefile
>  	tests/trace_event/Makefile
> +	tests/register_test/Makefile
>  	libustinstr-malloc/Makefile
>  	libustfork/Makefile
>  	libustd/Makefile
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index ab13cd7..1d31c3f 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -1,3 +1,3 @@
> -SUBDIRS = hello hello2 basic basic_long fork simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event
> +SUBDIRS = hello hello2 basic basic_long fork simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event register_test
>  
>  dist_noinst_SCRIPTS = test_loop runtests trace_matches
> diff --git a/tests/hello/hello.c b/tests/hello/hello.c
> index 86c5c71..8147860 100644
> --- a/tests/hello/hello.c
> +++ b/tests/hello/hello.c
> @@ -26,8 +26,8 @@
>  
>  #include <ust/marker.h>
>  #include "usterr.h"
> -#include "tp.h"
>  #include "tracer.h"
> +#include "tp.h"
>  
>  void inthandler(int sig)
>  {
> diff --git a/tests/hello/tp.c b/tests/hello/tp.c
> index be10615..3a4c6fc 100644
> --- a/tests/hello/tp.c
> +++ b/tests/hello/tp.c
> @@ -19,16 +19,26 @@
>  #include <ust/marker.h>
>  #include "usterr.h"
>  
> +struct hello_trace_struct {
> +	char *message;
> +};
> +
> +struct hello_trace_struct hello_struct = {
> +	.message = "ehlo\n",
> +};
> +
>  DEFINE_TRACE(hello_tptest);
>  
> -void tptest_probe(int anint)
> +void tptest_probe(void *data, int anint)
>  {
> +	struct hello_trace_struct *hello;
> +	hello=(struct hello_trace_struct *)data;
>  	DBG("in tracepoint probe...");
> -	trace_mark(ust, tptest, "anint %d", anint);
> +	printf("this is the message: %s\n", hello->message);
>  }
>  
>  static void __attribute__((constructor)) init()
>  {
> -	DBG("connecting tracepoint...");
> -	register_trace_hello_tptest(tptest_probe);
> +	DBG("connecting tracepoint...\n");
> +	register_trace_hello_tptest(tptest_probe, &hello_struct);
>  }
> diff --git a/tests/register_test/Makefile.am b/tests/register_test/Makefile.am
> new file mode 100644
> index 0000000..ff25e08
> --- /dev/null
> +++ b/tests/register_test/Makefile.am
> @@ -0,0 +1,5 @@
> +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libust
> +
> +noinst_PROGRAMS = register_test
> +register_test_SOURCES = register_test.c tp.h
> +register_test_LDADD = $(top_builddir)/libust/libust.la $(top_builddir)/libust-initializer.o
> diff --git a/tests/register_test/register_test.c b/tests/register_test/register_test.c
> new file mode 100644
> index 0000000..8b65ffb
> --- /dev/null
> +++ b/tests/register_test/register_test.c
> @@ -0,0 +1,97 @@
> +/* Copyright (C) 2010 Nils Carlson
> + *
> + * 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.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
> + */
> +
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <sys/mman.h>
> +#include <stdarg.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <sys/timerfd.h>
> +#include <fcntl.h>
> +#include <signal.h>
> +#include <pthread.h>
> +
> +#include <ust/marker.h>
> +#include "usterr.h"
> +#include "tracer.h"
> +#include "tp.h"
> +
> +DEFINE_TRACE(hello_tptest);
> +
> +
> +struct hello_trace_struct {
> +	char *message;
> +};
> +
> +struct hello_trace_struct hello_struct = {
> +	.message = "ehlo\n",
> +};
> +
> +void tptest_probe(void *data, int anint)
> +{
> +	struct hello_trace_struct *hello;
> +	char message[30];
> +	hello=(struct hello_trace_struct *)data;
> +	//printf("this is the message: %s\n", hello->message);
> +	snprintf(message, 30, "this is the %s\n", hello->message);
> +}
> +
> +
> +#define HELLO_LENGTH 100
> +
> +static void * register_thread_main(void *data)
> +{
> +	int ret, i, j = 0;
> +
> +	struct hello_trace_struct hello[HELLO_LENGTH];
> +
> +	for (i=0; i<HELLO_LENGTH; i++) {
> +		hello[i].message = malloc(6*sizeof(char));
> +		hello[i].message[0] = 'a'+i%25;
> +		memcpy(&hello[i].message[1], "ello", 5);
> +	}
> +
> +	for (i=0; i<1000; i++) {
> +		while (!register_trace_hello_tptest(tptest_probe,
> +						    &hello[j%HELLO_LENGTH])) {
> +			usleep(10);
> +			j++;
> +		}
> +		printf("Registered all\n");
> +		while (!unregister_trace_hello_tptest(tptest_probe,
> +						      &hello[j%HELLO_LENGTH])) {
> +			usleep(10);
> +			j++;
> +		}
> +		printf("Unregistered all\n");
> +	}
> +}
> +
> +
> +int main()
> +{
> +	pthread_t register_thread;
> +	int i;
> +
> +	pthread_create(&register_thread, NULL, register_thread_main, NULL);
> +	for(i=0; i<1000000; i++) {
> +		trace_hello_tptest(i);
> +	}
> +
> +	return 0;
> +}
> diff --git a/tests/register_test/tp.h b/tests/register_test/tp.h
> new file mode 100644
> index 0000000..f34f305
> --- /dev/null
> +++ b/tests/register_test/tp.h
> @@ -0,0 +1,22 @@
> +/* 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
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
> + */
> +
> +#include <ust/tracepoint.h>
> +
> +DECLARE_TRACE(hello_tptest,
> +	      TP_PROTO(int anint),
> +	      TP_ARGS(anint));
> -- 
> 1.7.1
> 
> 
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
> 

-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case
  2010-09-02 14:09   ` Mathieu Desnoyers
@ 2010-09-02 14:50     ` Nils Carlson
  2010-09-02 14:56       ` Mathieu Desnoyers
  0 siblings, 1 reply; 8+ messages in thread
From: Nils Carlson @ 2010-09-02 14:50 UTC (permalink / raw)


Jep, exactly that, multiple probes with different data. Didn't try adding with different functions. 

-----Original Message-----
From: Mathieu Desnoyers [mailto:compudj@krystal.dyndns.org] 
Sent: den 2 september 2010 16:09
To: Nils Carlson
Cc: ltt-dev at lists.casi.polymtl.ca
Subject: Re: [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case

* Nils Carlson (nils.carlson at ericsson.com) wrote:
> Update the test-case for probes to handle a new data pointer in the 
> probe function. Also add a new test-case that stress-tests probe 
> registration and unregistration.

Does it test reg. of multiple probes on a tracepoint ?

Mathieu

> ---
>  configure.ac                        |    1 +
>  tests/Makefile.am                   |    2 +-
>  tests/hello/hello.c                 |    2 +-
>  tests/hello/tp.c                    |   18 +++++--
>  tests/register_test/Makefile.am     |    5 ++
>  tests/register_test/register_test.c |   97 +++++++++++++++++++++++++++++++++++
>  tests/register_test/tp.h            |   22 ++++++++
>  7 files changed, 141 insertions(+), 6 deletions(-)  create mode 
> 100644 tests/register_test/Makefile.am  create mode 100644 
> tests/register_test/register_test.c
>  create mode 100644 tests/register_test/tp.h
> 
> diff --git a/configure.ac b/configure.ac index dee974f..10a02e0 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -122,6 +122,7 @@ AC_CONFIG_FILES([
>  	tests/dlopen/Makefile
>  	tests/same_line_marker/Makefile
>  	tests/trace_event/Makefile
> +	tests/register_test/Makefile
>  	libustinstr-malloc/Makefile
>  	libustfork/Makefile
>  	libustd/Makefile
> diff --git a/tests/Makefile.am b/tests/Makefile.am index 
> ab13cd7..1d31c3f 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -1,3 +1,3 @@
> -SUBDIRS = hello hello2 basic basic_long fork simple_include snprintf 
> test-nevents test-libustinstr-malloc dlopen same_line_marker 
> trace_event
> +SUBDIRS = hello hello2 basic basic_long fork simple_include snprintf 
> +test-nevents test-libustinstr-malloc dlopen same_line_marker 
> +trace_event register_test
>  
>  dist_noinst_SCRIPTS = test_loop runtests trace_matches diff --git 
> a/tests/hello/hello.c b/tests/hello/hello.c index 86c5c71..8147860 
> 100644
> --- a/tests/hello/hello.c
> +++ b/tests/hello/hello.c
> @@ -26,8 +26,8 @@
>  
>  #include <ust/marker.h>
>  #include "usterr.h"
> -#include "tp.h"
>  #include "tracer.h"
> +#include "tp.h"
>  
>  void inthandler(int sig)
>  {
> diff --git a/tests/hello/tp.c b/tests/hello/tp.c index 
> be10615..3a4c6fc 100644
> --- a/tests/hello/tp.c
> +++ b/tests/hello/tp.c
> @@ -19,16 +19,26 @@
>  #include <ust/marker.h>
>  #include "usterr.h"
>  
> +struct hello_trace_struct {
> +	char *message;
> +};
> +
> +struct hello_trace_struct hello_struct = {
> +	.message = "ehlo\n",
> +};
> +
>  DEFINE_TRACE(hello_tptest);
>  
> -void tptest_probe(int anint)
> +void tptest_probe(void *data, int anint)
>  {
> +	struct hello_trace_struct *hello;
> +	hello=(struct hello_trace_struct *)data;
>  	DBG("in tracepoint probe...");
> -	trace_mark(ust, tptest, "anint %d", anint);
> +	printf("this is the message: %s\n", hello->message);
>  }
>  
>  static void __attribute__((constructor)) init()  {
> -	DBG("connecting tracepoint...");
> -	register_trace_hello_tptest(tptest_probe);
> +	DBG("connecting tracepoint...\n");
> +	register_trace_hello_tptest(tptest_probe, &hello_struct);
>  }
> diff --git a/tests/register_test/Makefile.am 
> b/tests/register_test/Makefile.am new file mode 100644 index 
> 0000000..ff25e08
> --- /dev/null
> +++ b/tests/register_test/Makefile.am
> @@ -0,0 +1,5 @@
> +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libust
> +
> +noinst_PROGRAMS = register_test
> +register_test_SOURCES = register_test.c tp.h register_test_LDADD = 
> +$(top_builddir)/libust/libust.la $(top_builddir)/libust-initializer.o
> diff --git a/tests/register_test/register_test.c 
> b/tests/register_test/register_test.c
> new file mode 100644
> index 0000000..8b65ffb
> --- /dev/null
> +++ b/tests/register_test/register_test.c
> @@ -0,0 +1,97 @@
> +/* Copyright (C) 2010 Nils Carlson
> + *
> + * 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.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free 
> +Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
> +02110-1301 USA  */
> +
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <sys/mman.h>
> +#include <stdarg.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <sys/timerfd.h>
> +#include <fcntl.h>
> +#include <signal.h>
> +#include <pthread.h>
> +
> +#include <ust/marker.h>
> +#include "usterr.h"
> +#include "tracer.h"
> +#include "tp.h"
> +
> +DEFINE_TRACE(hello_tptest);
> +
> +
> +struct hello_trace_struct {
> +	char *message;
> +};
> +
> +struct hello_trace_struct hello_struct = {
> +	.message = "ehlo\n",
> +};
> +
> +void tptest_probe(void *data, int anint) {
> +	struct hello_trace_struct *hello;
> +	char message[30];
> +	hello=(struct hello_trace_struct *)data;
> +	//printf("this is the message: %s\n", hello->message);
> +	snprintf(message, 30, "this is the %s\n", hello->message); }
> +
> +
> +#define HELLO_LENGTH 100
> +
> +static void * register_thread_main(void *data) {
> +	int ret, i, j = 0;
> +
> +	struct hello_trace_struct hello[HELLO_LENGTH];
> +
> +	for (i=0; i<HELLO_LENGTH; i++) {
> +		hello[i].message = malloc(6*sizeof(char));
> +		hello[i].message[0] = 'a'+i%25;
> +		memcpy(&hello[i].message[1], "ello", 5);
> +	}
> +
> +	for (i=0; i<1000; i++) {
> +		while (!register_trace_hello_tptest(tptest_probe,
> +						    &hello[j%HELLO_LENGTH])) {
> +			usleep(10);
> +			j++;
> +		}
> +		printf("Registered all\n");
> +		while (!unregister_trace_hello_tptest(tptest_probe,
> +						      &hello[j%HELLO_LENGTH])) {
> +			usleep(10);
> +			j++;
> +		}
> +		printf("Unregistered all\n");
> +	}
> +}
> +
> +
> +int main()
> +{
> +	pthread_t register_thread;
> +	int i;
> +
> +	pthread_create(&register_thread, NULL, register_thread_main, NULL);
> +	for(i=0; i<1000000; i++) {
> +		trace_hello_tptest(i);
> +	}
> +
> +	return 0;
> +}
> diff --git a/tests/register_test/tp.h b/tests/register_test/tp.h new 
> file mode 100644 index 0000000..f34f305
> --- /dev/null
> +++ b/tests/register_test/tp.h
> @@ -0,0 +1,22 @@
> +/* 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
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free 
> +Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
> +02110-1301 USA  */
> +
> +#include <ust/tracepoint.h>
> +
> +DECLARE_TRACE(hello_tptest,
> +	      TP_PROTO(int anint),
> +	      TP_ARGS(anint));
> --
> 1.7.1
> 
> 
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
> 

--
Mathieu Desnoyers
Operating System Efficiency R&D Consultant EfficiOS Inc.
http://www.efficios.com




^ permalink raw reply	[flat|nested] 8+ messages in thread

* [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case
  2010-09-02 14:50     ` Nils Carlson
@ 2010-09-02 14:56       ` Mathieu Desnoyers
  0 siblings, 0 replies; 8+ messages in thread
From: Mathieu Desnoyers @ 2010-09-02 14:56 UTC (permalink / raw)


* Nils Carlson (nils.carlson at ericsson.com) wrote:
> Jep, exactly that, multiple probes with different data. Didn't try
> adding with different functions. 

Could be good to add the "multiple functions" test case eventually. But
so far, this patch looks good.

Acked-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>

> 
> -----Original Message-----
> From: Mathieu Desnoyers [mailto:compudj@krystal.dyndns.org] 
> Sent: den 2 september 2010 16:09
> To: Nils Carlson
> Cc: ltt-dev at lists.casi.polymtl.ca
> Subject: Re: [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case
> 
> * Nils Carlson (nils.carlson at ericsson.com) wrote:
> > Update the test-case for probes to handle a new data pointer in the 
> > probe function. Also add a new test-case that stress-tests probe 
> > registration and unregistration.
> 
> Does it test reg. of multiple probes on a tracepoint ?
> 
> Mathieu
> 
> > ---
> >  configure.ac                        |    1 +
> >  tests/Makefile.am                   |    2 +-
> >  tests/hello/hello.c                 |    2 +-
> >  tests/hello/tp.c                    |   18 +++++--
> >  tests/register_test/Makefile.am     |    5 ++
> >  tests/register_test/register_test.c |   97 +++++++++++++++++++++++++++++++++++
> >  tests/register_test/tp.h            |   22 ++++++++
> >  7 files changed, 141 insertions(+), 6 deletions(-)  create mode 
> > 100644 tests/register_test/Makefile.am  create mode 100644 
> > tests/register_test/register_test.c
> >  create mode 100644 tests/register_test/tp.h
> > 
> > diff --git a/configure.ac b/configure.ac index dee974f..10a02e0 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -122,6 +122,7 @@ AC_CONFIG_FILES([
> >  	tests/dlopen/Makefile
> >  	tests/same_line_marker/Makefile
> >  	tests/trace_event/Makefile
> > +	tests/register_test/Makefile
> >  	libustinstr-malloc/Makefile
> >  	libustfork/Makefile
> >  	libustd/Makefile
> > diff --git a/tests/Makefile.am b/tests/Makefile.am index 
> > ab13cd7..1d31c3f 100644
> > --- a/tests/Makefile.am
> > +++ b/tests/Makefile.am
> > @@ -1,3 +1,3 @@
> > -SUBDIRS = hello hello2 basic basic_long fork simple_include snprintf 
> > test-nevents test-libustinstr-malloc dlopen same_line_marker 
> > trace_event
> > +SUBDIRS = hello hello2 basic basic_long fork simple_include snprintf 
> > +test-nevents test-libustinstr-malloc dlopen same_line_marker 
> > +trace_event register_test
> >  
> >  dist_noinst_SCRIPTS = test_loop runtests trace_matches diff --git 
> > a/tests/hello/hello.c b/tests/hello/hello.c index 86c5c71..8147860 
> > 100644
> > --- a/tests/hello/hello.c
> > +++ b/tests/hello/hello.c
> > @@ -26,8 +26,8 @@
> >  
> >  #include <ust/marker.h>
> >  #include "usterr.h"
> > -#include "tp.h"
> >  #include "tracer.h"
> > +#include "tp.h"
> >  
> >  void inthandler(int sig)
> >  {
> > diff --git a/tests/hello/tp.c b/tests/hello/tp.c index 
> > be10615..3a4c6fc 100644
> > --- a/tests/hello/tp.c
> > +++ b/tests/hello/tp.c
> > @@ -19,16 +19,26 @@
> >  #include <ust/marker.h>
> >  #include "usterr.h"
> >  
> > +struct hello_trace_struct {
> > +	char *message;
> > +};
> > +
> > +struct hello_trace_struct hello_struct = {
> > +	.message = "ehlo\n",
> > +};
> > +
> >  DEFINE_TRACE(hello_tptest);
> >  
> > -void tptest_probe(int anint)
> > +void tptest_probe(void *data, int anint)
> >  {
> > +	struct hello_trace_struct *hello;
> > +	hello=(struct hello_trace_struct *)data;
> >  	DBG("in tracepoint probe...");
> > -	trace_mark(ust, tptest, "anint %d", anint);
> > +	printf("this is the message: %s\n", hello->message);
> >  }
> >  
> >  static void __attribute__((constructor)) init()  {
> > -	DBG("connecting tracepoint...");
> > -	register_trace_hello_tptest(tptest_probe);
> > +	DBG("connecting tracepoint...\n");
> > +	register_trace_hello_tptest(tptest_probe, &hello_struct);
> >  }
> > diff --git a/tests/register_test/Makefile.am 
> > b/tests/register_test/Makefile.am new file mode 100644 index 
> > 0000000..ff25e08
> > --- /dev/null
> > +++ b/tests/register_test/Makefile.am
> > @@ -0,0 +1,5 @@
> > +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libust
> > +
> > +noinst_PROGRAMS = register_test
> > +register_test_SOURCES = register_test.c tp.h register_test_LDADD = 
> > +$(top_builddir)/libust/libust.la $(top_builddir)/libust-initializer.o
> > diff --git a/tests/register_test/register_test.c 
> > b/tests/register_test/register_test.c
> > new file mode 100644
> > index 0000000..8b65ffb
> > --- /dev/null
> > +++ b/tests/register_test/register_test.c
> > @@ -0,0 +1,97 @@
> > +/* Copyright (C) 2010 Nils Carlson
> > + *
> > + * 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.
> > + *
> > + * This library is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General Public
> > + * License along with this library; if not, write to the Free 
> > +Software
> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
> > +02110-1301 USA  */
> > +
> > +#include <stdio.h>
> > +#include <unistd.h>
> > +#include <sys/mman.h>
> > +#include <stdarg.h>
> > +#include <sys/types.h>
> > +#include <sys/stat.h>
> > +#include <sys/timerfd.h>
> > +#include <fcntl.h>
> > +#include <signal.h>
> > +#include <pthread.h>
> > +
> > +#include <ust/marker.h>
> > +#include "usterr.h"
> > +#include "tracer.h"
> > +#include "tp.h"
> > +
> > +DEFINE_TRACE(hello_tptest);
> > +
> > +
> > +struct hello_trace_struct {
> > +	char *message;
> > +};
> > +
> > +struct hello_trace_struct hello_struct = {
> > +	.message = "ehlo\n",
> > +};
> > +
> > +void tptest_probe(void *data, int anint) {
> > +	struct hello_trace_struct *hello;
> > +	char message[30];
> > +	hello=(struct hello_trace_struct *)data;
> > +	//printf("this is the message: %s\n", hello->message);
> > +	snprintf(message, 30, "this is the %s\n", hello->message); }
> > +
> > +
> > +#define HELLO_LENGTH 100
> > +
> > +static void * register_thread_main(void *data) {
> > +	int ret, i, j = 0;
> > +
> > +	struct hello_trace_struct hello[HELLO_LENGTH];
> > +
> > +	for (i=0; i<HELLO_LENGTH; i++) {
> > +		hello[i].message = malloc(6*sizeof(char));
> > +		hello[i].message[0] = 'a'+i%25;
> > +		memcpy(&hello[i].message[1], "ello", 5);
> > +	}
> > +
> > +	for (i=0; i<1000; i++) {
> > +		while (!register_trace_hello_tptest(tptest_probe,
> > +						    &hello[j%HELLO_LENGTH])) {
> > +			usleep(10);
> > +			j++;
> > +		}
> > +		printf("Registered all\n");
> > +		while (!unregister_trace_hello_tptest(tptest_probe,
> > +						      &hello[j%HELLO_LENGTH])) {
> > +			usleep(10);
> > +			j++;
> > +		}
> > +		printf("Unregistered all\n");
> > +	}
> > +}
> > +
> > +
> > +int main()
> > +{
> > +	pthread_t register_thread;
> > +	int i;
> > +
> > +	pthread_create(&register_thread, NULL, register_thread_main, NULL);
> > +	for(i=0; i<1000000; i++) {
> > +		trace_hello_tptest(i);
> > +	}
> > +
> > +	return 0;
> > +}
> > diff --git a/tests/register_test/tp.h b/tests/register_test/tp.h new 
> > file mode 100644 index 0000000..f34f305
> > --- /dev/null
> > +++ b/tests/register_test/tp.h
> > @@ -0,0 +1,22 @@
> > +/* 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
> > + * License as published by the Free Software Foundation; either
> > + * version 2.1 of the License, or (at your option) any later version.
> > + *
> > + * This library is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General Public
> > + * License along with this library; if not, write to the Free 
> > +Software
> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
> > +02110-1301 USA  */
> > +
> > +#include <ust/tracepoint.h>
> > +
> > +DECLARE_TRACE(hello_tptest,
> > +	      TP_PROTO(int anint),
> > +	      TP_ARGS(anint));
> > --
> > 1.7.1
> > 
> > 
> > _______________________________________________
> > ltt-dev mailing list
> > ltt-dev at lists.casi.polymtl.ca
> > http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
> > 
> 
> --
> Mathieu Desnoyers
> Operating System Efficiency R&D Consultant EfficiOS Inc.
> http://www.efficios.com
> 

-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com




^ permalink raw reply	[flat|nested] 8+ messages in thread

* [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case
@ 2010-08-31 13:53 Nils Carlson
  0 siblings, 0 replies; 8+ messages in thread
From: Nils Carlson @ 2010-08-31 13:53 UTC (permalink / raw)


Update the test-case for probes to handle a new data pointer
in the probe function. Also add a new test-case that stress-tests
probe registration and unregistration.
---
 configure.ac                        |    1 +
 tests/Makefile.am                   |    2 +-
 tests/hello/hello.c                 |    2 +-
 tests/hello/tp.c                    |   18 +++++--
 tests/register_test/Makefile.am     |    5 ++
 tests/register_test/register_test.c |   97 +++++++++++++++++++++++++++++++++++
 tests/register_test/tp.h            |   22 ++++++++
 7 files changed, 141 insertions(+), 6 deletions(-)
 create mode 100644 tests/register_test/Makefile.am
 create mode 100644 tests/register_test/register_test.c
 create mode 100644 tests/register_test/tp.h

diff --git a/configure.ac b/configure.ac
index dee974f..10a02e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -122,6 +122,7 @@ AC_CONFIG_FILES([
 	tests/dlopen/Makefile
 	tests/same_line_marker/Makefile
 	tests/trace_event/Makefile
+	tests/register_test/Makefile
 	libustinstr-malloc/Makefile
 	libustfork/Makefile
 	libustd/Makefile
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ab13cd7..1d31c3f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = hello hello2 basic basic_long fork simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event
+SUBDIRS = hello hello2 basic basic_long fork simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event register_test
 
 dist_noinst_SCRIPTS = test_loop runtests trace_matches
diff --git a/tests/hello/hello.c b/tests/hello/hello.c
index 86c5c71..8147860 100644
--- a/tests/hello/hello.c
+++ b/tests/hello/hello.c
@@ -26,8 +26,8 @@
 
 #include <ust/marker.h>
 #include "usterr.h"
-#include "tp.h"
 #include "tracer.h"
+#include "tp.h"
 
 void inthandler(int sig)
 {
diff --git a/tests/hello/tp.c b/tests/hello/tp.c
index be10615..3a4c6fc 100644
--- a/tests/hello/tp.c
+++ b/tests/hello/tp.c
@@ -19,16 +19,26 @@
 #include <ust/marker.h>
 #include "usterr.h"
 
+struct hello_trace_struct {
+	char *message;
+};
+
+struct hello_trace_struct hello_struct = {
+	.message = "ehlo\n",
+};
+
 DEFINE_TRACE(hello_tptest);
 
-void tptest_probe(int anint)
+void tptest_probe(void *data, int anint)
 {
+	struct hello_trace_struct *hello;
+	hello=(struct hello_trace_struct *)data;
 	DBG("in tracepoint probe...");
-	trace_mark(ust, tptest, "anint %d", anint);
+	printf("this is the message: %s\n", hello->message);
 }
 
 static void __attribute__((constructor)) init()
 {
-	DBG("connecting tracepoint...");
-	register_trace_hello_tptest(tptest_probe);
+	DBG("connecting tracepoint...\n");
+	register_trace_hello_tptest(tptest_probe, &hello_struct);
 }
diff --git a/tests/register_test/Makefile.am b/tests/register_test/Makefile.am
new file mode 100644
index 0000000..ff25e08
--- /dev/null
+++ b/tests/register_test/Makefile.am
@@ -0,0 +1,5 @@
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libust
+
+noinst_PROGRAMS = register_test
+register_test_SOURCES = register_test.c tp.h
+register_test_LDADD = $(top_builddir)/libust/libust.la $(top_builddir)/libust-initializer.o
diff --git a/tests/register_test/register_test.c b/tests/register_test/register_test.c
new file mode 100644
index 0000000..8b65ffb
--- /dev/null
+++ b/tests/register_test/register_test.c
@@ -0,0 +1,97 @@
+/* Copyright (C) 2010 Nils Carlson
+ *
+ * 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/timerfd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pthread.h>
+
+#include <ust/marker.h>
+#include "usterr.h"
+#include "tracer.h"
+#include "tp.h"
+
+DEFINE_TRACE(hello_tptest);
+
+
+struct hello_trace_struct {
+	char *message;
+};
+
+struct hello_trace_struct hello_struct = {
+	.message = "ehlo\n",
+};
+
+void tptest_probe(void *data, int anint)
+{
+	struct hello_trace_struct *hello;
+	char message[30];
+	hello=(struct hello_trace_struct *)data;
+	//printf("this is the message: %s\n", hello->message);
+	snprintf(message, 30, "this is the %s\n", hello->message);
+}
+
+
+#define HELLO_LENGTH 100
+
+static void * register_thread_main(void *data)
+{
+	int ret, i, j = 0;
+
+	struct hello_trace_struct hello[HELLO_LENGTH];
+
+	for (i=0; i<HELLO_LENGTH; i++) {
+		hello[i].message = malloc(6*sizeof(char));
+		hello[i].message[0] = 'a'+i%25;
+		memcpy(&hello[i].message[1], "ello", 5);
+	}
+
+	for (i=0; i<1000; i++) {
+		while (!register_trace_hello_tptest(tptest_probe,
+						    &hello[j%HELLO_LENGTH])) {
+			usleep(10);
+			j++;
+		}
+		printf("Registered all\n");
+		while (!unregister_trace_hello_tptest(tptest_probe,
+						      &hello[j%HELLO_LENGTH])) {
+			usleep(10);
+			j++;
+		}
+		printf("Unregistered all\n");
+	}
+}
+
+
+int main()
+{
+	pthread_t register_thread;
+	int i;
+
+	pthread_create(&register_thread, NULL, register_thread_main, NULL);
+	for(i=0; i<1000000; i++) {
+		trace_hello_tptest(i);
+	}
+
+	return 0;
+}
diff --git a/tests/register_test/tp.h b/tests/register_test/tp.h
new file mode 100644
index 0000000..f34f305
--- /dev/null
+++ b/tests/register_test/tp.h
@@ -0,0 +1,22 @@
+/* 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <ust/tracepoint.h>
+
+DECLARE_TRACE(hello_tptest,
+	      TP_PROTO(int anint),
+	      TP_ARGS(anint));
-- 
1.7.1





^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-09-02 14:56 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-02  7:03 [ltt-dev] [PATCH 1/2] Add a data pointer to all tracepoint probe callbacks Nils Carlson
2010-09-02  7:03 ` [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case Nils Carlson
2010-09-02 14:09   ` Mathieu Desnoyers
2010-09-02 14:50     ` Nils Carlson
2010-09-02 14:56       ` Mathieu Desnoyers
2010-09-02  9:08 ` [ltt-dev] [PATCH 1/2] Add a data pointer to all tracepoint probe callbacks Nils Carlson
2010-09-02 13:52 ` Mathieu Desnoyers
  -- strict thread matches above, loose matches on Subject: below --
2010-08-31 13:53 [ltt-dev] [PATCH 2/2] Update test-case for tracepoints and add a new test-case Nils Carlson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox