threadprof.c 2.1 KB

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