add examples
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 6 Apr 2007 23:00:47 +0000 (23:00 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 6 Apr 2007 23:00:47 +0000 (23:00 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@2482 04897980-b3bd-0310-b5e0-8ef037075253

tests/kernel/Makefile
tests/kernel/marker-example.c [new file with mode: 0644]
tests/kernel/probe-example.c [new file with mode: 0644]
tests/kernel/test-compact.c
tests/kernel/trace-event.h

index 01259f55f200b1e0888e4bd14a80e9e2d6a50b1e..5b9431634e534151d2b737424659a78b6b6d7ebf 100644 (file)
@@ -3,13 +3,17 @@ ifneq ($(CONFIG_LTT),)
        #obj-m += ltt-facility-loader-tests.o
 #      #obj-m += test-time-probe.o 
        #obj-m += test-time-probe2.o 
-       #obj-m += test-compact.o 
+       obj-m += test-compact.o 
 #      obj-m += ltt-facility-loader-compact.o
 #      obj-m += test-instrument-size-small.o
 #      obj-m += test-instrument-size-med.o
 #      obj-m += test-instrument-size-big.o
 #      obj-m += test-printk-effect.o
+       obj-m += ltt-probe-tests.o
+       obj-m += test-time-probe3.o
 endif
+       obj-m += probe-example.o
+       obj-m += marker-example.o
 #      obj-m += test-async-tsc.o
        obj-m += test-tsc-sync.o
        obj-m += test-tsc.o
diff --git a/tests/kernel/marker-example.c b/tests/kernel/marker-example.c
new file mode 100644 (file)
index 0000000..9ae10d9
--- /dev/null
@@ -0,0 +1,56 @@
+/* marker-example.c
+ *
+ * Executes a marker when /proc/marker-example is opened.
+ *
+ * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/marker.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+
+struct proc_dir_entry *pentry_example = NULL;
+
+static int my_open(struct inode *inode, struct file *file)
+{
+       int i;
+
+       MARK(subsystem_event, "%d %s %*.*r", 123, "example string",
+               sizeof(current), __alignof__(current), current);
+       for (i=0; i<10; i++) {
+               MARK(subsystem_eventb, MARK_NOARGS);
+       }
+       return -EPERM;
+}
+
+static struct file_operations mark_ops = {
+       .open = my_open,
+};
+
+static int example_init(void)
+{
+       printk(KERN_ALERT "example init\n");
+       pentry_example = create_proc_entry("marker-example", 0444, NULL);
+       if (pentry_example)
+               pentry_example->proc_fops = &mark_ops;
+       else
+               return -EPERM;
+       return 0;
+}
+
+static void example_exit(void)
+{
+       printk(KERN_ALERT "example exit\n");
+       remove_proc_entry("marker-example", NULL);
+}
+
+module_init(example_init)
+module_exit(example_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit example");
diff --git a/tests/kernel/probe-example.c b/tests/kernel/probe-example.c
new file mode 100644 (file)
index 0000000..5e7093c
--- /dev/null
@@ -0,0 +1,102 @@
+/* probe-example.c
+ *
+ * Connects a two functions to marker call sites.
+ *
+ * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/marker.h>
+#include <asm/atomic.h>
+
+#define NUM_PROBES (sizeof(probe_array) / sizeof(struct probe_data))
+
+struct probe_data {
+       const char *name;
+       const char *format;
+       marker_probe_func *probe_func;
+};
+
+void probe_subsystem_event(const struct __mark_marker_c *mdata,
+               const char *format, ...)
+{
+       va_list ap;
+       /* Declare args */
+       unsigned int value;
+       const char *mystr;
+       int task_size, task_alignment;
+       struct task_struct *task;
+
+       /* Assign args */
+       va_start(ap, format);
+       value = va_arg(ap, typeof(value));
+       mystr = va_arg(ap, typeof(mystr));
+       task_size = va_arg(ap, typeof(task_size));
+       task_alignment = va_arg(ap, typeof(task_alignment));
+       task = va_arg(ap, typeof(task));
+
+       /* Call printk */
+       printk("Value %u, string %s, current ptr %p\n", value, mystr, current);
+
+       /* or count, check rights, serialize data in a buffer */
+
+       va_end(ap);
+}
+
+atomic_t eventb_count = ATOMIC_INIT(0);
+
+void probe_subsystem_eventb(const struct __mark_marker_c *mdata,
+       const char *format, ...)
+{
+       /* Increment counter */
+       atomic_inc(&eventb_count);
+}
+
+static struct probe_data probe_array[] =
+{
+       {       .name = "subsystem_event",
+               .format = "%d %s %*.*r",
+               .probe_func = probe_subsystem_event },
+       {       .name = "subsystem_eventb",
+               .format = MARK_NOARGS,
+               .probe_func = probe_subsystem_eventb },
+};
+
+static int __init probe_init(void)
+{
+       int result;
+       uint8_t eID;
+
+       for (eID = 0; eID < NUM_PROBES; eID++) {
+               result = marker_set_probe(probe_array[eID].name,
+                               probe_array[eID].format,
+                               probe_array[eID].probe_func, &probe_array[eID]);
+               if (!result)
+                       printk(KERN_INFO "Unable to register probe %s\n",
+                               probe_array[eID].name);
+       }
+       return 0;
+}
+
+static void __exit probe_fini(void)
+{
+       uint8_t eID;
+
+       for (eID = 0; eID < NUM_PROBES; eID++) {
+               marker_remove_probe(probe_array[eID].name);
+       }
+       synchronize_sched();    /* Wait for probes to finish */
+       printk("Number of event b : %u\n", atomic_read(&eventb_count));
+}
+
+module_init(probe_init);
+module_exit(probe_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("SUBSYSTEM Probe");
index 5aed22fdf272f8506d3ce44c945fc127948f2e9f..d3f4472e17012b1cfae553aa68a5f93ec1033631 100644 (file)
@@ -4,14 +4,14 @@
  */
 
 
-#include <ltt/ltt-facility-select-compact.h>
-#include <ltt/ltt-facility-compact.h>
-
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/ltt-core.h>
+#include <ltt/ltt-tracer.h>
 #include <linux/timex.h>
+#include <linux/marker.h>
+#include <linux/proc_fs.h>
 
+struct proc_dir_entry *pentry_test = NULL;
 
 /* Event logged : 4 bytes. Let's use 1MB of
  * buffers. 1MB / 4bytes = 262144 (plus heartbeats). So, if we write 20000
 
 #define NR_LOOPS 20000
 
-static int ltt_test_init(void)
+static int my_open(struct inode *inode, struct file *file)
 {
        unsigned int i;
        cycles_t time1, time2, time;
        cycles_t tot_time = 0;
        unsigned long flags;
-       printk(KERN_ALERT "test init\n");
        
+       printk(KERN_ALERT "test begin\n");
        local_irq_save(flags);
        time1 = get_cycles();
        for(i=0; i<NR_LOOPS; i++) {
-               trace_compact_event_a();
-               trace_compact_event_c(get_cycles());
-               trace_compact_event_d(0xFF);
-               trace_compact_event_e(0xFF, 0xFAFAFA);
+               _MARK(_MF_DEFAULT | ltt_flag_mask(LTT_FLAG_COMPACT),
+                       compact_event_a, MARK_NOARGS);
+               _MARK(_MF_DEFAULT | ltt_flag_mask(LTT_FLAG_COMPACT),
+                       compact_event_b, "%4b", 0xFFFF);
+               _MARK(_MF_DEFAULT | ltt_flag_mask(LTT_FLAG_COMPACT),
+                       compact_event_c, "%8b", 0xFFFFFFFFULL);
+               _MARK(_MF_DEFAULT | ltt_flag_mask(LTT_FLAG_COMPACT)
+                       | ltt_flag_mask(LTT_FLAG_COMPACT_DATA),
+                       compact_event_d, MARK_NOARGS, 0xFFFF);
+               _MARK(_MF_DEFAULT | ltt_flag_mask(LTT_FLAG_COMPACT)
+                       | ltt_flag_mask(LTT_FLAG_COMPACT_DATA),
+                       compact_event_e, "%8b", 0xFFFF, 0xFFFFFFFFULL);
        }
        time2 = get_cycles();
        time = time2 - time1;
@@ -45,13 +53,28 @@ static int ltt_test_init(void)
        printk(KERN_ALERT "total time : %llu\n", tot_time);
 
        printk(KERN_ALERT "test end\n");
-       
-       return -EAGAIN; /* Fail will directly unload the module */
+       return -EPERM;
+}
+
+static struct file_operations mark_ops = {
+       .open = my_open,
+};
+
+static int ltt_test_init(void)
+{
+       printk(KERN_ALERT "test init\n");
+       pentry_test = create_proc_entry("test-compact", 0444, NULL);
+       if (pentry_test)
+               pentry_test->proc_fops = &mark_ops;
+       else
+               return -EPERM;
+       return 0;
 }
 
 static void ltt_test_exit(void)
 {
        printk(KERN_ALERT "test exit\n");
+       remove_proc_entry("test-compact", NULL);
 }
 
 module_init(ltt_test_init)
index 1f2eccac3f6650f7dce095f4079d26e78493015c..bf5d9e5be84b87c9ca591cbf62cedd73962a443c 100644 (file)
@@ -1,5 +1,8 @@
 #include <stdarg.h>
 
+/* Maximum number of callbacks per marker */
+#define LTT_NR_CALLBACKS       10
+
 /* LTT flags
  *
  * LTT_FLAG_TRACE : first arg contains trace to write into.
@@ -18,7 +21,8 @@
 #define LTT_FLAG_FORCE         (1 << _LTT_FLAG_FORCE)
 
 
-char *(*ltt_serialize_cb)(char *buffer, const char *fmt, va_list args);
+char *(*ltt_serialize_cb)(char *buffer, int *cb_args,
+                       const char *fmt, va_list args);
 
 
 static int skip_atoi(const char **s)
@@ -32,10 +36,13 @@ static int skip_atoi(const char **s)
 
 /* Inspired from vsnprintf */
 /* New types :
- * %r : serialized pointer.
+ * %r : serialized fixed length struct, union, array.
+ * %v : serialized sequence
+ * %k : callback
  */
 static inline __attribute__((no_instrument_function))
-char *ltt_serialize_data(char *buffer, const char *fmt, va_list args)
+char *ltt_serialize_data(char *buffer, int *cb_args,
+                       const char *fmt, va_list args)
 {
        int len;
        const char *s;
@@ -48,6 +55,7 @@ char *ltt_serialize_data(char *buffer, const char *fmt, va_list args)
                                /* 't' added for ptrdiff_t */
        char *str;              /* Pointer to write to */
        ltt_serialize_cb cb;
+       int cb_arg_nr = 0;
 
        str = buf;
 
@@ -117,6 +125,9 @@ char *ltt_serialize_data(char *buffer, const char *fmt, va_list args)
                                if (buffer)
                                        strcpy(str, s);
                                str += strlen(s);
+                               /* Following alignment for genevent
+                                * compatibility */
+                               str += ltt_align(str, sizeof(void*));
                                continue;
 
                        case 'p':
@@ -154,6 +165,9 @@ char *ltt_serialize_data(char *buffer, const char *fmt, va_list args)
                                                memcpy(str, src, elem_size);
                                        str += elem_size;
                                }
+                               /* Following alignment for genevent
+                                * compatibility */
+                               str += ltt_align(str, sizeof(void*));
                                continue;
 
                        case 'k':
@@ -162,16 +176,20 @@ char *ltt_serialize_data(char *buffer, const char *fmt, va_list args)
                                 /* The callback will take as many arguments
                                  * as it needs from args. They won't be
                                  * type verified. */
-                               str = cb(str, fmt, args);
+                               if (cb_arg_nr < LTT_NR_CALLBACKS)
+                                       str = cb(str, &cb_args[cb_arg_nr++],
+                                               fmt, args);
                                continue;
 
                        case 'n':
                                /* FIXME:
-                               * What does C99 say about the overflow case here? */
+                               * What does C99 say about the overflow case
+                               * here? */
                                if (qualifier == 'l') {
                                        long * ip = va_arg(args, long *);
                                        *ip = (str - buf);
-                               } else if (qualifier == 'Z' || qualifier == 'z') {
+                               } else if (qualifier == 'Z'
+                                       || qualifier == 'z') {
                                        size_t * ip = va_arg(args, size_t *);
                                        *ip = (str - buf);
                                } else {
@@ -234,10 +252,12 @@ char *ltt_serialize_data(char *buffer, const char *fmt, va_list args)
                        if (buffer)
                                switch (elem_size) {
                                case 1:
-                                       *(int8_t*)str = (int8_t)va_arg(args, int);
+                                       *(int8_t*)str =
+                                               (int8_t)va_arg(args, int);
                                        break;
                                case 2:
-                                       *(int16_t*)str = (int16_t)va_arg(args, int);
+                                       *(int16_t*)str =
+                                               (int16_t)va_arg(args, int);
                                        break;
                                case 4:
                                        *(int32_t*)str = va_arg(args, int32_t);
@@ -262,6 +282,7 @@ char *ltt_serialize_data(char *buffer, const char *fmt, va_list args)
  * sizeof(void *) address. */
 static inline __attribute__((no_instrument_function))
 size_t ltt_get_data_size(ltt_facility_t fID, uint8_t eID,
+                               int *cb_args,
                                const char *fmt, va_list args)
 {
        return (size_t)ltt_serialize_data(NULL, fmt, args);
@@ -270,6 +291,7 @@ size_t ltt_get_data_size(ltt_facility_t fID, uint8_t eID,
 static inline __attribute__((no_instrument_function))
 void ltt_write_event_data(char *buffer,
                                ltt_facility_t fID, uint8_t eID,
+                               int *cb_args,
                                const char *fmt, va_list args)
 {
        ltt_serialize_data(buffer, fmt, args);
@@ -288,10 +310,12 @@ void _vtrace(ltt_facility_t fID, uint8_t eID, long flags,
        uint64_t tsc;
        char *buffer;
        va_list args_copy;
+       int cb_args[LTT_NR_CALLBACKS];
 
        /* This test is useful for quickly exiting static tracing when no
         * trace is active. */
-       if (likely(ltt_traces.num_active_traces == 0 && !(flags & LTT_FLAG_FORCE)))
+       if (likely(ltt_traces.num_active_traces == 0
+               && !(flags & LTT_FLAG_FORCE)))
                return;
 
        preempt_disable();
@@ -305,7 +329,7 @@ void _vtrace(ltt_facility_t fID, uint8_t eID, long flags,
                channel_index = ltt_get_channel_index(fID, eID);
 
        va_copy(args_copy, args);       /* Check : skip 2 st args if trace/ch */
-       data_size = ltt_get_data_size(fID, eID, fmt, args_copy);
+       data_size = ltt_get_data_size(fID, eID, cb_args, fmt, args_copy);
        va_end(args_copy);
 
        /* Iterate on each traces */
@@ -324,7 +348,7 @@ void _vtrace(ltt_facility_t fID, uint8_t eID, long flags,
                buffer = ltt_write_event_header(trace, channel, buffer,
                                                fID, eID, data_size, tsc);
                va_copy(args_copy, args);
-               ltt_write_event_data(buffer, fID, eID, fmt, args_copy);
+               ltt_write_event_data(buffer, fID, eID, cb_args, fmt, args_copy);
                va_end(args_copy);
                /* Out-of-order commit */
                ltt_commit_slot(channel, &transport_data, buffer, slot_size);
This page took 0.02858 seconds and 4 git commands to generate.