]> gitweb.fperrin.net Git - iftop.git/blob - threadprof.c
Import iftop-1.0pre4
[iftop.git] / threadprof.c
1 /* 
2  * pthread_create wrapper for gprof compatibility
3  *
4  */
5
6 #include <pthread.h>
7 #include <sys/time.h>
8
9 #undef pthread_create
10
11 typedef struct wrapper_s
12 {
13     void * (*start_routine)(void *);
14     void * arg;
15
16     pthread_mutex_t lock;
17     pthread_cond_t  wait;
18
19     struct itimerval itimer;
20
21 } wrapper_t;
22
23 static void * wrapper_routine(void *);
24
25 /* Same prototype as pthread_create; use some #define magic to
26  * transparently replace it in other files */
27 int gprof_pthread_create(pthread_t * thread, pthread_attr_t * attr,
28                          void * (*start_routine)(void *), void * arg)
29 {
30     wrapper_t wrapper_data;
31     int i_return;
32
33     /* Initialize the wrapper structure */
34     wrapper_data.start_routine = start_routine;
35     wrapper_data.arg = arg;
36     getitimer(ITIMER_PROF, &wrapper_data.itimer);
37     pthread_cond_init(&wrapper_data.wait, NULL);
38     pthread_mutex_init(&wrapper_data.lock, NULL);
39     pthread_mutex_lock(&wrapper_data.lock);
40
41     /* The real pthread_create call */
42     i_return = pthread_create(thread, attr, &wrapper_routine,
43                                             &wrapper_data);
44
45     /* If the thread was successfully spawned, wait for the data
46      * to be released */
47     if(i_return == 0)
48     {
49         pthread_cond_wait(&wrapper_data.wait, &wrapper_data.lock);
50     }
51
52     pthread_mutex_unlock(&wrapper_data.lock);
53     pthread_mutex_destroy(&wrapper_data.lock);
54     pthread_cond_destroy(&wrapper_data.wait);
55
56     return i_return;
57 }
58
59 /* The wrapper function in charge for setting the itimer value */
60 static void * wrapper_routine(void * data)
61 {
62     /* Put user data in thread-local variables */
63     void * (*start_routine)(void *) = ((wrapper_t*)data)->start_routine;
64     void * arg = ((wrapper_t*)data)->arg;
65
66     /* Set the profile timer value */
67     setitimer(ITIMER_PROF, &((wrapper_t*)data)->itimer, NULL);
68
69     /* Tell the calling thread that we don't need its data anymore */
70     pthread_mutex_lock(&((wrapper_t*)data)->lock);
71     pthread_cond_signal(&((wrapper_t*)data)->wait);
72     pthread_mutex_unlock(&((wrapper_t*)data)->lock);
73
74     /* Call the real function */
75     return start_routine(arg);
76 }