1 /* LTTng user-space "fast" library
3 * This daemon is spawned by each traced thread (to share the mmap).
5 * Its job is to dump periodically this buffer to disk (when it receives a
6 * SIGUSR1 from its parent).
8 * It uses the control information in the shared memory area (producer/consumer
11 * When the parent thread dies (yes, those thing may happen) ;) , this daemon
12 * will flush the last buffer and write it to disk.
14 * Supplement note for streaming : the daemon is responsible for flushing
15 * periodically the buffer if it is streaming data.
19 * shm memory is typically limited to 4096 units (system wide limit SHMMNI in
20 * /proc/sys/kernel/shmmni). As it requires computation time upon creation, we
21 * do not use it : we will use a shared mmap() instead which is passed through
23 * MAP_SHARED mmap segment. Updated when msync or munmap are called.
25 * Memory mapped by mmap() is preserved across fork(2), with the same
28 * Eventually, there will be two mode :
29 * * Slow thread spawn : a fork() is done for each new thread. If the process
30 * dies, the data is not lost.
31 * * Fast thread spawn : a pthread_create() is done by the application for each
33 * Copyright 2006 Mathieu Desnoyers
37 #include <sys/types.h>
51 #include "ltt-usertrace-fast.h"
53 /* TLS for the trace buffer
54 * http://www.dis.com/gnu/gcc/C--98-Thread-Local-Edits.html
56 * Add after paragraph 4
58 * The storage for an object of thread storage duration shall be statically
59 * initialized before the first statement of the thread startup function. An
60 * object of thread storage duration shall not require dynamic
64 __thread
struct ltt_trace_info ltt_trace_info
=
68 .nesting
= ATOMIC_INIT(0),
84 __thread
struct ltt_trace_info
*thread_trace_info
= NULL
;
89 static void handler(int signo
)
91 printf("Signal %d received\n", signo
);
96 void ltt_usertrace_fast_buffer_switch(void)
98 kill(thread_trace_info
->daemon_id
, SIGUSR1
);
101 static void ltt_usertrace_fast_daemon(struct ltt_trace_info
*shared_trace_info
,
104 struct sigaction act
;
107 printf("ltt_usertrace_fast_daemon : init is %d, pid is %lu\n",
108 shared_trace_info
->init
, getpid());
110 act
.sa_handler
= handler
;
112 sigemptyset(&(act
.sa_mask
));
113 sigaddset(&(act
.sa_mask
), SIGUSR1
);
114 sigaction(SIGUSR1
, &act
, NULL
);
116 ret
= pthread_sigmask(SIG_SETMASK
, &oldset
, NULL
);
118 printf("Error in pthread_sigmask\n");
123 printf("Doing a buffer switch read. pid is : %lu\n", getpid());
128 void ltt_thread_init(void)
131 struct ltt_trace_info
*shared_trace_info
;
133 sigset_t set
, oldset
;
135 /* parent : create the shared memory map */
136 shared_trace_info
= thread_trace_info
= mmap(0, sizeof(*thread_trace_info
),
137 PROT_READ
|PROT_WRITE
, MAP_SHARED
|MAP_ANONYMOUS
, 0, 0);
138 memset(shared_trace_info
, 0, sizeof(*thread_trace_info
));
139 thread_trace_info
->init
= 1;
141 /* Disable signals */
142 ret
= sigfillset(&set
);
144 printf("Error in sigfillset\n");
148 ret
= pthread_sigmask(SIG_BLOCK
, &set
, &oldset
);
150 printf("Error in pthread_sigmask\n");
156 thread_trace_info
->daemon_id
= pid
;
159 ret
= pthread_sigmask(SIG_SETMASK
, &oldset
, NULL
);
161 printf("Error in pthread_sigmask\n");
163 } else if(pid
== 0) {
165 ltt_usertrace_fast_daemon(shared_trace_info
, oldset
);
166 /* Should never return */
170 perror("Error in forking ltt-usertrace-fast");
174 void __attribute__((constructor
)) __ltt_usertrace_fast_init(void)
176 printf("LTT usertrace-fast init\n");
181 void __attribute__((destructor
)) __ltt_usertrace_fast_fini(void)
183 printf("LTT usertrace-fast fini\n");