// pthread_barrier_init
PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
         pthread_barrier_t* barrier,
         const pthread_barrierattr_t* attr,
         unsigned count)
{
  int   ret;
  int   res;
  OrigFn fn;
  VALGRIND_GET_ORIG_FN(fn);
  VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_INIT,
                             barrier, pthread_barrier, count, 0, 0);
  CALL_FN_W_WWW(ret, fn, barrier, attr, count);
  VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_INIT,
                             barrier, pthread_barrier, 0, 0, 0);
  return ret;
}
// pthread_mutex_unlock
PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
         pthread_mutex_t *mutex)
{
  int ret;
  int   res;
  OrigFn fn;
  VALGRIND_GET_ORIG_FN(fn);
  VALGRIND_DO_CLIENT_REQUEST(res, -1,
                             VG_USERREQ__PRE_MUTEX_UNLOCK,
                             mutex, mutex_type(mutex), 0, 0, 0);
  CALL_FN_W_W(ret, fn, mutex);
  VALGRIND_DO_CLIENT_REQUEST(res, -1,
                             VG_USERREQ__POST_MUTEX_UNLOCK,
                             mutex, 0, 0, 0, 0);
  return ret;
}
// pthread_cond_timedwait
PTH_FUNC(int, pthreadZucondZutimedwaitZa, // pthread_cond_timedwait*
         pthread_cond_t *cond,
         pthread_mutex_t *mutex,
         const struct timespec* abstime)
{
  int   ret;
  int   res;
  OrigFn fn;
  VALGRIND_GET_ORIG_FN(fn);
  VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
                             cond, mutex, mutex_type(mutex), 0, 0);
  CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
  VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
                             cond, mutex, 1, 0, 0);
  return ret;
}
static void vg_set_joinable(const pthread_t tid, const int joinable)
{
  int res;
  assert(joinable == 0 || joinable == 1);
  VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_JOINABLE,
                             tid, joinable, 0, 0, 0);
}
/**
 * The main thread is the only thread not created by pthread_create().
 * Update DRD's state information about the main thread.
 */
