]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/valgrind/src/valgrind-3.6.0-svn/drd/drd_pthread_intercepts.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / drd / drd_pthread_intercepts.c
index f3026edd3dfc2aa6f220888a856d9ff8ec611b68..ac648e99887f44a8557e8df1fc990cf01874b452 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: C; c-basic-offset: 3; -*- */
+/* -*- mode: C; c-basic-offset: 3; indent-tabs-mode: nil; -*- */
 
 /*--------------------------------------------------------------------*/
 /*--- Client-space code for DRD.          drd_pthread_intercepts.c ---*/
@@ -7,7 +7,7 @@
 /*
   This file is part of DRD, a thread error detector.
 
-  Copyright (C) 2006-2010 Bart Van Assche <bart.vanassche@gmail.com>.
+  Copyright (C) 2006-2011 Bart Van Assche <bvanassche@acm.org>.
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
@@ -51,6 +51,7 @@
 #include <assert.h>         /* assert() */
 #include <pthread.h>        /* pthread_mutex_t */
 #include <semaphore.h>      /* sem_t */
+#include <stdint.h>         /* uintptr_t */
 #include <stdio.h>          /* fprintf() */
 #include <stdlib.h>         /* malloc(), free() */
 #include <unistd.h>         /* confstr() */
 #include "pub_tool_redir.h" /* VG_WRAP_FUNCTION_ZZ() */
 
 
-/* Defines. */
-
 /*
- * Do not undefine the two macro's below, or the following two subtle race
- * conditions will be introduced in the data race detection algorithm:
- * - sg_init() runs on the context of the created thread and copies the
- *   vector clock of the creator thread. This only works reliably if
- *   the creator thread waits until this copy has been performed.
- * - Since DRD_(thread_compute_minimum_vc)() does not take the vector
- *   clocks into account that are involved in thread creation but
- *   for which the corresponding thread has not yet been created, by
- *   undefining the macro below it becomes possible that segments get
- *   discarded that should not yet be discarded. Or: some data races
- *   are not detected.
+ * Notes regarding thread creation:
+ * - sg_init() runs on the context of the created thread and copies the vector
+ *   clock of the creator thread. This only works reliably if the creator
+ *   thread waits until this copy has been performed.
+ * - DRD_(thread_compute_minimum_vc)() does not take the vector clocks into
+ *   account that are involved in thread creation and for which the
+ *   corresponding thread has not yet been created. So not waiting until the
+ *   created thread has been started would make it possible that segments get
+ *   discarded that should not yet be discarded. Or: some data races are not
+ *   detected.
  */
-#define WAIT_UNTIL_CREATED_THREAD_STARTED
-#define ALLOCATE_THREAD_ARGS_ON_THE_STACK
 
 /**
  * Macro for generating a Valgrind interception function.
  * @param[in] arg_decl Argument declaration list enclosed in parentheses.
  * @param[in] argl Argument list enclosed in parentheses.
  */
+#ifdef VGO_darwin
+static int never_true;
+#define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl)                    \
+   ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl;     \
+   ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl      \
+   {                                                                   \
+      ret_ty pth_func_result = implf argl;                             \
+      /* Apparently inserting a function call in wrapper functions */   \
+      /* is sufficient to avoid misaligned stack errors.           */  \
+      if (never_true)                                                  \
+        fflush(stdout);                                                \
+      return pth_func_result;                                          \
+   }
+#else
 #define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl)                    \
    ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl;     \
    ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl      \
    { return implf argl; }
+#endif
 
 /**
  * Macro for generating three Valgrind interception functions: one with the
@@ -123,9 +134,7 @@ typedef struct
    void* (*start)(void*);
    void* arg;
    int   detachstate;
-#if defined(WAIT_UNTIL_CREATED_THREAD_STARTED)
    int   wrapper_started;
-#endif
 } DrdPosixThreadArgs;
 
 
@@ -181,6 +190,8 @@ static MutexT DRD_(pthread_to_drd_mutex_type)(const int kind)
    }
 }
 
+#define IS_ALIGNED(p) (((uintptr_t)(p) & (sizeof(*(p)) - 1)) == 0)
+
 /**
  * Read the mutex type stored in the client memory used for the mutex
  * implementation.
@@ -198,19 +209,25 @@ static __always_inline MutexT DRD_(mutex_type)(pthread_mutex_t* mutex)
 {
 #if defined(HAVE_PTHREAD_MUTEX_T__M_KIND)
    /* glibc + LinuxThreads. */
