--- /dev/null
+/*
+ * ltt-facility-loader-user_tests.c
+ *
+ * (C) Copyright 2005 -
+ * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ *
+ * Contains the LTT user space facility loader.
+ *
+ */
+
+
+#define LTT_TRACE
+#include <error.h>
+#include <stdio.h>
+#include <ltt/ltt-usertrace.h>
+#include "ltt-facility-loader-user_tests.h"
+
+static struct user_facility_info facility = {
+ .name = LTT_FACILITY_NAME,
+ .num_events = LTT_FACILITY_NUM_EVENTS,
+#ifndef LTT_PACK
+ .alignment = sizeof(void*),
+#else
+ .alignment = 0,
+#endif //LTT_PACK
+ .checksum = LTT_FACILITY_CHECKSUM,
+ .int_size = sizeof(int),
+ .long_size = sizeof(long),
+ .pointer_size = sizeof(void*),
+ .size_t_size = sizeof(size_t)
+};
+
+static void __attribute__((constructor)) __ltt_user_init(void)
+{
+ int err;
+#ifdef LTT_SHOW_DEBUG
+ printf("LTT : ltt-facility-user_tests init in userspace\n");
+#endif //LTT_SHOW_DEBUG
+
+ err = ltt_register_generic(<T_FACILITY_SYMBOL, &facility);
+ LTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;
+
+ if(err) {
+#ifdef LTT_SHOW_DEBUG
+ perror("Error in ltt_register_generic");
+#endif //LTT_SHOW_DEBUG
+ }
+}
+
--- /dev/null
+#ifndef _LTT_FACILITY_USER_TESTS_H_
+#define _LTT_FACILITY_USER_TESTS_H_
+
+#include <sys/types.h>
+#include <ltt/ltt-facility-id-user_tests.h>
+#include <ltt/ltt-usertrace.h>
+
+/* Named types */
+
+/* Event write_4bytes structures */
+
+/* Event write_4bytes logging function */
+#ifndef LTT_TRACE_FAST
+static inline int trace_user_tests_write_4bytes(
+ int lttng_param_data)
+#ifndef LTT_TRACE
+{
+}
+#else
+{
+ int ret = 0;
+ void *buffer = NULL;
+ size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+ size_t *to_base = &real_to_base;
+ size_t real_to = 0;
+ size_t *to = &real_to;
+ size_t real_len = 0;
+ size_t *len = &real_len;
+ size_t reserve_size;
+ size_t slot_size;
+ size_t align;
+ const void *real_from;
+ const void **from = &real_from;
+ /* For each field, calculate the field size. */
+ /* size = *to_base + *to + *len */
+ /* Assume that the padding for alignment starts at a
+ * sizeof(void *) address. */
+
+ *from = <tng_param_data;
+ align = sizeof(int);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(int);
+
+ reserve_size = *to_base + *to + *len;
+ {
+ char stack_buffer[reserve_size];
+ buffer = stack_buffer;
+
+ *to_base = *to = *len = 0;
+
+ *from = <tng_param_data;
+ align = sizeof(int);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(int);
+
+ /* Flush pending memcpy */
+ if(*len != 0) {
+ memcpy(buffer+*to_base+*to, *from, *len);
+ *to += *len;
+ *len = 0;
+ }
+
+ ret = ltt_trace_generic(ltt_facility_user_tests_CDD24456, event_user_tests_write_4bytes, buffer, reserve_size, LTT_BLOCKING);
+ }
+
+ return ret;
+
+}
+#endif //LTT_TRACE
+#endif //!LTT_TRACE_FAST
+
+#ifdef LTT_TRACE_FAST
+static inline int trace_user_tests_write_4bytes(
+ int lttng_param_data)
+#ifndef LTT_TRACE
+{
+}
+#else
+{
+ unsigned int index;
+ struct ltt_trace_info *trace = thread_trace_info;
+ struct ltt_buf *ltt_buf;
+ void *buffer = NULL;
+ size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+ size_t *to_base = &real_to_base;
+ size_t real_to = 0;
+ size_t *to = &real_to;
+ size_t real_len = 0;
+ size_t *len = &real_len;
+ size_t reserve_size;
+ size_t slot_size;
+ size_t align;
+ const void *real_from;
+ const void **from = &real_from;
+ uint64_t tsc;
+ size_t before_hdr_pad, after_hdr_pad, header_size;
+
+ if(!trace) {
+ ltt_thread_init();
+ trace = thread_trace_info;
+ }
+
+
+ /* For each field, calculate the field size. */
+ /* size = *to_base + *to + *len */
+ /* Assume that the padding for alignment starts at a
+ * sizeof(void *) address. */
+
+ *from = <tng_param_data;
+ align = sizeof(int);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(int);
+
+ reserve_size = *to_base + *to + *len;
+ trace->nesting++;
+ index = ltt_get_index_from_facility(ltt_facility_user_tests_CDD24456,
+ event_user_tests_write_4bytes);
+
+ {
+ ltt_buf = ltt_get_channel_from_index(trace, index);
+ slot_size = 0;
+ buffer = ltt_reserve_slot(trace, ltt_buf,
+ reserve_size, &slot_size, &tsc,
+ &before_hdr_pad, &after_hdr_pad, &header_size);
+ if(!buffer) goto end; /* buffer full */
+
+ *to_base = *to = *len = 0;
+
+ ltt_write_event_header(trace, ltt_buf, buffer,
+ ltt_facility_user_tests_CDD24456, event_user_tests_write_4bytes,
+ reserve_size, before_hdr_pad, tsc);
+ *to_base += before_hdr_pad + after_hdr_pad + header_size;
+
+ *from = <tng_param_data;
+ align = sizeof(int);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(int);
+
+ /* Flush pending memcpy */
+ if(*len != 0) {
+ memcpy(buffer+*to_base+*to, *from, *len);
+ *to += *len;
+ *len = 0;
+ }
+
+ ltt_commit_slot(ltt_buf, buffer, slot_size);
+
+}
+
+end:
+ trace->nesting--;
+}
+#endif //LTT_TRACE
+#endif //LTT_TRACE_FAST
+
+#endif //_LTT_FACILITY_USER_TESTS_H_
--- /dev/null
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/timex.h>
+
+#define LTT_TRACE
+#define LTT_TRACE_FAST
+#include <ltt/ltt-facility-user_tests.h>
+
+#define max(a,b) ((a)>(b)?(a):(b))
+#define min(a,b) ((a)<(b)?(a):(b))
+
+/* Event logged : 4 bytes + 20 bytes header = 24 bytes. Let's use 1MB of
+ * buffers. 1MB / 24bytes = 43690. So, if we write 20000 event, we should not
+ * lose events. Check event lost count after tests. */
+
+#define NR_LOOPS 20000
+
+typedef unsigned long long cycles_t;
+
+int main(int argc, char **argv)
+{
+ unsigned int i;
+ cycles_t time1, time2, time;
+ cycles_t max_time = 0, min_time = 18446744073709551615ULL; /* (2^64)-1 */
+ cycles_t tot_time = 0;
+
+ for(i=0; i<NR_LOOPS; i++) {
+ time1 = get_cycles();
+ trace_user_tests_write_4bytes(5000);
+ time2 = get_cycles();
+ time = time2 - time1;
+ max_time = max(max_time, time);
+ min_time = min(min_time, time);
+ tot_time += time;
+ }
+
+ printf("test results : time per probe (in cycles)\n");
+ printf("number of loops : %d\n", NR_LOOPS);
+ printf("total time : %llu\n", tot_time);
+ printf("average time : %g\n", tot_time/(double)NR_LOOPS);
+ printf("min : %llu\n", min_time);
+ printf("max : %llu\n", max_time);
+
+ return 0;
+}
+