static void DRD_(set_main_thread_state)(void)
{
   int res;

   // Make sure that DRD knows about the main thread's POSIX thread ID.
   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
                              pthread_self(), 0, 0, 0, 0);

}
예제 #6
0
// pthread_mutex_init
PTH_FUNC(int, pthreadZumutexZuinit,
         pthread_mutex_t *mutex,
         const pthread_mutexattr_t* attr)
{
  int ret;
  int res;
  OrigFn fn;
  int mt;
  VALGRIND_GET_ORIG_FN(fn);
  mt = PTHREAD_MUTEX_DEFAULT;
  if (attr)
    pthread_mutexattr_gettype(attr, &mt);
  VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
                             mutex, pthread_to_drd_mutex_type(mt), 0, 0, 0);
  CALL_FN_W_WW(ret, fn, mutex, attr);
  VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT,
                             mutex, 0, 0, 0, 0);
  return ret;
}
// pthread_spin_unlock
PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock
         pthread_spinlock_t *spinlock)
{
    int   ret;
    int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
                               spinlock, mutex_type_spinlock, 0, 0, 0);
    CALL_FN_W_W(ret, fn, spinlock);
    return ret;
}
// pthread_spin_destroy
PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
         pthread_spinlock_t *spinlock)
{
    int ret;
    int res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    CALL_FN_W_W(ret, fn, spinlock);
    VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
                               spinlock, mutex_type_spinlock, 0, 0, 0);
    return ret;
}
// pthread_cond_broadcast
PTH_FUNC(int, pthreadZucondZubroadcastZa, // pthread_cond_broadcast*
         pthread_cond_t* cond)
{
    int   ret;
    int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_BROADCAST,
                               cond, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, cond);
    return ret;
}
예제 #10
0
// pthread_cond_signal
PTH_FUNC(int, pthreadZucondZusignalZa, // pthread_cond_signal*
         pthread_cond_t* cond)
{
    int   ret;
    int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_SIGNAL,
                               cond, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, cond);
    return ret;
}
예제 #11
0
// pthread_cond_destroy
PTH_FUNC(int, pthreadZucondZudestroyZa, // pthread_cond_destroy*
         pthread_cond_t* cond)
{
    int ret;
    int res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    CALL_FN_W_W(ret, fn, cond);
    VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_DESTROY,
                               cond, 0, 0, 0, 0);
    return ret;
}
예제 #12
0
static void init(void)
{
   int res;

   if (init_done)
      return;

   init_done = 1;

   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__GET_MALLOCFUNCS, &info,
                              0, 0, 0, 0);
}
예제 #13
0
// pthread_cond_init
PTH_FUNC(int, pthreadZucondZuinitZa, // pthread_cond_init*
         pthread_cond_t* cond,
         const pthread_condattr_t* attr)
{
    int ret;
    int res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_INIT,
                               cond, 0, 0, 0, 0);
    CALL_FN_W_WW(ret, fn, cond, attr);
    return ret;
}
예제 #14
0
void VG_NOTIFY_ON_LOAD(freeres)( void )
{
   int res;
#ifndef __UCLIBC__
   extern void __libc_freeres(void);
   __libc_freeres();
#endif
   VALGRIND_DO_CLIENT_REQUEST(res, 0 /* default */,
                              VG_USERREQ__LIBC_FREERES_DONE, 
                              0, 0, 0, 0, 0);
   /*NOTREACHED*/
   *(int *)0 = 'x';
}
예제 #15
0
// pthread_rwlock_destroy
PTH_FUNC(int,
         pthreadZurwlockZudestroyZa, // pthread_rwlock_destroy*
         pthread_rwlock_t* rwlock)
{
   int   ret;
   int   res;
   OrigFn fn;
   VALGRIND_GET_ORIG_FN(fn);
   CALL_FN_W_W(ret, fn, rwlock);
   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_DESTROY,
                              rwlock, 0, 0, 0, 0);
   return ret;
}
예제 #16
0
void VG_NOTIFY_ON_LOAD(freeres)( void )
{
   int res;
#if !defined(__UCLIBC__) && !defined(VGO_aix5)
   extern void __libc_freeres(void);
   __libc_freeres();
#endif
   VALGRIND_DO_CLIENT_REQUEST(res, 0 /* default */,
                              VG_USERREQ__LIBC_FREERES_DONE, 
                              0, 0, 0, 0, 0);
   /*NOTREACHED*/
   *(volatile int *)0 = 'x';
}
예제 #17
0
// pthread_rwlock_init
PTH_FUNC(int,
         pthreadZurwlockZuinitZa, // pthread_rwlock_init*
         pthread_rwlock_t* rwlock,
         const pthread_rwlockattr_t* attr)
{
   int   ret;
   int   res;
   OrigFn fn;
   VALGRIND_GET_ORIG_FN(fn);
   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_INIT,
                              rwlock, 0, 0, 0, 0);
   CALL_FN_W_WW(ret, fn, rwlock, attr);
   return ret;
}
예제 #18
0
// pthread_join
PTH_FUNC(int, pthreadZujoinZa, // pthread_join*
         pthread_t pt_joinee, void **thread_return)
{
   int      ret;
   int      res;
   OrigFn   fn;

   VALGRIND_GET_ORIG_FN(fn);
   CALL_FN_W_WW(ret, fn, pt_joinee, thread_return);
   if (ret == 0)
   {
      VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_JOIN,
                                 pt_joinee, 0, 0, 0, 0);
   }
   return ret;
}
예제 #19
0
void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void)
{
    OrigFn fn;
    Addr result = 0;
    int res;

    /* Call the original indirect function and get it's result */
    VALGRIND_GET_ORIG_FN(fn);
    CALL_FN_W_v(result, fn);

    /* Ask the valgrind core running on the real CPU (as opposed to this
       code which runs on the emulated CPU) to update the redirection that
       led to this function. This client request eventually gives control to
       the function VG_(redir_add_ifunc_target) in m_redir.c  */
    VALGRIND_DO_CLIENT_REQUEST(res, 0,
                               VG_USERREQ__ADD_IFUNC_TARGET,
                               fn.nraddr, result, 0, 0, 0);
    return (void*)result;
}
예제 #20
0
// pthread_create
PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
         pthread_t *thread, const pthread_attr_t *attr,
         void *(*start) (void *), void *arg)
{
   int    res;
   int    ret;
   OrigFn fn;
#if defined(ALLOCATE_THREAD_ARGS_ON_THE_STACK)
   DrdPosixThreadArgs thread_args;
#endif
   DrdPosixThreadArgs* thread_args_p;

   VALGRIND_GET_ORIG_FN(fn);

#if defined(ALLOCATE_THREAD_ARGS_ON_THE_STACK)
   thread_args_p = &thread_args;
#else
   thread_args_p = malloc(sizeof(*thread_args_p));
#endif
   assert(thread_args_p);

   thread_args_p->start           = start;
   thread_args_p->arg             = arg;
#if defined(WAIT_UNTIL_CREATED_THREAD_STARTED)
   DRD_IGNORE_VAR(thread_args_p->wrapper_started);
   thread_args_p->wrapper_started = 0;
#endif
   /*
    * Find out whether the thread will be started as a joinable thread
    * or as a detached thread. If no thread attributes have been specified,
    * this means that the new thread will be started as a joinable thread.
    */
   thread_args_p->detachstate = PTHREAD_CREATE_JOINABLE;
   if (attr)
   {
      if (pthread_attr_getdetachstate(attr, &thread_args_p->detachstate) != 0)
      {
         assert(0);
      }
   }
   assert(thread_args_p->detachstate == PTHREAD_CREATE_JOINABLE
          || thread_args_p->detachstate == PTHREAD_CREATE_DETACHED);


   DRD_(entering_pthread_create)();
   CALL_FN_W_WWWW(ret, fn, thread, attr, DRD_(thread_wrapper), thread_args_p);
   DRD_(left_pthread_create)();

#if defined(WAIT_UNTIL_CREATED_THREAD_STARTED)
   if (ret == 0)
   {
      /*
       * Wait until the thread wrapper started.
       * @todo Find out why some regression tests fail if thread arguments are
       *   passed via dynamically allocated memory and if the loop below is
       *   removed.
       */
      while (! thread_args_p->wrapper_started)
      {
         sched_yield();
      }
   }

#if defined(ALLOCATE_THREAD_ARGS_DYNAMICALLY)
   free(thread_args_p);
#endif

#endif

   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_START_NEW_SEGMENT,
                              pthread_self(), 0, 0, 0, 0);

   return ret;
}
예제 #21
0
static int getvgtid()
{
  int res;
  VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__GET_THREAD_SELF, 0, 0, 0,0,0);
  return res;
}
예제 #22
0
/** Tell DRD that the calling thread has left pthread_create(). */
static __inline__ void DRD_(left_pthread_create)(void)
{
   int res;
   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__LEFT_PTHREAD_CREATE,
                              0, 0, 0, 0, 0);
}
예제 #23
0
/** Tell DRD that the calling thread is about to enter pthread_create(). */
static __inline__ void DRD_(entering_pthread_create)(void)
{
   int res;
   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__ENTERING_PTHREAD_CREATE,
                              0, 0, 0, 0, 0);
}
예제 #24
0
static void vg_start_suppression(const void* const p, size_t const size)
{
  int res;
  VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
                             p, size, 0, 0, 0);
}