-   const int kind = mutex->__m_kind & 3;
-   return DRD_(pthread_to_drd_mutex_type)(kind);
+   if (IS_ALIGNED(&mutex->__m_kind))
+   {
+      const int kind = mutex->__m_kind & 3;
+      return DRD_(pthread_to_drd_mutex_type)(kind);
+   }
 #elif defined(HAVE_PTHREAD_MUTEX_T__DATA__KIND)
    /* glibc + NPTL. */
-   const int kind = mutex->__data.__kind & 3;
-   return DRD_(pthread_to_drd_mutex_type)(kind);
+   if (IS_ALIGNED(&mutex->__data.__kind))
+   {
+      const int kind = mutex->__data.__kind & 3;
+      return DRD_(pthread_to_drd_mutex_type)(kind);
+   }
 #else
    /*
     * Another POSIX threads implementation. The mutex type won't be printed
     * when enabling --trace-mutex=yes.
     */
-   return mutex_type_unknown;
 #endif
+   return mutex_type_unknown;
 }
 
 /**
@@ -218,26 +235,23 @@ static __always_inline MutexT DRD_(mutex_type)(pthread_mutex_t* mutex)
  */
 static void DRD_(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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__SET_JOINABLE,
+                                   tid, joinable, 0, 0, 0);
 }
 
 /** Tell DRD that the calling thread is about to enter pthread_create(). */
 static __always_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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__ENTERING_PTHREAD_CREATE,
+                                   0, 0, 0, 0, 0);
 }
 
 /** Tell DRD that the calling thread has left pthread_create(). */
 static __always_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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__LEFT_PTHREAD_CREATE,
+                                   0, 0, 0, 0, 0);
 }
 
 /**
@@ -246,29 +260,25 @@ static __always_inline void DRD_(left_pthread_create)(void)
  */
 static void* DRD_(thread_wrapper)(void* arg)
 {
-   int res;
    DrdPosixThreadArgs* arg_ptr;
    DrdPosixThreadArgs arg_copy;
 
    arg_ptr = (DrdPosixThreadArgs*)arg;
    arg_copy = *arg_ptr;
-#if defined(WAIT_UNTIL_CREATED_THREAD_STARTED)
-   arg_ptr->wrapper_started = 1;
-#else
-#if defined(ALLOCATE_THREAD_ARGS_ON_THE_STACK)
-#error Defining ALLOCATE_THREAD_ARGS_ON_THE_STACK but not \
-       WAIT_UNTIL_CREATED_THREAD_STARTED is not supported.
-#else
-   free(arg_ptr);
-#endif
-#endif
 
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
-                              pthread_self(), 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__SET_PTHREADID,
+                                   pthread_self(), 0, 0, 0, 0);
 
    DRD_(set_joinable)(pthread_self(),
                       arg_copy.detachstate == PTHREAD_CREATE_JOINABLE);
 
+   /*
+    * Only set 'wrapper_started' after VG_USERREQ__SET_PTHREADID and
+    * DRD_(set_joinable)() have been invoked to avoid a race with
+    * a pthread_detach() invocation for this thread from another thread.
+    */
+   arg_ptr->wrapper_started = 1;
+
    return (arg_copy.start)(arg_copy.arg);
 }
 
@@ -334,11 +344,9 @@ static void DRD_(check_threading_library)(void)
  */
 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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__SET_PTHREADID,
