2 * pthread_create wrapper for gprof compatibility
11 typedef struct wrapper_s
13 void * (*start_routine)(void *);
19 struct itimerval itimer;
23 static void * wrapper_routine(void *);
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)
30 wrapper_t wrapper_data;
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);
41 /* The real pthread_create call */
42 i_return = pthread_create(thread, attr, &wrapper_routine,
45 /* If the thread was successfully spawned, wait for the data
49 pthread_cond_wait(&wrapper_data.wait, &wrapper_data.lock);
52 pthread_mutex_unlock(&wrapper_data.lock);
53 pthread_mutex_destroy(&wrapper_data.lock);
54 pthread_cond_destroy(&wrapper_data.wait);
59 /* The wrapper function in charge for setting the itimer value */
60 static void * wrapper_routine(void * data)
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;
66 /* Set the profile timer value */
67 setitimer(ITIMER_PROF, &((wrapper_t*)data)->itimer, NULL);
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);
74 /* Call the real function */
75 return start_routine(arg);