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 | |
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 { |
92f441a7 |
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 */ |
78d75b00 |
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 | */ |
92f441a7 |
55 | |
78d75b00 |
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 | }; |
92f441a7 |
67 | |
b8b00688 |
68 | /* signal handler */ |
69 | void __lttng_sig_trace_handler(int signo) |
70 | { |
92f441a7 |
71 | int ret; |
72 | sigset_t set, oldset; |
73 | |
1a1e2a8c |
74 | printf("LTTng signal handler : thread id : %lu, pid %lu\n", pthread_self(), getpid()); |
75 | #if 0 |
92f441a7 |
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 | } |
1a1e2a8c |
88 | #endif //0 |
92f441a7 |
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 |
1a1e2a8c |
102 | |
103 | #if 0 |
92f441a7 |
104 | /* Enable signals */ |
105 | ret = sigprocmask(SIG_SETMASK, &oldset, NULL); |
106 | if(ret) { |
107 | printf("Error in sigprocmask\n"); |
108 | exit(1); |
109 | } |
1a1e2a8c |
110 | #endif //0 |
b8b00688 |
111 | } |
112 | |
113 | |
1a1e2a8c |
114 | static void thread_init(void) |
b8b00688 |
115 | { |
b8b00688 |
116 | int err; |
117 | |
92f441a7 |
118 | /* TEST */ |
119 | err = ltt_switch((unsigned long)NULL); |
120 | if(err) { |
121 | printf("Error in ltt_switch system call\n"); |
122 | exit(1); |
123 | } |
124 | |
b8b00688 |
125 | /* Make the first ltt_update system call */ |
126 | err = ltt_update(1, NULL, NULL); |
127 | if(err) { |
128 | printf("Error in ltt_update system call\n"); |
129 | exit(1); |
130 | } |
92f441a7 |
131 | |
132 | /* Make some ltt_switch syscalls */ |
133 | err = ltt_switch((unsigned long)NULL); |
134 | if(err) { |
135 | printf("Error in ltt_switch system call\n"); |
136 | exit(1); |
137 | } |
1a1e2a8c |
138 | } |
139 | |
140 | void __attribute__((constructor)) __lttng_user_init(void) |
141 | { |
142 | static struct sigaction act; |
143 | int err; |
144 | |
145 | printf("LTTng user init\n"); |
146 | |
147 | /* Activate the signal */ |
148 | act.sa_handler = __lttng_sig_trace_handler; |
149 | err = sigemptyset(&(act.sa_mask)); |
150 | if(err) perror("Error with sigemptyset"); |
151 | err = sigaddset(&(act.sa_mask), SIGRTMIN+3); |
152 | if(err) perror("Error with sigaddset"); |
153 | err = sigaction(SIGRTMIN+3, &act, NULL); |
154 | if(err) perror("Error with sigaction"); |
92f441a7 |
155 | |
1a1e2a8c |
156 | thread_init(); |
157 | } |
92f441a7 |
158 | |
159 | |
1a1e2a8c |
160 | void lttng_thread_init(void) |
161 | { |
162 | thread_init(); |
b8b00688 |
163 | } |
1a1e2a8c |
164 | |
165 | |
166 | |
167 | |
168 | |