+                                   pthread_self(), 0, 0, 0, 0);
 }
 
 /*
@@ -363,73 +371,43 @@ static __always_inline
 int pthread_create_intercept(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
+   thread_args.start           = start;
+   thread_args.arg             = arg;
+   DRD_IGNORE_VAR(thread_args.wrapper_started);
+   thread_args.wrapper_started = 0;
    /*
     * 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;
+   thread_args.detachstate = PTHREAD_CREATE_JOINABLE;
    if (attr)
    {
-      if (pthread_attr_getdetachstate(attr, &thread_args_p->detachstate) != 0)
-      {
+      if (pthread_attr_getdetachstate(attr, &thread_args.detachstate) != 0)
          assert(0);
-      }
    }
-   assert(thread_args_p->detachstate == PTHREAD_CREATE_JOINABLE
-          || thread_args_p->detachstate == PTHREAD_CREATE_DETACHED);
-
+   assert(thread_args.detachstate == PTHREAD_CREATE_JOINABLE
+          || thread_args.detachstate == PTHREAD_CREATE_DETACHED);
 
    DRD_(entering_pthread_create)();
-   CALL_FN_W_WWWW(ret, fn, thread, attr, DRD_(thread_wrapper), thread_args_p);
+   CALL_FN_W_WWWW(ret, fn, thread, attr, DRD_(thread_wrapper), &thread_args);
    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)
-      {
+      /* Wait until the thread wrapper started. */
+      while (!thread_args.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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__DRD_START_NEW_SEGMENT,
+                                   pthread_self(), 0, 0, 0, 0);
 
    return ret;
 }
@@ -443,15 +421,14 @@ static __always_inline
 int pthread_join_intercept(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);
+      VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_THREAD_JOIN,
+                                      pt_joinee, 0, 0, 0, 0);
    }
    return ret;
 }
@@ -465,14 +442,11 @@ int pthread_detach_intercept(pthread_t pt_thread)
 {
    int ret;
    OrigFn fn;
+
    VALGRIND_GET_ORIG_FN(fn);
-   {
-      CALL_FN_W_W(ret, fn, pt_thread);
-      if (ret == 0)
-      {
-         DRD_(set_joinable)(pt_thread, 0);
-      }
-   }
+   CALL_FN_W_W(ret, fn, pt_thread);
+   DRD_(set_joinable)(pt_thread, 0);
+
    return ret;
 }
 
@@ -485,15 +459,14 @@ PTH_FUNCS(int, pthreadZudetach, pthread_detach_intercept,
 static __always_inline
 int pthread_cancel_intercept(pthread_t pt_thread)
 {
-   int res;
    int ret;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_THREAD_CANCEL,
-                              pt_thread, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_THREAD_CANCEL,
+                                   pt_thread, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, pt_thread);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_CANCEL,
-                              pt_thread, ret==0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_THREAD_CANCEL,
+                                   pt_thread, ret==0, 0, 0, 0);
    return ret;
 }
 
@@ -527,19 +500,18 @@ int pthread_mutex_init_intercept(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, DRD_(pthread_to_drd_mutex_type)(mt),
-                              0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_MUTEX_INIT,
+                                   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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_MUTEX_INIT,
+                                   mutex, 0, 0, 0, 0);
    return ret;
 }
 
@@ -551,14 +523,13 @@ static __always_inline
 int pthread_mutex_destroy_intercept(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_DESTROY,
-                              mutex, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_MUTEX_DESTROY,
+                                   mutex, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, mutex);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
-                              mutex, DRD_(mutex_type)(mutex), 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_MUTEX_DESTROY,
+                                   mutex, DRD_(mutex_type)(mutex), 0, 0, 0);
    return ret;
 }
 
@@ -569,14 +540,13 @@ static __always_inline
 int pthread_mutex_lock_intercept(pthread_mutex_t* mutex)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
-                              mutex, DRD_(mutex_type)(mutex), 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__PRE_MUTEX_LOCK,
+                                   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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__POST_MUTEX_LOCK,
+                                   mutex, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -587,14 +557,13 @@ static __always_inline
 int pthread_mutex_trylock_intercept(pthread_mutex_t* mutex)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
-                              mutex, DRD_(mutex_type)(mutex), 1, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__PRE_MUTEX_LOCK,
+                                   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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_MUTEX_LOCK,
+                                   mutex, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -606,14 +575,13 @@ int pthread_mutex_timedlock_intercept(pthread_mutex_t *mutex,
                                       const struct timespec *abs_timeout)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
