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