7f1039f44eb01e7c8909e7ec8cccd26fba495bc4
[lttv.git] / usertrace / lttng_usertrace.c
1
2 /* LTTng user-space tracing code
3 *
4 * Copyright 2006 Mathieu Desnoyers
5 *
6 */
7
8
9 #include <sys/types.h>
10 #include <sys/wait.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <signal.h>
15 #include <syscall.h>
16 #include <features.h>
17 #include <pthread.h>
18 #include <malloc.h>
19 #include <string.h>
20
21 #include <asm/atomic.h>
22 #include "lttng_usertrace.h"
23
24 #define MAX_TRACES 16
25
26 struct ltt_buf {
27 void *start;
28 atomic_t offset;
29 atomic_t reserve_count;
30 atomic_t commit_count;
31
32 atomic_t events_lost;
33 };
34
35 struct lttng_trace_info {
36 int active:1;
37 struct {
38 struct ltt_buf facilities;
39 struct ltt_buf cpu;
40 } channel;
41 };
42
43
44 /* TLS for the trace info */
45 /* http://www.dis.com/gnu/gcc/C--98-Thread-Local-Edits.html
46 *
47 * Add after paragraph 4
48 *
49 * The storage for an object of thread storage duration shall be statically
50 * initialized before the first statement of the thread startup function. An
51 * object of thread storage duration shall not require dynamic
52 * initialization.
53 * GCC extention permits init of a range.
54 */
55
56 static __thread struct lttng_trace_info lttng_trace_info[MAX_TRACES] =
57 { [ 0 ... MAX_TRACES-1 ].active = 0,
58 [ 0 ... MAX_TRACES-1 ].channel =
59 { NULL,
60 ATOMIC_INIT(0),
61 ATOMIC_INIT(0),
62 ATOMIC_INIT(0),
63 ATOMIC_INIT(0),
64 ATOMIC_INIT(0)
65 }
66 };
67
68 /* signal handler */
69 void __lttng_sig_trace_handler(int signo)
70 {
71 int ret;
72 sigset_t set, oldset;
73
74 printf("LTTng Sig handler : pid : %lu\n", getpid());
75
76 /* Disable signals */
77 ret = sigfillset(&set);
78 if(ret) {
79 printf("Error in sigfillset\n");
80 exit(1);
81 }
82
83 ret = sigprocmask(SIG_BLOCK, &set, &oldset);
84 if(ret) {
85 printf("Error in sigprocmask\n");
86 exit(1);
87 }
88
89 /* Get all the new traces */
90 #if 0
91 do {
92 /* FIXME : allocate the trace structure somewhere : thread private */
93 ret = ltt_update(addr, &active, &filter);
94
95 if(ret) {
96 printf("Error in ltt_update system call\n");
97 exit(1);
98 }
99 } while(addr);
100
101 #endif //0
102 /* Enable signals */
103 ret = sigprocmask(SIG_SETMASK, &oldset, NULL);
104 if(ret) {
105 printf("Error in sigprocmask\n");
106 exit(1);
107 }
108
109 }
110
111
112 void __lttng_init_trace_info(void)
113 {
114 memset(&lttng_trace_info, 0, MAX_TRACES*sizeof(struct lttng_trace_info));
115 }
116
117 void __attribute__((constructor)) __lttng_user_init(void)
118 {
119 static struct sigaction act;
120 int err;
121
122 printf("LTTng user init\n");
123
124 /* Init trace info */
125 __lttng_init_trace_info();
126
127 /* Activate the signal */
128 act.sa_handler = __lttng_sig_trace_handler;
129 err = sigemptyset(&(act.sa_mask));
130 if(err) perror("Error with sigemptyset");
131 err = sigaddset(&(act.sa_mask), SIGRTMIN+3);
132 if(err) perror("Error with sigaddset");
133 err = sigaction(SIGRTMIN+3, &act, NULL);
134 if(err) perror("Error with sigaction");
135
136 /* TEST */
137 err = ltt_switch((unsigned long)NULL);
138 if(err) {
139 printf("Error in ltt_switch system call\n");
140 exit(1);
141 }
142
143 /* Make the first ltt_update system call */
144 err = ltt_update(1, NULL, NULL);
145 if(err) {
146 printf("Error in ltt_update system call\n");
147 exit(1);
148 }
149
150 /* Make some ltt_switch syscalls */
151 err = ltt_switch((unsigned long)NULL);
152 if(err) {
153 printf("Error in ltt_switch system call\n");
154 exit(1);
155 }
156
157
158
159 }
This page took 0.03358 seconds and 4 git commands to generate.