-                              mutex, DRD_(mutex_type)(mutex), 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__PRE_MUTEX_LOCK,
+                                   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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_MUTEX_LOCK,
+                                   mutex, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -625,16 +593,13 @@ static __always_inline
 int pthread_mutex_unlock_intercept(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, DRD_(mutex_type)(mutex), 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_MUTEX_UNLOCK,
+                                   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,
-                              mutex, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_MUTEX_UNLOCK,
+                                   mutex, 0, 0, 0, 0);
    return ret;
 }
 
@@ -646,14 +611,13 @@ int pthread_cond_init_intercept(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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_COND_INIT,
+                                   cond, 0, 0, 0, 0);
    CALL_FN_W_WW(ret, fn, cond, attr);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_INIT,
-                              cond, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_COND_INIT,
+                                   cond, 0, 0, 0, 0);
    return ret;
 }
 
@@ -665,14 +629,13 @@ static __always_inline
 int pthread_cond_destroy_intercept(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_DESTROY,
-                              cond, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_COND_DESTROY,
+                                   cond, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, cond);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_DESTROY,
-                              cond, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_COND_DESTROY,
+                                   cond, 0, 0, 0, 0);
    return ret;
 }
 
@@ -683,14 +646,13 @@ static __always_inline
 int pthread_cond_wait_intercept(pthread_cond_t *cond, pthread_mutex_t *mutex)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
-                              cond, mutex, DRD_(mutex_type)(mutex), 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_COND_WAIT,
+                                   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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_COND_WAIT,
+                                   cond, mutex, 1, 0, 0);
    return ret;
 }
 
@@ -704,14 +666,13 @@ int pthread_cond_timedwait_intercept(pthread_cond_t *cond,
                                      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, DRD_(mutex_type)(mutex), 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_COND_WAIT,
+                                   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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_COND_WAIT,
+                                   cond, mutex, 1, 0, 0);
    return ret;
 }
 
@@ -730,14 +691,13 @@ static __always_inline
 int pthread_cond_signal_intercept(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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_COND_SIGNAL,
+                                   cond, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, cond);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_SIGNAL,
-                              cond, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_COND_SIGNAL,
+                                   cond, 0, 0, 0, 0);
    return ret;
 }
 
@@ -748,14 +708,13 @@ static __always_inline
 int pthread_cond_broadcast_intercept(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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_COND_BROADCAST,
+                                   cond, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, cond);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_BROADCAST,
-                              cond, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_COND_BROADCAST,
+                                   cond, 0, 0, 0, 0);
    return ret;
 }
 
@@ -767,14 +726,13 @@ static __always_inline
 int pthread_spin_init_intercept(pthread_spinlock_t *spinlock, int pshared)
 {
    int ret;
-   int res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
-                              spinlock, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
+                                   spinlock, 0, 0, 0, 0);
    CALL_FN_W_WW(ret, fn, spinlock, pshared);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
-                              spinlock, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
+                                   spinlock, 0, 0, 0, 0);
    return ret;
 }
 
@@ -785,14 +743,13 @@ static __always_inline
 int pthread_spin_destroy_intercept(pthread_spinlock_t *spinlock)
 {
    int ret;
-   int res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
-                              spinlock, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_MUTEX_DESTROY,
+                                   spinlock, 0, 0, 0, 0);
    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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_MUTEX_DESTROY,
+                                   spinlock, mutex_type_spinlock, 0, 0, 0);
    return ret;
 }
 
@@ -803,14 +760,13 @@ static __always_inline
 int pthread_spin_lock_intercept(pthread_spinlock_t *spinlock)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
-                              spinlock, mutex_type_spinlock, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__PRE_MUTEX_LOCK,
+                                   spinlock, mutex_type_spinlock, 0, 0, 0);
    CALL_FN_W_W(ret, fn, spinlock);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
-                              spinlock, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_MUTEX_LOCK,
+                                   spinlock, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -821,14 +777,13 @@ static __always_inline
 int pthread_spin_trylock_intercept(pthread_spinlock_t *spinlock)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
-                              spinlock, mutex_type_spinlock, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__PRE_MUTEX_LOCK,
+                                   spinlock, mutex_type_spinlock, 0, 0, 0);
    CALL_FN_W_W(ret, fn, spinlock);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
