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 | |
b8b00688 |
74 | printf("LTTng Sig handler : pid : %lu\n", getpid()); |
92f441a7 |
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 | |
b8b00688 |
109 | } |
110 | |
111 | |
92f441a7 |
112 | void __lttng_init_trace_info(void) |
113 | { |
114 | memset(<tng_trace_info, 0, MAX_TRACES*sizeof(struct lttng_trace_info)); |
115 | } |
b8b00688 |
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 | |
92f441a7 |
124 | /* Init trace info */ |
125 | __lttng_init_trace_info(); |
126 | |
b8b00688 |
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 | |
92f441a7 |
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 | |
b8b00688 |
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 | } |
92f441a7 |
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 | |
b8b00688 |
159 | } |