2 /* LTTng user-space tracing code
4 * Copyright 2006 Mathieu Desnoyers
21 #include "lttng_usertrace.h"
26 /* TLS for the trace info
27 * http://www.dis.com/gnu/gcc/C--98-Thread-Local-Edits.html
29 * Add after paragraph 4
31 * The storage for an object of thread storage duration shall be statically
32 * initialized before the first statement of the thread startup function. An
33 * object of thread storage duration shall not require dynamic
35 * GCC extention permits init of a range.
38 static __thread
struct lttng_trace_info lttng_trace_info
[MAX_TRACES
] =
39 { [ 0 ... MAX_TRACES
-1 ].active
= 0,
40 [ 0 ... MAX_TRACES
-1 ].filter
= 0,
41 [ 0 ... MAX_TRACES
-1 ].nesting
= ATOMIC_INIT(0),
42 [ 0 ... MAX_TRACES
-1 ].channel
=
54 /* Must be called we sure nobody else is using the info.
55 * It implies that the trace should have been previously stopped
56 * and that every writer has finished.
58 * Writers should always check if the trace must be destroyed when they
59 * finish writing and the nesting level is 0.
61 void lttng_free_trace_info(struct lttng_trace_info
*info
)
67 "LTTng ERROR : lttng_free_trace_info should be called on inactive trace\n");
72 "LTTng ERROR : lttng_free_trace_info should be called on destroyed trace\n");
75 if(atomic_read(&info
->nesting
) > 0) {
77 "LTTng ERROR : lttng_free_trace_info should not be nested on tracing\n");
82 ret
= munmap(info
->channel
.cpu
.start
, info
->channel
.cpu
.length
);
84 perror("LTTNG : error in munmap");
86 ret
= munmap(info
->channel
.facilities
.start
, info
->channel
.facilities
.length
);
88 perror("LTTNG : error in munmap");
91 /* Zero the structure */
92 memset(info
, 0, sizeof(struct lttng_trace_info
));
96 static void lttng_get_new_info(void)
98 unsigned long cpu_addr
, fac_addr
;
99 unsigned int i
, first_empty
;
100 int active
, filter
, destroy
;
103 /* Get all the new traces */
105 cpu_addr
= fac_addr
= 0;
106 active
= filter
= destroy
= 0;
107 ret
= ltt_update(&cpu_addr
, &fac_addr
, &active
, &filter
, &destroy
);
109 printf("LTTng : error in ltt_update\n");
113 if(!cpu_addr
|| !fac_addr
) break;
115 first_empty
= MAX_TRACES
;
116 /* Try to find the trace */
117 for(i
=0;i
<MAX_TRACES
;i
++) {
118 if(i
<first_empty
&& !lttng_trace_info
[i
].channel
.cpu
.start
)
121 (unsigned long)lttng_trace_info
[i
].channel
.cpu
.start
&&
123 (unsigned long)lttng_trace_info
[i
].channel
.facilities
.start
) {
125 lttng_trace_info
[i
].filter
= filter
;
126 lttng_trace_info
[i
].active
= active
;
127 lttng_trace_info
[i
].destroy
= destroy
;
128 if(destroy
&& !atomic_read(<tng_trace_info
[i
].nesting
)) {
129 lttng_free_trace_info(<tng_trace_info
[i
]);
135 if(i
== MAX_TRACES
) {
136 /* Not found. Must take an empty slot */
137 if(first_empty
== MAX_TRACES
) {
139 "LTTng WARNING : too many traces requested for pid %d by the kernel.\n"
140 " Compilation defined maximum is %u\n",
141 getpid(), MAX_TRACES
);
144 lttng_trace_info
[first_empty
].channel
.cpu
.start
= (void*)cpu_addr
;
145 lttng_trace_info
[first_empty
].channel
.cpu
.length
= PAGE_SIZE
;
146 lttng_trace_info
[first_empty
].channel
.facilities
.start
=
148 lttng_trace_info
[first_empty
].channel
.facilities
.length
= PAGE_SIZE
;
149 lttng_trace_info
[first_empty
].filter
= filter
;
150 lttng_trace_info
[first_empty
].active
= active
;
158 void __lttng_sig_trace_handler(int signo
)
161 sigset_t set
, oldset
;
163 printf("LTTng signal handler : thread id : %lu, pid %lu\n", pthread_self(), getpid());
165 /* Disable signals */
166 ret
= sigfillset(&set
);
168 printf("Error in sigfillset\n");
172 ret
= sigprocmask(SIG_BLOCK
, &set
, &oldset
);
174 printf("Error in sigprocmask\n");
180 ret
= sigprocmask(SIG_SETMASK
, &oldset
, NULL
);
182 printf("Error in sigprocmask\n");
189 static void thread_init(void)
191 lttng_get_new_info();
194 /* Make some ltt_switch syscalls */
195 err
= ltt_switch((unsigned long)NULL
);
197 printf("Error in ltt_switch system call\n");
202 void __attribute__((constructor
)) __lttng_user_init(void)
204 static struct sigaction act
;
207 printf("LTTng user init\n");
209 /* Activate the signal */
210 act
.sa_handler
= __lttng_sig_trace_handler
;
211 err
= sigemptyset(&(act
.sa_mask
));
212 if(err
) perror("Error with sigemptyset");
213 err
= sigaddset(&(act
.sa_mask
), SIGRTMIN
+3);
214 if(err
) perror("Error with sigaddset");
215 err
= sigaction(SIGRTMIN
+3, &act
, NULL
);
216 if(err
) perror("Error with sigaction");
222 void lttng_thread_init(void)