-                              spinlock, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_MUTEX_LOCK,
+                                   spinlock, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -839,14 +794,13 @@ static __always_inline
 int pthread_spin_unlock_intercept(pthread_spinlock_t *spinlock)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
-                              spinlock, mutex_type_spinlock, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
+                                   spinlock, mutex_type_spinlock, 0, 0, 0);
    CALL_FN_W_W(ret, fn, spinlock);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
-                              spinlock, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
+                                   spinlock, 0, 0, 0, 0);
    return ret;
 }
 
@@ -862,14 +816,13 @@ int pthread_barrier_init_intercept(pthread_barrier_t* barrier,
                                    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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_BARRIER_INIT,
+                                   barrier, pthread_barrier, 0, 0, 0);
    return ret;
 }
 
@@ -881,14 +834,13 @@ static __always_inline
 int pthread_barrier_destroy_intercept(pthread_barrier_t* barrier)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_DESTROY,
-                              barrier, pthread_barrier, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_BARRIER_DESTROY,
+                                   barrier, pthread_barrier, 0, 0, 0);
    CALL_FN_W_W(ret, fn, barrier);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_DESTROY,
-                              barrier, pthread_barrier, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_BARRIER_DESTROY,
+                                   barrier, pthread_barrier, 0, 0, 0);
    return ret;
 }
 
@@ -899,13 +851,12 @@ static __always_inline
 int pthread_barrier_wait_intercept(pthread_barrier_t* barrier)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT,
-                              barrier, pthread_barrier, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_BARRIER_WAIT,
+                                   barrier, pthread_barrier, 0, 0, 0);
    CALL_FN_W_W(ret, fn, barrier);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_BARRIER_WAIT,
                               barrier, pthread_barrier,
                               ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
                               ret == PTHREAD_BARRIER_SERIAL_THREAD, 0);
@@ -921,14 +872,13 @@ static __always_inline
 int sem_init_intercept(sem_t *sem, int pshared, unsigned int value)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_INIT,
-                              sem, pshared, value, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_SEM_INIT,
+                                   sem, pshared, value, 0, 0);
    CALL_FN_W_WWW(ret, fn, sem, pshared, value);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_INIT,
-                              sem, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_SEM_INIT,
+                                   sem, 0, 0, 0, 0);
    return ret;
 }
 
@@ -939,14 +889,13 @@ static __always_inline
 int sem_destroy_intercept(sem_t *sem)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_DESTROY,
-                              sem, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_SEM_DESTROY,
+                                   sem, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, sem);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_DESTROY,
-                              sem, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_SEM_DESTROY,
+                                   sem, 0, 0, 0, 0);
    return ret;
 }
 
@@ -957,15 +906,14 @@ sem_t* sem_open_intercept(const char *name, int oflag, mode_t mode,
                           unsigned int value)
 {
    sem_t *ret;
-   int    res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_OPEN,
-                              name, oflag, mode, value, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_SEM_OPEN,
+                                   name, oflag, mode, value, 0);
    CALL_FN_W_WWWW(ret, fn, name, oflag, mode, value);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_OPEN,
-                              ret != SEM_FAILED ? ret : 0,
-                              name, oflag, mode, value);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_SEM_OPEN,
+                                   ret != SEM_FAILED ? ret : 0,
+                                   name, oflag, mode, value);
    return ret;
 }
 
@@ -976,14 +924,13 @@ PTH_FUNCS(sem_t *, semZuopen, sem_open_intercept,
 static __always_inline int sem_close_intercept(sem_t *sem)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_CLOSE,
-                              sem, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_SEM_CLOSE,
+                                   sem, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, sem);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_CLOSE,
-                              sem, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_SEM_CLOSE,
+                                   sem, 0, 0, 0, 0);
    return ret;
 }
 
@@ -992,14 +939,13 @@ PTH_FUNCS(int, semZuclose, sem_close_intercept, (sem_t *sem), (sem));
 static __always_inline int sem_wait_intercept(sem_t *sem)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
