// 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); }
// 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; }
// 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; }
// 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; }
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); }
// 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; }
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'; }
// 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; }
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'; }
// 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; }
// 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; }
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; }
// 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; }
static int getvgtid() { int res; VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__GET_THREAD_SELF, 0, 0, 0,0,0); return res; }
/** 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); }
/** 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); }
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); }