blob: aabac05894923aa3391da5a3027020d26ebb5c87 [file] [log] [blame]
sewardjaf44c822007-11-25 14:01:38 +00001
2/*--------------------------------------------------------------------*/
sewardj85642922008-01-14 11:54:56 +00003/*--- Client-space code for drd. drd_intercepts.c ---*/
sewardjaf44c822007-11-25 14:01:38 +00004/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of drd, a data race detector.
8
sewardj85642922008-01-14 11:54:56 +00009 Copyright (C) 2006-2008 Bart Van Assche
sewardjaf44c822007-11-25 14:01:38 +000010 bart.vanassche@gmail.com
11
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 02111-1307, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28*/
29
30/* ---------------------------------------------------------------------
31 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
32
33 These functions are not called directly - they're the targets of code
34 redirection or load notifications (see pub_core_redir.h for info).
35 They're named weirdly so that the intercept code can find them when the
36 shared object is initially loaded.
37
38 Note that this filename has the "drd_" prefix because it can appear
39 in stack traces, and the "drd_" makes it a little clearer that it
40 originates from Valgrind.
41 ------------------------------------------------------------------ */
42
bart5e85d262008-03-01 10:49:37 +000043// Make sure pthread_spinlock_t is available when compiling with older glibc
44// versions (2.3 or before).
sewardjaf44c822007-11-25 14:01:38 +000045#ifndef _GNU_SOURCE
46#define _GNU_SOURCE
47#endif
48
49#include <assert.h>
bart4501d5c2008-03-04 18:36:23 +000050#include <inttypes.h> // uintptr_t
sewardj85642922008-01-14 11:54:56 +000051#include <pthread.h>
52#include <semaphore.h>
sewardjaf44c822007-11-25 14:01:38 +000053#include <stdio.h>
bart0d063002008-03-01 07:25:13 +000054#include <stdlib.h>
bart4501d5c2008-03-04 18:36:23 +000055#include <unistd.h> // confstr()
sewardjaf44c822007-11-25 14:01:38 +000056#include "drd_clientreq.h"
sewardj85642922008-01-14 11:54:56 +000057#include "pub_tool_redir.h"
sewardjaf44c822007-11-25 14:01:38 +000058
59
60// Defines.
61
bart3772a982008-03-15 08:11:03 +000062#define PTH_FUNC(ret_ty, f, args...) \
63 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args); \
64 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args)
sewardjaf44c822007-11-25 14:01:38 +000065
66
bart6f07b252008-04-04 16:45:20 +000067/* Local data structures. */
sewardjaf44c822007-11-25 14:01:38 +000068
69typedef struct
70{
bart3772a982008-03-15 08:11:03 +000071 void* (*start)(void*);
72 void* arg;
73 int detachstate;
sewardjaf44c822007-11-25 14:01:38 +000074#if 0
bart3772a982008-03-15 08:11:03 +000075 pthread_mutex_t mutex;
76 pthread_cond_t cond;
sewardjaf44c822007-11-25 14:01:38 +000077#else
bart3772a982008-03-15 08:11:03 +000078 int wrapper_started;
sewardjaf44c822007-11-25 14:01:38 +000079#endif
80} VgPosixThreadArgs;
81
82
bart6f07b252008-04-04 16:45:20 +000083/* Function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000084
bart6f07b252008-04-04 16:45:20 +000085void _init(void);
86static void check_threading_library(void);
87static void vg_set_main_thread_state(void);
sewardjaf44c822007-11-25 14:01:38 +000088
89
bart6f07b252008-04-04 16:45:20 +000090/* Function definitions. */
91
92/** Shared library initialization function: the _init() function is called
93 * after dlopen() has loaded the shared library. This function must not
94 * be declared static.
95 */
96void _init(void)
97{
98 check_threading_library();
99 vg_set_main_thread_state();
100}
sewardjaf44c822007-11-25 14:01:38 +0000101
bart5357fcb2008-02-27 15:46:00 +0000102static MutexT pthread_to_drd_mutex_type(const int kind)
103{
bart3772a982008-03-15 08:11:03 +0000104 switch (kind)
105 {
106 /* PTHREAD_MUTEX_RECURSIVE_NP */
107 case PTHREAD_MUTEX_RECURSIVE:
108 return mutex_type_recursive_mutex;
109 /* PTHREAD_MUTEX_ERRORCHECK_NP */
110 case PTHREAD_MUTEX_ERRORCHECK:
111 return mutex_type_errorcheck_mutex;
112 /* PTHREAD_MUTEX_TIMED_NP */
113 /* PTHREAD_MUTEX_NORMAL */
114 case PTHREAD_MUTEX_DEFAULT:
115 case PTHREAD_MUTEX_ADAPTIVE_NP:
116 return mutex_type_default_mutex;
117 }
118 return mutex_type_invalid_mutex;
bart5357fcb2008-02-27 15:46:00 +0000119}
120
121static MutexT mutex_type(pthread_mutex_t* mutex)
122{
bartc9463c42008-02-28 07:36:04 +0000123#if defined(_PTHREAD_DESCR_DEFINED)
bart3772a982008-03-15 08:11:03 +0000124 // Linuxthreads.
125 const int kind = mutex->__m_kind;
bartc9463c42008-02-28 07:36:04 +0000126#elif defined(__SIZEOF_PTHREAD_MUTEX_T)
bart3772a982008-03-15 08:11:03 +0000127 // NPTL.
128 const int kind = mutex->__data.__kind;
bartc9463c42008-02-28 07:36:04 +0000129#else
bart3772a982008-03-15 08:11:03 +0000130 // Another POSIX threads implementation. Regression tests will fail.
131 const int kind = PTHREAD_MUTEX_DEFAULT;
bartc9463c42008-02-28 07:36:04 +0000132#endif
bart3772a982008-03-15 08:11:03 +0000133 return pthread_to_drd_mutex_type(kind);
bart5357fcb2008-02-27 15:46:00 +0000134}
135
sewardjaf44c822007-11-25 14:01:38 +0000136static void vg_start_suppression(const void* const p, size_t const size)
137{
bart3772a982008-03-15 08:11:03 +0000138 int res;
139 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
bartf5bb46a2008-03-29 13:18:02 +0000140 p, size, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000141}
142
143static void vg_set_joinable(const pthread_t tid, const int joinable)
144{
bart3772a982008-03-15 08:11:03 +0000145 int res;
146 assert(joinable == 0 || joinable == 1);
147 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_JOINABLE,
148 tid, joinable, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000149}
150
151static void* vg_thread_wrapper(void* arg)
152{
bart3772a982008-03-15 08:11:03 +0000153 int res;
bart0d063002008-03-01 07:25:13 +0000154
bart3772a982008-03-15 08:11:03 +0000155 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
156 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000157
bart3772a982008-03-15 08:11:03 +0000158 {
159 VgPosixThreadArgs* const arg_ptr = (VgPosixThreadArgs*)arg;
160 VgPosixThreadArgs const arg_copy = *arg_ptr;
161 void* result;
sewardjaf44c822007-11-25 14:01:38 +0000162
163#if 0
bart3772a982008-03-15 08:11:03 +0000164 pthread_mutex_lock(arg_ptr->mutex);
165 pthread_cond_signal(arg_ptr->cond);
166 pthread_mutex_unlock(arg_ptr->mutex);
sewardjaf44c822007-11-25 14:01:38 +0000167#else
bart3772a982008-03-15 08:11:03 +0000168 arg_ptr->wrapper_started = 1;
sewardjaf44c822007-11-25 14:01:38 +0000169#endif
170
bart3772a982008-03-15 08:11:03 +0000171 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
172 pthread_self(), 0, 0, 0, 0);
173 vg_set_joinable(pthread_self(),
174 arg_copy.detachstate == PTHREAD_CREATE_JOINABLE);
175 result = (arg_copy.start)(arg_copy.arg);
176 return result;
177 }
sewardjaf44c822007-11-25 14:01:38 +0000178}
179
bart6f07b252008-04-04 16:45:20 +0000180/** Return 1 if LinuxThread has been detected, and 0 otherwise. */
bart4501d5c2008-03-04 18:36:23 +0000181static int detected_linuxthreads(void)
182{
183#if defined(linux)
184#if defined(_CS_GNU_LIBPTHREAD_VERSION)
bart3772a982008-03-15 08:11:03 +0000185 /* Linux with a recent glibc. */
186 char buffer[256];
187 unsigned len;
188 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
189 assert(len <= sizeof(buffer));
190 return len > 0 && buffer[0] == 'l';
bart4501d5c2008-03-04 18:36:23 +0000191#else
bart3772a982008-03-15 08:11:03 +0000192 /* Linux without _CS_GNU_LIBPTHREAD_VERSION: most likely LinuxThreads. */
193 return 1;
bart4501d5c2008-03-04 18:36:23 +0000194#endif
195#else
bart3772a982008-03-15 08:11:03 +0000196 /* Another OS than Linux, hence no LinuxThreads. */
197 return 0;
bart4501d5c2008-03-04 18:36:23 +0000198#endif
199}
200
bart6f07b252008-04-04 16:45:20 +0000201/** Stop and print an error message in case a non-supported threading
202 * library (LinuxThreads) has been detected.
203 */
204static void check_threading_library(void)
sewardjaf44c822007-11-25 14:01:38 +0000205{
bart3772a982008-03-15 08:11:03 +0000206 if (detected_linuxthreads())
207 {
208 if (getenv("LD_ASSUME_KERNEL"))
209 {
210 fprintf(stderr,
211 "Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
212 "the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
213 "after having unset the environment variable LD_ASSUME_KERNEL. Giving up.\n"
214 );
215 }
216 else
217 {
218 fprintf(stderr,
219 "Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
220 "the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
221 "after having upgraded to a newer version of your Linux distribution.\n"
222 "Giving up.\n"
223 );
224 }
225 abort();
226 }
bart6f07b252008-04-04 16:45:20 +0000227}
228
229static void vg_set_main_thread_state(void)
230{
231 int res;
bart0d063002008-03-01 07:25:13 +0000232
bart3772a982008-03-15 08:11:03 +0000233 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
234 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000235
bart3772a982008-03-15 08:11:03 +0000236 // Make sure that DRD knows about the main thread's POSIX thread ID.
237 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
238 pthread_self(), 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000239
240}
241
242// pthread_create
sewardj347eeba2008-01-21 14:19:07 +0000243PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
bart3772a982008-03-15 08:11:03 +0000244 pthread_t *thread, const pthread_attr_t *attr,
245 void *(*start) (void *), void *arg)
sewardjaf44c822007-11-25 14:01:38 +0000246{
bart3772a982008-03-15 08:11:03 +0000247 int ret;
248 OrigFn fn;
249 VgPosixThreadArgs vgargs;
sewardjaf44c822007-11-25 14:01:38 +0000250
bart3772a982008-03-15 08:11:03 +0000251 VALGRIND_GET_ORIG_FN(fn);
sewardjaf44c822007-11-25 14:01:38 +0000252
bart3772a982008-03-15 08:11:03 +0000253 vg_start_suppression(&vgargs.wrapper_started,
254 sizeof(vgargs.wrapper_started));
255 vgargs.start = start;
256 vgargs.arg = arg;
257 vgargs.wrapper_started = 0;
258 vgargs.detachstate = PTHREAD_CREATE_JOINABLE;
259 if (attr)
260 {
261 if (pthread_attr_getdetachstate(attr, &vgargs.detachstate) != 0)
262 {
263 assert(0);
264 }
265 }
266 assert(vgargs.detachstate == PTHREAD_CREATE_JOINABLE
267 || vgargs.detachstate == PTHREAD_CREATE_DETACHED);
sewardjaf44c822007-11-25 14:01:38 +0000268#if 0
bart3772a982008-03-15 08:11:03 +0000269 pthread_mutex_init(&vgargs.mutex, 0);
270 pthread_cond_init(&vgargs.cond, 0);
271 pthread_mutex_lock(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000272#endif
bart3772a982008-03-15 08:11:03 +0000273 CALL_FN_W_WWWW(ret, fn, thread, attr, vg_thread_wrapper, &vgargs);
sewardjaf44c822007-11-25 14:01:38 +0000274#if 0
bart3772a982008-03-15 08:11:03 +0000275 pthread_cond_wait(&vgargs.cond, &vgargs.mutex);
276 pthread_mutex_unlock(&vgargs.mutex);
277 pthread_cond_destroy(&vgargs.cond);
278 pthread_mutex_destroy(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000279#else
bart3772a982008-03-15 08:11:03 +0000280 // Yes, you see it correctly, busy waiting ... The problem is that
281 // POSIX threads functions cannot be called here -- the functions defined
282 // in this file (drd_intercepts.c) would be called instead of those in
283 // libpthread.so. This loop is necessary because vgargs is allocated on the
284 // stack, and the created thread reads it.
285 if (ret == 0)
286 {
287 while (! vgargs.wrapper_started)
288 {
289 sched_yield();
290 }
291 }
sewardjaf44c822007-11-25 14:01:38 +0000292#endif
bart3772a982008-03-15 08:11:03 +0000293 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000294}
295
296// pthread_join
297PTH_FUNC(int, pthreadZujoin, // pthread_join
bart3772a982008-03-15 08:11:03 +0000298 pthread_t pt_joinee, void **thread_return)
sewardjaf44c822007-11-25 14:01:38 +0000299{
bart3772a982008-03-15 08:11:03 +0000300 int ret;
301 int res;
302 OrigFn fn;
sewardjaf44c822007-11-25 14:01:38 +0000303
bart3772a982008-03-15 08:11:03 +0000304 VALGRIND_GET_ORIG_FN(fn);
305 CALL_FN_W_WW(ret, fn, pt_joinee, thread_return);
306 if (ret == 0)
307 {
308 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_JOIN,
309 pt_joinee, 0, 0, 0, 0);
310 }
311 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000312}
313
314// pthread_detach
315PTH_FUNC(int, pthreadZudetach, pthread_t pt_thread)
316{
bart3772a982008-03-15 08:11:03 +0000317 int ret;
318 OrigFn fn;
319 VALGRIND_GET_ORIG_FN(fn);
320 {
321 CALL_FN_W_W(ret, fn, pt_thread);
322 if (ret == 0)
323 {
324 vg_set_joinable(pt_thread, 0);
325 }
326 }
327 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000328}
329
330// pthread_mutex_init
331PTH_FUNC(int, pthreadZumutexZuinit,
bart3772a982008-03-15 08:11:03 +0000332 pthread_mutex_t *mutex,
333 const pthread_mutexattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000334{
bart3772a982008-03-15 08:11:03 +0000335 int ret;
336 int res;
337 OrigFn fn;
338 int mt;
339 VALGRIND_GET_ORIG_FN(fn);
340 mt = PTHREAD_MUTEX_DEFAULT;
341 if (attr)
342 pthread_mutexattr_gettype(attr, &mt);
343 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
344 mutex, pthread_to_drd_mutex_type(mt), 0, 0, 0);
345 CALL_FN_W_WW(ret, fn, mutex, attr);
346 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT,
347 mutex, 0, 0, 0, 0);
348 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000349}
350
351// pthread_mutex_destroy
352PTH_FUNC(int, pthreadZumutexZudestroy,
bart3772a982008-03-15 08:11:03 +0000353 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000354{
bart3772a982008-03-15 08:11:03 +0000355 int ret;
356 int res;
357 OrigFn fn;
358 VALGRIND_GET_ORIG_FN(fn);
359 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
360 mutex, 0, 0, 0, 0);
361 CALL_FN_W_W(ret, fn, mutex);
362 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
363 mutex, mutex_type(mutex), 0, 0, 0);
364 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000365}
366
367// pthread_mutex_lock
368PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
bart3772a982008-03-15 08:11:03 +0000369 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000370{
bart3772a982008-03-15 08:11:03 +0000371 int ret;
372 int res;
373 OrigFn fn;
374 VALGRIND_GET_ORIG_FN(fn);
375 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
376 mutex, mutex_type(mutex), 0, 0, 0);
377 CALL_FN_W_W(ret, fn, mutex);
378 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_MUTEX_LOCK,
379 mutex, ret == 0, 0, 0, 0);
380 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000381}
382
383// pthread_mutex_trylock
384PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
bart3772a982008-03-15 08:11:03 +0000385 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000386{
bart3772a982008-03-15 08:11:03 +0000387 int ret;
388 int res;
389 OrigFn fn;
390 VALGRIND_GET_ORIG_FN(fn);
391 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
bart2e3a3c12008-03-24 08:33:47 +0000392 mutex, mutex_type(mutex), 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000393 CALL_FN_W_W(ret, fn, mutex);
394 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
395 mutex, ret == 0, 0, 0, 0);
396 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000397}
398
sewardj85642922008-01-14 11:54:56 +0000399// pthread_mutex_timedlock
400PTH_FUNC(int, pthreadZumutexZutimedlock, // pthread_mutex_timedlock
bart3772a982008-03-15 08:11:03 +0000401 pthread_mutex_t *mutex,
402 const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000403{
bart3772a982008-03-15 08:11:03 +0000404 int ret;
405 int res;
406 OrigFn fn;
407 VALGRIND_GET_ORIG_FN(fn);
408 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
409 mutex, mutex_type(mutex), 0, 0, 0);
410 CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
411 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
412 mutex, ret == 0, 0, 0, 0);
413 return ret;
sewardj85642922008-01-14 11:54:56 +0000414}
415
sewardjaf44c822007-11-25 14:01:38 +0000416// pthread_mutex_unlock
417PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
bart3772a982008-03-15 08:11:03 +0000418 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000419{
bart3772a982008-03-15 08:11:03 +0000420 int ret;
421 int res;
422 OrigFn fn;
423 VALGRIND_GET_ORIG_FN(fn);
424 VALGRIND_DO_CLIENT_REQUEST(res, -1,
425 VG_USERREQ__PRE_MUTEX_UNLOCK,
426 mutex, mutex_type(mutex), 0, 0, 0);
427 CALL_FN_W_W(ret, fn, mutex);
428 VALGRIND_DO_CLIENT_REQUEST(res, -1,
429 VG_USERREQ__POST_MUTEX_UNLOCK,
430 mutex, 0, 0, 0, 0);
431 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000432}
433
434// pthread_cond_init
sewardj347eeba2008-01-21 14:19:07 +0000435PTH_FUNC(int, pthreadZucondZuinitZa, // pthread_cond_init*
bart3772a982008-03-15 08:11:03 +0000436 pthread_cond_t* cond,
437 const pthread_condattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000438{
bart3772a982008-03-15 08:11:03 +0000439 int ret;
440 int res;
441 OrigFn fn;
442 VALGRIND_GET_ORIG_FN(fn);
443 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_INIT,
444 cond, 0, 0, 0, 0);
445 CALL_FN_W_WW(ret, fn, cond, attr);
446 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000447}
448
449// pthread_cond_destroy
sewardj347eeba2008-01-21 14:19:07 +0000450PTH_FUNC(int, pthreadZucondZudestroyZa, // pthread_cond_destroy*
bart3772a982008-03-15 08:11:03 +0000451 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000452{
bart3772a982008-03-15 08:11:03 +0000453 int ret;
454 int res;
455 OrigFn fn;
456 VALGRIND_GET_ORIG_FN(fn);
457 CALL_FN_W_W(ret, fn, cond);
458 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_DESTROY,
459 cond, 0, 0, 0, 0);
460 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000461}
462
463// pthread_cond_wait
sewardj347eeba2008-01-21 14:19:07 +0000464PTH_FUNC(int, pthreadZucondZuwaitZa, // pthread_cond_wait*
bart3772a982008-03-15 08:11:03 +0000465 pthread_cond_t *cond,
466 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000467{
bart3772a982008-03-15 08:11:03 +0000468 int ret;
469 int res;
470 OrigFn fn;
471 VALGRIND_GET_ORIG_FN(fn);
472 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
473 cond, mutex, mutex_type(mutex), 0, 0);
474 CALL_FN_W_WW(ret, fn, cond, mutex);
475 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000476 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000477 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000478}
479
480// pthread_cond_timedwait
sewardj347eeba2008-01-21 14:19:07 +0000481PTH_FUNC(int, pthreadZucondZutimedwaitZa, // pthread_cond_timedwait*
bart3772a982008-03-15 08:11:03 +0000482 pthread_cond_t *cond,
483 pthread_mutex_t *mutex,
484 const struct timespec* abstime)
sewardjaf44c822007-11-25 14:01:38 +0000485{
bart3772a982008-03-15 08:11:03 +0000486 int ret;
487 int res;
488 OrigFn fn;
489 VALGRIND_GET_ORIG_FN(fn);
490 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
491 cond, mutex, mutex_type(mutex), 0, 0);
492 CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
493 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000494 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000495 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000496}
497
498// pthread_cond_signal
sewardj347eeba2008-01-21 14:19:07 +0000499PTH_FUNC(int, pthreadZucondZusignalZa, // pthread_cond_signal*
bart3772a982008-03-15 08:11:03 +0000500 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000501{
bart3772a982008-03-15 08:11:03 +0000502 int ret;
503 int res;
504 OrigFn fn;
505 VALGRIND_GET_ORIG_FN(fn);
506 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_SIGNAL,
507 cond, 0, 0, 0, 0);
508 CALL_FN_W_W(ret, fn, cond);
509 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000510}
511
512// pthread_cond_broadcast
sewardj347eeba2008-01-21 14:19:07 +0000513PTH_FUNC(int, pthreadZucondZubroadcastZa, // pthread_cond_broadcast*
bart3772a982008-03-15 08:11:03 +0000514 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000515{
bart3772a982008-03-15 08:11:03 +0000516 int ret;
517 int res;
518 OrigFn fn;
519 VALGRIND_GET_ORIG_FN(fn);
520 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_BROADCAST,
521 cond, 0, 0, 0, 0);
522 CALL_FN_W_W(ret, fn, cond);
523 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000524}
525
526
527// pthread_spin_init
528PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
bart3772a982008-03-15 08:11:03 +0000529 pthread_spinlock_t *spinlock,
530 int pshared)
sewardjaf44c822007-11-25 14:01:38 +0000531{
bart3772a982008-03-15 08:11:03 +0000532 int ret;
533 int res;
534 OrigFn fn;
535 VALGRIND_GET_ORIG_FN(fn);
536 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
537 spinlock, mutex_type_spinlock, 0, 0, 0);
538 CALL_FN_W_WW(ret, fn, spinlock, pshared);
539 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000540}
541
542// pthread_spin_destroy
543PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
bart3772a982008-03-15 08:11:03 +0000544 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000545{
bart3772a982008-03-15 08:11:03 +0000546 int ret;
547 int res;
548 OrigFn fn;
549 VALGRIND_GET_ORIG_FN(fn);
550 CALL_FN_W_W(ret, fn, spinlock);
551 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
552 spinlock, mutex_type_spinlock, 0, 0, 0);
553 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000554}
555
556// pthread_spin_lock
557PTH_FUNC(int, pthreadZuspinZulock, // pthread_spin_lock
bart3772a982008-03-15 08:11:03 +0000558 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000559{
bart3772a982008-03-15 08:11:03 +0000560 int ret;
561 int res;
562 OrigFn fn;
563 VALGRIND_GET_ORIG_FN(fn);
564 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
565 spinlock, mutex_type_spinlock, 0, 0, 0);
566 CALL_FN_W_W(ret, fn, spinlock);
567 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
568 spinlock, ret == 0, 0, 0, 0);
569 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000570}
571
572// pthread_spin_trylock
573PTH_FUNC(int, pthreadZuspinZutrylock, // pthread_spin_trylock
bart3772a982008-03-15 08:11:03 +0000574 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000575{
bart3772a982008-03-15 08:11:03 +0000576 int ret;
577 int res;
578 OrigFn fn;
579 VALGRIND_GET_ORIG_FN(fn);
580 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
581 spinlock, mutex_type_spinlock, 0, 0, 0);
582 CALL_FN_W_W(ret, fn, spinlock);
583 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
584 spinlock, ret == 0, 0, 0, 0);
585 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000586}
587
588// pthread_spin_unlock
589PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock
bart3772a982008-03-15 08:11:03 +0000590 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000591{
bart3772a982008-03-15 08:11:03 +0000592 int ret;
593 int res;
594 OrigFn fn;
595 VALGRIND_GET_ORIG_FN(fn);
596 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
597 spinlock, mutex_type_spinlock, 0, 0, 0);
598 CALL_FN_W_W(ret, fn, spinlock);
599 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000600}
601
sewardj85642922008-01-14 11:54:56 +0000602// pthread_barrier_init
603PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
bart3772a982008-03-15 08:11:03 +0000604 pthread_barrier_t* barrier,
605 const pthread_barrierattr_t* attr,
606 unsigned count)
sewardj85642922008-01-14 11:54:56 +0000607{
bart3772a982008-03-15 08:11:03 +0000608 int ret;
609 int res;
610 OrigFn fn;
611 VALGRIND_GET_ORIG_FN(fn);
612 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_INIT,
613 barrier, pthread_barrier, count, 0, 0);
614 CALL_FN_W_WWW(ret, fn, barrier, attr, count);
615 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_INIT,
616 barrier, pthread_barrier, 0, 0, 0);
617 return ret;
sewardj85642922008-01-14 11:54:56 +0000618}
619
620// pthread_barrier_destroy
621PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
bart3772a982008-03-15 08:11:03 +0000622 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000623{
bart3772a982008-03-15 08:11:03 +0000624 int ret;
625 int res;
626 OrigFn fn;
627 VALGRIND_GET_ORIG_FN(fn);
628 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_DESTROY,
629 barrier, pthread_barrier, 0, 0, 0);
630 CALL_FN_W_W(ret, fn, barrier);
631 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_DESTROY,
632 barrier, pthread_barrier, 0, 0, 0);
633 return ret;
sewardj85642922008-01-14 11:54:56 +0000634}
635
636// pthread_barrier_wait
637PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
bart3772a982008-03-15 08:11:03 +0000638 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000639{
bart3772a982008-03-15 08:11:03 +0000640 int ret;
641 int res;
642 OrigFn fn;
643 VALGRIND_GET_ORIG_FN(fn);
644 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT,
645 barrier, pthread_barrier, 0, 0, 0);
646 CALL_FN_W_W(ret, fn, barrier);
647 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
648 barrier, pthread_barrier,
649 ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
650 0, 0);
651 return ret;
sewardj85642922008-01-14 11:54:56 +0000652}
653
654
sewardj85642922008-01-14 11:54:56 +0000655// sem_init
bart368ec982008-03-11 20:39:01 +0000656PTH_FUNC(int, semZuinitZa, // sem_init*
bart3772a982008-03-15 08:11:03 +0000657 sem_t *sem,
658 int pshared,
659 unsigned int value)
sewardj85642922008-01-14 11:54:56 +0000660{
bart3772a982008-03-15 08:11:03 +0000661 int ret;
662 int res;
663 OrigFn fn;
664 VALGRIND_GET_ORIG_FN(fn);
665 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_INIT,
666 sem, pshared, value, 0, 0);
667 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
668 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_INIT,
669 sem, 0, 0, 0, 0);
670 return ret;
sewardj85642922008-01-14 11:54:56 +0000671}
672
673// sem_destroy
bart00344642008-03-01 15:27:41 +0000674PTH_FUNC(int, semZudestroyZa, // sem_destroy*
bart3772a982008-03-15 08:11:03 +0000675 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000676{
bart3772a982008-03-15 08:11:03 +0000677 int ret;
678 int res;
679 OrigFn fn;
680 VALGRIND_GET_ORIG_FN(fn);
681 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_DESTROY,
682 sem, 0, 0, 0, 0);
683 CALL_FN_W_W(ret, fn, sem);
684 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_DESTROY,
685 sem, 0, 0, 0, 0);
686 return ret;
sewardj85642922008-01-14 11:54:56 +0000687}
688
689// sem_wait
bart368ec982008-03-11 20:39:01 +0000690PTH_FUNC(int, semZuwaitZa, // sem_wait*
bart3772a982008-03-15 08:11:03 +0000691 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000692{
bart3772a982008-03-15 08:11:03 +0000693 int ret;
694 int res;
695 OrigFn fn;
696 VALGRIND_GET_ORIG_FN(fn);
697 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
698 sem, 0, 0, 0, 0);
699 CALL_FN_W_W(ret, fn, sem);
700 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
701 sem, ret == 0, 0, 0, 0);
702 return ret;
sewardj85642922008-01-14 11:54:56 +0000703}
704
705// sem_trywait
bart00344642008-03-01 15:27:41 +0000706PTH_FUNC(int, semZutrywaitZa, // sem_trywait*
bart3772a982008-03-15 08:11:03 +0000707 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000708{
bart3772a982008-03-15 08:11:03 +0000709 int ret;
710 int res;
711 OrigFn fn;
712 VALGRIND_GET_ORIG_FN(fn);
713 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
714 sem, 0, 0, 0, 0);
715 CALL_FN_W_W(ret, fn, sem);
716 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
717 sem, ret == 0, 0, 0, 0);
718 return ret;
sewardj85642922008-01-14 11:54:56 +0000719}
720
721// sem_timedwait
bart00344642008-03-01 15:27:41 +0000722PTH_FUNC(int, semZutimedwait, // sem_timedwait
bart3772a982008-03-15 08:11:03 +0000723 sem_t *sem, const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000724{
bart3772a982008-03-15 08:11:03 +0000725 int ret;
726 int res;
727 OrigFn fn;
728 VALGRIND_GET_ORIG_FN(fn);
729 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
730 sem, 0, 0, 0, 0);
731 CALL_FN_W_WW(ret, fn, sem, abs_timeout);
732 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
733 sem, ret == 0, 0, 0, 0);
734 return ret;
sewardj85642922008-01-14 11:54:56 +0000735}
736
737// sem_post
bart368ec982008-03-11 20:39:01 +0000738PTH_FUNC(int, semZupostZa, // sem_post*
bart3772a982008-03-15 08:11:03 +0000739 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000740{
bart3772a982008-03-15 08:11:03 +0000741 int ret;
742 int res;
743 OrigFn fn;
744 VALGRIND_GET_ORIG_FN(fn);
745 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
746 sem, 0, 0, 0, 0);
747 CALL_FN_W_W(ret, fn, sem);
748 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
749 sem, ret == 0, 0, 0, 0);
750 return ret;
sewardj85642922008-01-14 11:54:56 +0000751}
752
bart00344642008-03-01 15:27:41 +0000753// pthread_rwlock_init
754PTH_FUNC(int,
755 pthreadZurwlockZuinitZa, // pthread_rwlock_init*
756 pthread_rwlock_t* rwlock,
757 const pthread_rwlockattr_t* attr)
758{
bart3772a982008-03-15 08:11:03 +0000759 int ret;
760 int res;
761 OrigFn fn;
762 VALGRIND_GET_ORIG_FN(fn);
763 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_INIT,
764 rwlock, 0, 0, 0, 0);
765 CALL_FN_W_WW(ret, fn, rwlock, attr);
766 return ret;
bart00344642008-03-01 15:27:41 +0000767}
768
769// pthread_rwlock_destroy
770PTH_FUNC(int,
771 pthreadZurwlockZudestroyZa, // pthread_rwlock_destroy*
772 pthread_rwlock_t* rwlock)
773{
bart3772a982008-03-15 08:11:03 +0000774 int ret;
775 int res;
776 OrigFn fn;
777 VALGRIND_GET_ORIG_FN(fn);
778 CALL_FN_W_W(ret, fn, rwlock);
779 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_DESTROY,
780 rwlock, 0, 0, 0, 0);
781 return ret;
bart00344642008-03-01 15:27:41 +0000782}
783
784// pthread_rwlock_rdlock
785PTH_FUNC(int,
786 pthreadZurwlockZurdlockZa, // pthread_rwlock_rdlock*
787 pthread_rwlock_t* rwlock)
788{
bart3772a982008-03-15 08:11:03 +0000789 int ret;
790 int res;
791 OrigFn fn;
792 VALGRIND_GET_ORIG_FN(fn);
793 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
794 rwlock, 0, 0, 0, 0);
795 CALL_FN_W_W(ret, fn, rwlock);
796 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
797 rwlock, ret == 0, 0, 0, 0);
798 return ret;
bart00344642008-03-01 15:27:41 +0000799}
800
801// pthread_rwlock_wrlock
802PTH_FUNC(int,
803 pthreadZurwlockZuwrlockZa, // pthread_rwlock_wrlock*
804 pthread_rwlock_t* rwlock)
805{
bart3772a982008-03-15 08:11:03 +0000806 int ret;
807 int res;
808 OrigFn fn;
809 VALGRIND_GET_ORIG_FN(fn);
810 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
811 rwlock, 0, 0, 0, 0);
812 CALL_FN_W_W(ret, fn, rwlock);
813 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
814 rwlock, ret == 0, 0, 0, 0);
815 return ret;
bart00344642008-03-01 15:27:41 +0000816}
817
818// pthread_rwlock_timedrdlock
819PTH_FUNC(int,
820 pthreadZurwlockZutimedrdlockZa, // pthread_rwlock_timedrdlock*
821 pthread_rwlock_t* rwlock)
822{
bart3772a982008-03-15 08:11:03 +0000823 int ret;
824 int res;
825 OrigFn fn;
826 VALGRIND_GET_ORIG_FN(fn);
827 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
828 rwlock, 0, 0, 0, 0);
829 CALL_FN_W_W(ret, fn, rwlock);
830 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
831 rwlock, ret == 0, 0, 0, 0);
832 return ret;
bart00344642008-03-01 15:27:41 +0000833}
834
835// pthread_rwlock_timedwrlock
836PTH_FUNC(int,
837 pthreadZurwlockZutimedwrlockZa, // pthread_rwlock_timedwrlock*
838 pthread_rwlock_t* rwlock)
839{
bart3772a982008-03-15 08:11:03 +0000840 int ret;
841 int res;
842 OrigFn fn;
843 VALGRIND_GET_ORIG_FN(fn);
844 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
845 rwlock, 0, 0, 0, 0);
846 CALL_FN_W_W(ret, fn, rwlock);
847 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
848 rwlock, ret == 0, 0, 0, 0);
849 return ret;
bart00344642008-03-01 15:27:41 +0000850}
851
852// pthread_rwlock_tryrdlock
853PTH_FUNC(int,
854 pthreadZurwlockZutryrdlockZa, // pthread_rwlock_tryrdlock*
855 pthread_rwlock_t* rwlock)
856{
bart3772a982008-03-15 08:11:03 +0000857 int ret;
858 int res;
859 OrigFn fn;
860 VALGRIND_GET_ORIG_FN(fn);
861 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
862 rwlock, 0, 0, 0, 0);
863 CALL_FN_W_W(ret, fn, rwlock);
864 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
865 rwlock, ret == 0, 0, 0, 0);
866 return ret;
bart00344642008-03-01 15:27:41 +0000867}
868
869// pthread_rwlock_trywrlock
870PTH_FUNC(int,
871 pthreadZurwlockZutrywrlockZa, // pthread_rwlock_trywrlock*
872 pthread_rwlock_t* rwlock)
873{
bart3772a982008-03-15 08:11:03 +0000874 int ret;
875 int res;
876 OrigFn fn;
877 VALGRIND_GET_ORIG_FN(fn);
878 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
879 rwlock, 0, 0, 0, 0);
880 CALL_FN_W_W(ret, fn, rwlock);
881 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
882 rwlock, ret == 0, 0, 0, 0);
883 return ret;
bart00344642008-03-01 15:27:41 +0000884}
885
886// pthread_rwlock_unlock
887PTH_FUNC(int,
888 pthreadZurwlockZuunlockZa, // pthread_rwlock_unlock*
889 pthread_rwlock_t* rwlock)
890{
bart3772a982008-03-15 08:11:03 +0000891 int ret;
892 int res;
893 OrigFn fn;
894 VALGRIND_GET_ORIG_FN(fn);
895 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_UNLOCK,
896 rwlock, 0, 0, 0, 0);
897 CALL_FN_W_W(ret, fn, rwlock);
898 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_UNLOCK,
899 rwlock, ret == 0, 0, 0, 0);
900 return ret;
bart00344642008-03-01 15:27:41 +0000901}