mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
- Performance improvement: eliminated busy waiting from thread creation.
- Applied DRD_() prefix to all names of functions that are not intercepts of client code. - Removed superfluous include directive, namely #include <inttypes.h>. - Removed hack for suppressing false positive reports on stdio / stderr because recently a suppression pattern was added for these races. - Removed unused code and declarations. - Added more comments. - Updated copyright statement. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9149
This commit is contained in:
parent
99249d56d6
commit
0a804bd7c6
@ -1,13 +1,12 @@
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/*--- Client-space code for drd. drd_pthread_intercepts.c ---*/
|
||||
/*--- Client-space code for DRD. drd_pthread_intercepts.c ---*/
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
This file is part of drd, a data race detector.
|
||||
This file is part of DRD, a data race detector.
|
||||
|
||||
Copyright (C) 2006-2008 Bart Van Assche
|
||||
bart.vanassche@gmail.com
|
||||
Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
@ -40,26 +39,27 @@
|
||||
originates from Valgrind.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
// Make sure pthread_spinlock_t is available when compiling with older glibc
|
||||
// versions (2.3 or before).
|
||||
/*
|
||||
Define _GNU_SOURCE to make sure that pthread_spinlock_t is available when
|
||||
compiling with older glibc versions (2.3 or before).
|
||||
*/
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h> // uintptr_t
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h> // confstr()
|
||||
#include "config.h"
|
||||
#include "drd_basics.h"
|
||||
#include <assert.h> /* assert() */
|
||||
#include <pthread.h> /* pthread_mutex_t */
|
||||
#include <semaphore.h> /* sem_t */
|
||||
#include <stdio.h> /* fprintf() */
|
||||
#include <stdlib.h> /* malloc(), free() */
|
||||
#include <unistd.h> /* confstr() */
|
||||
#include "config.h" /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP etc. */
|
||||
#include "drd_basics.h" /* DRD_() */
|
||||
#include "drd_clientreq.h"
|
||||
#include "pub_tool_redir.h"
|
||||
#include "pub_tool_redir.h" /* VG_WRAP_FUNCTION_ZZ() */
|
||||
|
||||
|
||||
// Defines.
|
||||
/* Defines. */
|
||||
|
||||
#define PTH_FUNC(ret_ty, f, args...) \
|
||||
ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args); \
|
||||
@ -73,74 +73,78 @@ typedef struct
|
||||
void* (*start)(void*);
|
||||
void* arg;
|
||||
int detachstate;
|
||||
#if 0
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
#else
|
||||
int wrapper_started;
|
||||
#endif
|
||||
} VgPosixThreadArgs;
|
||||
|
||||
|
||||
/* Function declarations. */
|
||||
/* Local function declarations. */
|
||||
|
||||
static void init(void) __attribute__((constructor));
|
||||
static void check_threading_library(void);
|
||||
static void vg_set_main_thread_state(void);
|
||||
static void DRD_(init)(void) __attribute__((constructor));
|
||||
static void DRD_(check_threading_library)(void);
|
||||
static void DRD_(set_main_thread_state)(void);
|
||||
|
||||
|
||||
/* Function definitions. */
|
||||
|
||||
/** Shared library initialization function: the _init() function is called
|
||||
* after dlopen() has loaded the shared library. This function must not
|
||||
* be declared static.
|
||||
/**
|
||||
* Shared library initialization function. The function init() is called after
|
||||
* dlopen() has loaded the shared library with DRD client intercepts because
|
||||
* the constructor attribute was specified in the declaration of this function.
|
||||
* Note: do specify the -nostdlib option to gcc when linking this code into a
|
||||
* shared library because doing so would cancel the effect of the constructor
|
||||
* attribute ! Using the gcc option -nodefaultlibs is fine because this last
|
||||
* option preserves the shared library initialization code that calls
|
||||
* constructor and destructor functions.
|
||||
*/
|
||||
static void init(void)
|
||||
static void DRD_(init)(void)
|
||||
{
|
||||
check_threading_library();
|
||||
vg_set_main_thread_state();
|
||||
/* glibc up to and including version 2.8 triggers conflicting accesses */
|
||||
/* on stdout and stderr when sending output to one of these streams from */
|
||||
/* more than one thread. Suppress data race reports on these objects. */
|
||||
DRD_IGNORE_VAR(*stdout);
|
||||
DRD_IGNORE_VAR(*stderr);
|
||||
#if defined(HAVE_LIBC_FILE_LOCK)
|
||||
DRD_IGNORE_VAR(*(pthread_mutex_t*)(stdout->_lock));
|
||||
DRD_IGNORE_VAR(*(pthread_mutex_t*)(stderr->_lock));
|
||||
#endif
|
||||
DRD_(check_threading_library)();
|
||||
DRD_(set_main_thread_state)();
|
||||
}
|
||||
|
||||
static MutexT pthread_to_drd_mutex_type(const int kind)
|
||||
/**
|
||||
* POSIX threads and DRD each have their own mutex type identification.
|
||||
* Convert POSIX threads' mutex type to DRD's mutex type. In the code below
|
||||
* if-statements are used to test the value of 'kind' instead of a switch
|
||||
* statement because some of the PTHREAD_MUTEX_ macro's may have the same
|
||||
* value.
|
||||
*/
|
||||
static MutexT DRD_(pthread_to_drd_mutex_type)(const int kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
/* PTHREAD_MUTEX_RECURSIVE_NP */
|
||||
case PTHREAD_MUTEX_RECURSIVE:
|
||||
if (kind == PTHREAD_MUTEX_RECURSIVE)
|
||||
return mutex_type_recursive_mutex;
|
||||
/* PTHREAD_MUTEX_ERRORCHECK_NP */
|
||||
case PTHREAD_MUTEX_ERRORCHECK:
|
||||
else if (kind == PTHREAD_MUTEX_ERRORCHECK)
|
||||
return mutex_type_errorcheck_mutex;
|
||||
/* PTHREAD_MUTEX_TIMED_NP */
|
||||
/* PTHREAD_MUTEX_NORMAL */
|
||||
case PTHREAD_MUTEX_DEFAULT:
|
||||
#if defined(HAVE_PTHREAD_MUTEX_ADAPTIVE_NP)
|
||||
case PTHREAD_MUTEX_ADAPTIVE_NP:
|
||||
#endif
|
||||
else if (kind == PTHREAD_MUTEX_NORMAL)
|
||||
return mutex_type_default_mutex;
|
||||
else if (kind == PTHREAD_MUTEX_DEFAULT)
|
||||
return mutex_type_default_mutex;
|
||||
#if defined(HAVE_PTHREAD_MUTEX_ADAPTIVE_NP)
|
||||
else if (kind == PTHREAD_MUTEX_ADAPTIVE_NP)
|
||||
return mutex_type_default_mutex;
|
||||
#endif
|
||||
else
|
||||
{
|
||||
return mutex_type_invalid_mutex;
|
||||
}
|
||||
return mutex_type_invalid_mutex;
|
||||
}
|
||||
|
||||
/** @note The function mutex_type() has been declared inline in order
|
||||
* to avoid that it shows up in call stacks.
|
||||
/**
|
||||
* Read the mutex type stored in the client memory used for the mutex
|
||||
* implementation.
|
||||
*
|
||||
* @note This function depends on the implementation of the POSIX threads
|
||||
* library -- the POSIX standard does not define the name of the member in
|
||||
* which the mutex type is stored.
|
||||
* @note The function mutex_type() has been declared inline in order
|
||||
* to avoid that it shows up in call stacks (drd/tests/...exp* files).
|
||||
*/
|
||||
static __inline__ MutexT mutex_type(pthread_mutex_t* mutex)
|
||||
static __inline__ MutexT DRD_(mutex_type)(pthread_mutex_t* mutex)
|
||||
{
|
||||
#if defined(HAVE_PTHREAD_MUTEX_T__M_KIND)
|
||||
/* LinuxThreads. */
|
||||
/* glibc + LinuxThreads. */
|
||||
const int kind = mutex->__m_kind;
|
||||
#elif defined(HAVE_PTHREAD_MUTEX_T__DATA__KIND)
|
||||
/* NPTL. */
|
||||
/* glibc + NPTL. */
|
||||
const int kind = mutex->__data.__kind;
|
||||
#else
|
||||
/* Another POSIX threads implementation. Regression tests will fail. */
|
||||
@ -149,17 +153,13 @@ static __inline__ MutexT mutex_type(pthread_mutex_t* mutex)
|
||||
"Did not recognize your POSIX threads implementation. Giving up.\n");
|
||||
assert(0);
|
||||
#endif
|
||||
return pthread_to_drd_mutex_type(kind);
|
||||
return DRD_(pthread_to_drd_mutex_type)(kind);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void vg_set_joinable(const pthread_t tid, const int joinable)
|
||||
/**
|
||||
* Tell DRD whether 'tid' is a joinable thread or a detached thread.
|
||||
*/
|
||||
static void DRD_(set_joinable)(const pthread_t tid, const int joinable)
|
||||
{
|
||||
int res;
|
||||
assert(joinable == 0 || joinable == 1);
|
||||
@ -167,37 +167,42 @@ static void vg_set_joinable(const pthread_t tid, const int joinable)
|
||||
tid, joinable, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function called from the thread created by pthread_create().
|
||||
*/
|
||||
static void* DRD_(thread_wrapper)(void* arg)
|
||||
{
|
||||
int res;
|
||||
VgPosixThreadArgs* arg_ptr;
|
||||
VgPosixThreadArgs arg_copy;
|
||||
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
|
||||
0, 0, 0, 0, 0);
|
||||
|
||||
{
|
||||
VgPosixThreadArgs* const arg_ptr = (VgPosixThreadArgs*)arg;
|
||||
VgPosixThreadArgs const arg_copy = *arg_ptr;
|
||||
void* result;
|
||||
arg_ptr = (VgPosixThreadArgs*)arg;
|
||||
arg_copy = *arg_ptr;
|
||||
|
||||
#if 0
|
||||
pthread_mutex_lock(arg_ptr->mutex);
|
||||
pthread_cond_signal(arg_ptr->cond);
|
||||
pthread_mutex_unlock(arg_ptr->mutex);
|
||||
#else
|
||||
arg_ptr->wrapper_started = 1;
|
||||
#endif
|
||||
/*
|
||||
* Free the memory 'arg_ptr' points at now such that it does not get
|
||||
* leaked when the function called below throws a C++ exception.
|
||||
*/
|
||||
free(arg_ptr);
|
||||
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
|
||||
pthread_self(), 0, 0, 0, 0);
|
||||
vg_set_joinable(pthread_self(),
|
||||
arg_copy.detachstate == PTHREAD_CREATE_JOINABLE);
|
||||
result = (arg_copy.start)(arg_copy.arg);
|
||||
return result;
|
||||
}
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
|
||||
pthread_self(), 0, 0, 0, 0);
|
||||
|
||||
DRD_(set_joinable)(pthread_self(),
|
||||
arg_copy.detachstate == PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
return (arg_copy.start)(arg_copy.arg);
|
||||
}
|
||||
|
||||
/** Return 1 if LinuxThread has been detected, and 0 otherwise. */
|
||||
static int detected_linuxthreads(void)
|
||||
/**
|
||||
* Return 1 if the LinuxThread implementation has been detected, and 0
|
||||
* otherwise. For more information about the confstr() function, see also
|
||||
* http://www.opengroup.org/onlinepubs/009695399/functions/confstr.html
|
||||
*/
|
||||
static int DRD_(detected_linuxthreads)(void)
|
||||
{
|
||||
#if defined(linux)
|
||||
#if defined(_CS_GNU_LIBPTHREAD_VERSION)
|
||||
@ -217,35 +222,40 @@ static int detected_linuxthreads(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Stop and print an error message in case a non-supported threading
|
||||
* library (LinuxThreads) has been detected.
|
||||
/**
|
||||
* Stop and print an error message in case a non-supported threading
|
||||
* library implementation (LinuxThreads) has been detected.
|
||||
*/
|
||||
static void check_threading_library(void)
|
||||
static void DRD_(check_threading_library)(void)
|
||||
{
|
||||
if (detected_linuxthreads())
|
||||
if (DRD_(detected_linuxthreads)())
|
||||
{
|
||||
if (getenv("LD_ASSUME_KERNEL"))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
|
||||
"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
|
||||
"after having unset the environment variable LD_ASSUME_KERNEL. Giving up.\n"
|
||||
"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
|
||||
"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
|
||||
"after having unset the environment variable LD_ASSUME_KERNEL. Giving up.\n"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
|
||||
"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
|
||||
"after having upgraded to a newer version of your Linux distribution.\n"
|
||||
"Giving up.\n"
|
||||
"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
|
||||
"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
|
||||
"after having upgraded to a newer version of your Linux distribution.\n"
|
||||
"Giving up.\n"
|
||||
);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void vg_set_main_thread_state(void)
|
||||
/**
|
||||
* 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;
|
||||
|
||||
@ -266,55 +276,43 @@ PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
|
||||
int res;
|
||||
int ret;
|
||||
OrigFn fn;
|
||||
VgPosixThreadArgs vgargs;
|
||||
VgPosixThreadArgs* vgargs;
|
||||
|
||||
VALGRIND_GET_ORIG_FN(fn);
|
||||
|
||||
vg_start_suppression(&vgargs.wrapper_started,
|
||||
sizeof(vgargs.wrapper_started));
|
||||
vgargs.start = start;
|
||||
vgargs.arg = arg;
|
||||
vgargs.wrapper_started = 0;
|
||||
vgargs.detachstate = PTHREAD_CREATE_JOINABLE;
|
||||
vgargs = malloc(sizeof *vgargs);
|
||||
assert(vgargs);
|
||||
vgargs->start = start;
|
||||
vgargs->arg = arg;
|
||||
/*
|
||||
* Find out whether the thread will be started as a joinable thread
|
||||
* or as a detached thread. If no thread attributes have been specified,
|
||||
* the new thread will be started as a joinable thread.
|
||||
*/
|
||||
vgargs->detachstate = PTHREAD_CREATE_JOINABLE;
|
||||
if (attr)
|
||||
{
|
||||
if (pthread_attr_getdetachstate(attr, &vgargs.detachstate) != 0)
|
||||
if (pthread_attr_getdetachstate(attr, &vgargs->detachstate) != 0)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
assert(vgargs.detachstate == PTHREAD_CREATE_JOINABLE
|
||||
|| vgargs.detachstate == PTHREAD_CREATE_DETACHED);
|
||||
#if 0
|
||||
pthread_mutex_init(&vgargs.mutex, 0);
|
||||
pthread_cond_init(&vgargs.cond, 0);
|
||||
pthread_mutex_lock(&vgargs.mutex);
|
||||
#endif
|
||||
assert(vgargs->detachstate == PTHREAD_CREATE_JOINABLE
|
||||
|| vgargs->detachstate == PTHREAD_CREATE_DETACHED);
|
||||
|
||||
/* Suppress NPTL-specific conflicts between creator and created thread. */
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_STOP_RECORDING,
|
||||
0, 0, 0, 0, 0);
|
||||
CALL_FN_W_WWWW(ret, fn, thread, attr, DRD_(thread_wrapper), &vgargs);
|
||||
|
||||
CALL_FN_W_WWWW(ret, fn, thread, attr, DRD_(thread_wrapper), vgargs);
|
||||
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_START_RECORDING,
|
||||
0, 0, 0, 0, 0);
|
||||
#if 0
|
||||
pthread_cond_wait(&vgargs.cond, &vgargs.mutex);
|
||||
pthread_mutex_unlock(&vgargs.mutex);
|
||||
pthread_cond_destroy(&vgargs.cond);
|
||||
pthread_mutex_destroy(&vgargs.mutex);
|
||||
#else
|
||||
// Yes, you see it correctly, busy waiting ... The problem is that
|
||||
// POSIX threads functions cannot be called here -- the functions defined
|
||||
// in this file (drd_intercepts.c) would be called instead of those in
|
||||
// libpthread.so. This loop is necessary because vgargs is allocated on the
|
||||
// stack, and the created thread reads it.
|
||||
if (ret == 0)
|
||||
{
|
||||
while (! vgargs.wrapper_started)
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Free the memory 'vgargs' points at if pthread_create() failed. */
|
||||
if (ret != 0)
|
||||
free(vgargs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -346,7 +344,7 @@ PTH_FUNC(int, pthreadZudetach, pthread_t pt_thread)
|
||||
CALL_FN_W_W(ret, fn, pt_thread);
|
||||
if (ret == 0)
|
||||
{
|
||||
vg_set_joinable(pt_thread, 0);
|
||||
DRD_(set_joinable)(pt_thread, 0);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -381,7 +379,8 @@ PTH_FUNC(int, pthreadZumutexZuinit,
|
||||
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);
|
||||
mutex, DRD_(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);
|
||||
@ -400,7 +399,7 @@ PTH_FUNC(int, pthreadZumutexZudestroy,
|
||||
mutex, 0, 0, 0, 0);
|
||||
CALL_FN_W_W(ret, fn, mutex);
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
|
||||
mutex, mutex_type(mutex), 0, 0, 0);
|
||||
mutex, DRD_(mutex_type)(mutex), 0, 0, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -413,7 +412,7 @@ PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
|
||||
OrigFn fn;
|
||||
VALGRIND_GET_ORIG_FN(fn);
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
|
||||
mutex, mutex_type(mutex), 0, 0, 0);
|
||||
mutex, DRD_(mutex_type)(mutex), 0, 0, 0);
|
||||
CALL_FN_W_W(ret, fn, mutex);
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_MUTEX_LOCK,
|
||||
mutex, ret == 0, 0, 0, 0);
|
||||
@ -429,7 +428,7 @@ PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
|
||||
OrigFn fn;
|
||||
VALGRIND_GET_ORIG_FN(fn);
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
|
||||
mutex, mutex_type(mutex), 1, 0, 0);
|
||||
mutex, DRD_(mutex_type)(mutex), 1, 0, 0);
|
||||
CALL_FN_W_W(ret, fn, mutex);
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
|
||||
mutex, ret == 0, 0, 0, 0);
|
||||
@ -446,7 +445,7 @@ PTH_FUNC(int, pthreadZumutexZutimedlock, // pthread_mutex_timedlock
|
||||
OrigFn fn;
|
||||
VALGRIND_GET_ORIG_FN(fn);
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
|
||||
mutex, mutex_type(mutex), 0, 0, 0);
|
||||
mutex, DRD_(mutex_type)(mutex), 0, 0, 0);
|
||||
CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
|
||||
mutex, ret == 0, 0, 0, 0);
|
||||
@ -463,7 +462,7 @@ PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
|
||||
VALGRIND_GET_ORIG_FN(fn);
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, -1,
|
||||
VG_USERREQ__PRE_MUTEX_UNLOCK,
|
||||
mutex, mutex_type(mutex), 0, 0, 0);
|
||||
mutex, DRD_(mutex_type)(mutex), 0, 0, 0);
|
||||
CALL_FN_W_W(ret, fn, mutex);
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, -1,
|
||||
VG_USERREQ__POST_MUTEX_UNLOCK,
|
||||
@ -514,7 +513,7 @@ PTH_FUNC(int, pthreadZucondZuwaitZa, // pthread_cond_wait*
|
||||
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);
|
||||
cond, mutex, DRD_(mutex_type)(mutex), 0, 0);
|
||||
CALL_FN_W_WW(ret, fn, cond, mutex);
|
||||
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
|
||||
cond, mutex, 1, 0, 0);
|
||||
@ -532,7 +531,7 @@ PTH_FUNC(int, pthreadZucondZutimedwaitZa, // pthread_cond_timedwait*
|
||||
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);
|
||||
cond, mutex, DRD_(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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user