signals ok
[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 signal handler : thread id : %lu, pid %lu\n", pthread_self(), getpid());
75 #if 0
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 #endif //0
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
103 #if 0
104 /* Enable signals */
105 ret = sigprocmask(SIG_SETMASK, &oldset, NULL);
106 if(ret) {
107 printf("Error in sigprocmask\n");
108 exit(1);
109 }
110 #endif //0
111 }
112
113
114 static void thread_init(void)
115 {
116 int err;
117
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
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 }
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 }
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");
155
156 thread_init();
157 }
158
159
160 void lttng_thread_init(void)
161 {
162 thread_init();
163 }
164
165
166
167
168
This page took 0.032102 seconds and 4 git commands to generate.