update all
[lttv.git] / usertrace / lttng_usertrace.c
CommitLineData
b8b00688 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>
92f441a7 12#include <stdlib.h>
b8b00688 13#include <stdio.h>
14#include <signal.h>
15#include <syscall.h>
92f441a7 16#include <features.h>
17#include <pthread.h>
18#include <malloc.h>
19#include <string.h>
b8b00688 20
92f441a7 21#include <asm/atomic.h>
b8b00688 22#include "lttng_usertrace.h"
23
92f441a7 24#define MAX_TRACES 16
25
26struct 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
35struct lttng_trace_info {
92f441a7 36 int active:1;
9d45fe0f 37 int filter;
92f441a7 38 struct {
39 struct ltt_buf facilities;
40 struct ltt_buf cpu;
41 } channel;
42};
43
44
9d45fe0f 45/* TLS for the trace info
46 * http://www.dis.com/gnu/gcc/C--98-Thread-Local-Edits.html
78d75b00 47 *
48 * Add after paragraph 4
49 *
50 * The storage for an object of thread storage duration shall be statically
51 * initialized before the first statement of the thread startup function. An
52 * object of thread storage duration shall not require dynamic
53 * initialization.
54 * GCC extention permits init of a range.
55 */
92f441a7 56
78d75b00 57static __thread struct lttng_trace_info lttng_trace_info[MAX_TRACES] =
58{ [ 0 ... MAX_TRACES-1 ].active = 0,
9d45fe0f 59 [ 0 ... MAX_TRACES-1 ].filter = 0,
78d75b00 60 [ 0 ... MAX_TRACES-1 ].channel =
61 { NULL,
62 ATOMIC_INIT(0),
63 ATOMIC_INIT(0),
64 ATOMIC_INIT(0),
65 ATOMIC_INIT(0),
66 ATOMIC_INIT(0)
67 }
68};
92f441a7 69
9d45fe0f 70
71static void lttng_get_new_info(void)
72{
73 unsigned long cpu_addr, fac_addr;
74 unsigned int i, first_empty;
75 int active, filter;
76 int ret;
77
78 /* Get all the new traces */
79 while(1) {
80 cpu_addr = fac_addr = 0;
81 active = filter = 0;
82 ret = ltt_update(&cpu_addr, &fac_addr, &active, &filter);
83 if(ret) {
84 printf("LTTng : error in ltt_update\n");
85 exit(1);
86 }
87
88 if(!cpu_addr || !fac_addr) break;
89
90 first_empty = MAX_TRACES;
91 /* Try to find the trace */
92 for(i=0;i<MAX_TRACES;i++) {
93 if(i<first_empty && !lttng_trace_info[i].channel.cpu.start)
94 first_empty = i;
95 if(cpu_addr ==
96 (unsigned long)lttng_trace_info[i].channel.cpu.start &&
97 fac_addr ==
98 (unsigned long)lttng_trace_info[i].channel.facilities.start) {
99
100 lttng_trace_info[i].filter = filter;
101 lttng_trace_info[i].active = active;
102 }
103
104 }
105 if(i == MAX_TRACES) {
106 /* Not found. Must take an empty slot */
107 if(first_empty == MAX_TRACES) {
108 printf(
109 "LTTng WARNING : too many traces requested for pid %d by the kernel.\n"
110 " Compilation defined maximum is %u\n",
111 getpid(), MAX_TRACES);
112
113 } else {
114 lttng_trace_info[first_empty].channel.cpu.start = (void*)cpu_addr;
115 lttng_trace_info[first_empty].channel.facilities.start =
116 (void*)fac_addr;
117 lttng_trace_info[first_empty].filter = filter;
118 lttng_trace_info[first_empty].active = active;
119 }
120 }
121 }
122}
123
124
b8b00688 125/* signal handler */
126void __lttng_sig_trace_handler(int signo)
127{
92f441a7 128 int ret;
129 sigset_t set, oldset;
130
1a1e2a8c 131 printf("LTTng signal handler : thread id : %lu, pid %lu\n", pthread_self(), getpid());
132#if 0
92f441a7 133 /* Disable signals */
134 ret = sigfillset(&set);
135 if(ret) {
136 printf("Error in sigfillset\n");
137 exit(1);
138 }
139
140 ret = sigprocmask(SIG_BLOCK, &set, &oldset);
141 if(ret) {
142 printf("Error in sigprocmask\n");
143 exit(1);
144 }
1a1e2a8c 145#endif //0
1a1e2a8c 146#if 0
92f441a7 147 /* Enable signals */
148 ret = sigprocmask(SIG_SETMASK, &oldset, NULL);
149 if(ret) {
150 printf("Error in sigprocmask\n");
151 exit(1);
152 }
1a1e2a8c 153#endif //0
b8b00688 154}
155
156
1a1e2a8c 157static void thread_init(void)
b8b00688 158{
9d45fe0f 159 lttng_get_new_info();
b8b00688 160 int err;
161
92f441a7 162 /* Make some ltt_switch syscalls */
163 err = ltt_switch((unsigned long)NULL);
164 if(err) {
165 printf("Error in ltt_switch system call\n");
166 exit(1);
167 }
1a1e2a8c 168}
169
170void __attribute__((constructor)) __lttng_user_init(void)
171{
172 static struct sigaction act;
173 int err;
174
175 printf("LTTng user init\n");
176
177 /* Activate the signal */
178 act.sa_handler = __lttng_sig_trace_handler;
179 err = sigemptyset(&(act.sa_mask));
180 if(err) perror("Error with sigemptyset");
181 err = sigaddset(&(act.sa_mask), SIGRTMIN+3);
182 if(err) perror("Error with sigaddset");
183 err = sigaction(SIGRTMIN+3, &act, NULL);
184 if(err) perror("Error with sigaction");
92f441a7 185
1a1e2a8c 186 thread_init();
187}
92f441a7 188
189
1a1e2a8c 190void lttng_thread_init(void)
191{
192 thread_init();
b8b00688 193}
1a1e2a8c 194
195
196
197
198
This page took 0.031652 seconds and 4 git commands to generate.