-                              sem, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_SEM_WAIT,
+                                   sem, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, sem);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
-                              sem, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_SEM_WAIT,
+                                   sem, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -1008,14 +954,13 @@ PTH_FUNCS(int, semZuwait, sem_wait_intercept, (sem_t *sem), (sem));
 static __always_inline int sem_trywait_intercept(sem_t *sem)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
-                              sem, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_SEM_WAIT,
+                                   sem, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, sem);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
-                              sem, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_SEM_WAIT,
+                                   sem, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -1025,14 +970,13 @@ static __always_inline
 int sem_timedwait_intercept(sem_t *sem, const struct timespec *abs_timeout)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
-                              sem, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_SEM_WAIT,
+                                   sem, 0, 0, 0, 0);
    CALL_FN_W_WW(ret, fn, sem, abs_timeout);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
-                              sem, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_SEM_WAIT,
+                                   sem, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -1043,14 +987,13 @@ PTH_FUNCS(int, semZutimedwait, sem_timedwait_intercept,
 static __always_inline int sem_post_intercept(sem_t *sem)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
-                              sem, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_SEM_POST,
+                                   sem, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, sem);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
-                              sem, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_SEM_POST,
+                                   sem, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -1061,11 +1004,10 @@ int pthread_rwlock_init_intercept(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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_RWLOCK_INIT,
+                                   rwlock, 0, 0, 0, 0);
    CALL_FN_W_WW(ret, fn, rwlock, attr);
    return ret;
 }
@@ -1079,12 +1021,11 @@ static __always_inline
 int pthread_rwlock_destroy_intercept(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);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_RWLOCK_DESTROY,
+                                   rwlock, 0, 0, 0, 0);
    return ret;
 }
 
@@ -1096,14 +1037,13 @@ static __always_inline
 int pthread_rwlock_rdlock_intercept(pthread_rwlock_t* rwlock)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
-                              rwlock, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
+                                   rwlock, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, rwlock);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
-                              rwlock, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_RWLOCK_RDLOCK,
+                                   rwlock, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -1115,14 +1055,13 @@ static __always_inline
 int pthread_rwlock_wrlock_intercept(pthread_rwlock_t* rwlock)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
-                              rwlock, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
+                                   rwlock, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, rwlock);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
-                              rwlock, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_RWLOCK_WRLOCK,
+                                   rwlock, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -1134,14 +1073,13 @@ static __always_inline
 int pthread_rwlock_timedrdlock_intercept(pthread_rwlock_t* rwlock)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
-                              rwlock, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
+                                   rwlock, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, rwlock);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
-                              rwlock, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_RWLOCK_RDLOCK,
+                                   rwlock, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -1153,14 +1091,13 @@ static __always_inline
 int pthread_rwlock_timedwrlock_intercept(pthread_rwlock_t* rwlock)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
-                              rwlock, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
+                                   rwlock, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, rwlock);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
-                              rwlock, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_RWLOCK_WRLOCK,
+                                   rwlock, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -1172,14 +1109,13 @@ static __always_inline
 int pthread_rwlock_tryrdlock_intercept(pthread_rwlock_t* rwlock)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
-                              rwlock, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
+                                   rwlock, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, rwlock);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
-                              rwlock, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_RWLOCK_RDLOCK,
+                                   rwlock, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -1191,14 +1127,13 @@ static __always_inline
 int pthread_rwlock_trywrlock_intercept(pthread_rwlock_t* rwlock)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
-                              rwlock, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
+                                   rwlock, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, rwlock);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
-                              rwlock, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_RWLOCK_WRLOCK,
+                                   rwlock, ret == 0, 0, 0, 0);
    return ret;
 }
 
@@ -1210,14 +1145,13 @@ static __always_inline
 int pthread_rwlock_unlock_intercept(pthread_rwlock_t* rwlock)
 {
    int   ret;
-   int   res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_UNLOCK,
-                              rwlock, 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__PRE_RWLOCK_UNLOCK,
+                                   rwlock, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, rwlock);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_UNLOCK,
-                              rwlock, ret == 0, 0, 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST_EXPR(-1, VG_USERREQ__POST_RWLOCK_UNLOCK,
+                                   rwlock, ret == 0, 0, 0, 0);
    return ret;
 }