blob: 62dd1d9d5663a959af24d6620ebf6f0485b34e6f [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()
bart5e389f12008-04-05 12:53:15 +000056#include "config.h"
sewardjaf44c822007-11-25 14:01:38 +000057#include "drd_clientreq.h"
sewardj85642922008-01-14 11:54:56 +000058#include "pub_tool_redir.h"
sewardjaf44c822007-11-25 14:01:38 +000059
60
61// Defines.
62
bart3772a982008-03-15 08:11:03 +000063#define PTH_FUNC(ret_ty, f, args...) \
64 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args); \
65 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args)
sewardjaf44c822007-11-25 14:01:38 +000066
67
bart6f07b252008-04-04 16:45:20 +000068/* Local data structures. */
sewardjaf44c822007-11-25 14:01:38 +000069
70typedef struct
71{
bart3772a982008-03-15 08:11:03 +000072 void* (*start)(void*);
73 void* arg;
74 int detachstate;
sewardjaf44c822007-11-25 14:01:38 +000075#if 0
bart3772a982008-03-15 08:11:03 +000076 pthread_mutex_t mutex;
77 pthread_cond_t cond;
sewardjaf44c822007-11-25 14:01:38 +000078#else
bart3772a982008-03-15 08:11:03 +000079 int wrapper_started;
sewardjaf44c822007-11-25 14:01:38 +000080#endif
81} VgPosixThreadArgs;
82
83
bart6f07b252008-04-04 16:45:20 +000084/* Function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000085
bart44ceea22008-04-16 18:19:45 +000086static void init(void) __attribute__((constructor));
bart6f07b252008-04-04 16:45:20 +000087static void check_threading_library(void);
88static void vg_set_main_thread_state(void);
sewardjaf44c822007-11-25 14:01:38 +000089
90
bart6f07b252008-04-04 16:45:20 +000091/* Function definitions. */
92
93/** Shared library initialization function: the _init() function is called
94 * after dlopen() has loaded the shared library. This function must not
95 * be declared static.
96 */
bart44ceea22008-04-16 18:19:45 +000097static void init(void)
bart6f07b252008-04-04 16:45:20 +000098{
99 check_threading_library();
bart0baacb32008-05-03 09:00:40 +0000100 vg_set_main_thread_state();
bart25d30032008-04-06 07:51:24 +0000101 /* glibc up to and including version 2.7 triggers conflicting accesses */
102 /* on stdout and stderr when sending output to one of these streams from */
103 /* more than one thread. Suppress data race reports on these objects. */
104 DRD_IGNORE_VAR(*stdout);
105 DRD_IGNORE_VAR(*stderr);
bart6f07b252008-04-04 16:45:20 +0000106}
sewardjaf44c822007-11-25 14:01:38 +0000107
bart5357fcb2008-02-27 15:46:00 +0000108static MutexT pthread_to_drd_mutex_type(const int kind)
109{
bart3772a982008-03-15 08:11:03 +0000110 switch (kind)
111 {
112 /* PTHREAD_MUTEX_RECURSIVE_NP */
113 case PTHREAD_MUTEX_RECURSIVE:
114 return mutex_type_recursive_mutex;
115 /* PTHREAD_MUTEX_ERRORCHECK_NP */
116 case PTHREAD_MUTEX_ERRORCHECK:
117 return mutex_type_errorcheck_mutex;
118 /* PTHREAD_MUTEX_TIMED_NP */
119 /* PTHREAD_MUTEX_NORMAL */
120 case PTHREAD_MUTEX_DEFAULT:
bart85569572008-05-03 09:15:25 +0000121#if defined(HAVE_PTHREAD_MUTEX_ADAPTIVE_NP)
bart3772a982008-03-15 08:11:03 +0000122 case PTHREAD_MUTEX_ADAPTIVE_NP:
bart85569572008-05-03 09:15:25 +0000123#endif
bart3772a982008-03-15 08:11:03 +0000124 return mutex_type_default_mutex;
125 }
126 return mutex_type_invalid_mutex;
bart5357fcb2008-02-27 15:46:00 +0000127}
128
129static MutexT mutex_type(pthread_mutex_t* mutex)
130{
bart5e389f12008-04-05 12:53:15 +0000131#if defined(HAVE_PTHREAD_MUTEX_T__M_KIND)
132 /* LinuxThreads. */
bart3772a982008-03-15 08:11:03 +0000133 const int kind = mutex->__m_kind;
bart5e389f12008-04-05 12:53:15 +0000134#elif defined(HAVE_PTHREAD_MUTEX_T__DATA__KIND)
135 /* NPTL. */
bart3772a982008-03-15 08:11:03 +0000136 const int kind = mutex->__data.__kind;
bartc9463c42008-02-28 07:36:04 +0000137#else
bart5e389f12008-04-05 12:53:15 +0000138 /* Another POSIX threads implementation. Regression tests will fail. */
bart3772a982008-03-15 08:11:03 +0000139 const int kind = PTHREAD_MUTEX_DEFAULT;
bart5e389f12008-04-05 12:53:15 +0000140 fprintf(stderr,
141 "Did not recognize your POSIX threads implementation. Giving up.\n");
142 assert(0);
bartc9463c42008-02-28 07:36:04 +0000143#endif
bart3772a982008-03-15 08:11:03 +0000144 return pthread_to_drd_mutex_type(kind);
bart5357fcb2008-02-27 15:46:00 +0000145}
146
sewardjaf44c822007-11-25 14:01:38 +0000147static void vg_start_suppression(const void* const p, size_t const size)
148{
bart3772a982008-03-15 08:11:03 +0000149 int res;
150 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
bartf5bb46a2008-03-29 13:18:02 +0000151 p, size, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000152}
153
154static void vg_set_joinable(const pthread_t tid, const int joinable)
155{
bart3772a982008-03-15 08:11:03 +0000156 int res;
157 assert(joinable == 0 || joinable == 1);
158 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_JOINABLE,
159 tid, joinable, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000160}
161
162static void* vg_thread_wrapper(void* arg)
163{
bart3772a982008-03-15 08:11:03 +0000164 int res;
bart0d063002008-03-01 07:25:13 +0000165
bart3772a982008-03-15 08:11:03 +0000166 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
167 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000168
bart3772a982008-03-15 08:11:03 +0000169 {
170 VgPosixThreadArgs* const arg_ptr = (VgPosixThreadArgs*)arg;
171 VgPosixThreadArgs const arg_copy = *arg_ptr;
172 void* result;
sewardjaf44c822007-11-25 14:01:38 +0000173
174#if 0
bart3772a982008-03-15 08:11:03 +0000175 pthread_mutex_lock(arg_ptr->mutex);
176 pthread_cond_signal(arg_ptr->cond);
177 pthread_mutex_unlock(arg_ptr->mutex);
sewardjaf44c822007-11-25 14:01:38 +0000178#else
bart3772a982008-03-15 08:11:03 +0000179 arg_ptr->wrapper_started = 1;
sewardjaf44c822007-11-25 14:01:38 +0000180#endif
181
bart3772a982008-03-15 08:11:03 +0000182 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
183 pthread_self(), 0, 0, 0, 0);
184 vg_set_joinable(pthread_self(),
185 arg_copy.detachstate == PTHREAD_CREATE_JOINABLE);
186 result = (arg_copy.start)(arg_copy.arg);
187 return result;
188 }
sewardjaf44c822007-11-25 14:01:38 +0000189}
190
bart6f07b252008-04-04 16:45:20 +0000191/** Return 1 if LinuxThread has been detected, and 0 otherwise. */
bart4501d5c2008-03-04 18:36:23 +0000192static int detected_linuxthreads(void)
193{
194#if defined(linux)
195#if defined(_CS_GNU_LIBPTHREAD_VERSION)
bart3772a982008-03-15 08:11:03 +0000196 /* Linux with a recent glibc. */
197 char buffer[256];
198 unsigned len;
199 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
200 assert(len <= sizeof(buffer));
201 return len > 0 && buffer[0] == 'l';
bart4501d5c2008-03-04 18:36:23 +0000202#else
bart3772a982008-03-15 08:11:03 +0000203 /* Linux without _CS_GNU_LIBPTHREAD_VERSION: most likely LinuxThreads. */
204 return 1;
bart4501d5c2008-03-04 18:36:23 +0000205#endif
206#else
bart3772a982008-03-15 08:11:03 +0000207 /* Another OS than Linux, hence no LinuxThreads. */
208 return 0;
bart4501d5c2008-03-04 18:36:23 +0000209#endif
210}
211
bart6f07b252008-04-04 16:45:20 +0000212/** Stop and print an error message in case a non-supported threading
213 * library (LinuxThreads) has been detected.
214 */
215static void check_threading_library(void)
sewardjaf44c822007-11-25 14:01:38 +0000216{
bart3772a982008-03-15 08:11:03 +0000217 if (detected_linuxthreads())
218 {
219 if (getenv("LD_ASSUME_KERNEL"))
220 {
221 fprintf(stderr,
222 "Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
223 "the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
224 "after having unset the environment variable LD_ASSUME_KERNEL. Giving up.\n"
225 );
226 }
227 else
228 {
229 fprintf(stderr,
230 "Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
231 "the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
232 "after having upgraded to a newer version of your Linux distribution.\n"
233 "Giving up.\n"
234 );
235 }
236 abort();
237 }
bart6f07b252008-04-04 16:45:20 +0000238}
239
240static void vg_set_main_thread_state(void)
241{
242 int res;
bart0d063002008-03-01 07:25:13 +0000243
bart3772a982008-03-15 08:11:03 +0000244 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
245 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000246
bart3772a982008-03-15 08:11:03 +0000247 // Make sure that DRD knows about the main thread's POSIX thread ID.
248 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
249 pthread_self(), 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000250
251}
252
253// pthread_create
sewardj347eeba2008-01-21 14:19:07 +0000254PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
bart3772a982008-03-15 08:11:03 +0000255 pthread_t *thread, const pthread_attr_t *attr,
256 void *(*start) (void *), void *arg)
sewardjaf44c822007-11-25 14:01:38 +0000257{
bartbf3a60c2008-04-04 19:10:21 +0000258 int res;
bart3772a982008-03-15 08:11:03 +0000259 int ret;
260 OrigFn fn;
261 VgPosixThreadArgs vgargs;
sewardjaf44c822007-11-25 14:01:38 +0000262
bart3772a982008-03-15 08:11:03 +0000263 VALGRIND_GET_ORIG_FN(fn);
sewardjaf44c822007-11-25 14:01:38 +0000264
bart3772a982008-03-15 08:11:03 +0000265 vg_start_suppression(&vgargs.wrapper_started,
266 sizeof(vgargs.wrapper_started));
267 vgargs.start = start;
268 vgargs.arg = arg;
269 vgargs.wrapper_started = 0;
270 vgargs.detachstate = PTHREAD_CREATE_JOINABLE;
271 if (attr)
272 {
273 if (pthread_attr_getdetachstate(attr, &vgargs.detachstate) != 0)
274 {
275 assert(0);
276 }
277 }
278 assert(vgargs.detachstate == PTHREAD_CREATE_JOINABLE
279 || vgargs.detachstate == PTHREAD_CREATE_DETACHED);
sewardjaf44c822007-11-25 14:01:38 +0000280#if 0
bart3772a982008-03-15 08:11:03 +0000281 pthread_mutex_init(&vgargs.mutex, 0);
282 pthread_cond_init(&vgargs.cond, 0);
283 pthread_mutex_lock(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000284#endif
bartbf3a60c2008-04-04 19:10:21 +0000285 /* Suppress NPTL-specific conflicts between creator and created thread. */
286 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_STOP_RECORDING,
287 0, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000288 CALL_FN_W_WWWW(ret, fn, thread, attr, vg_thread_wrapper, &vgargs);
bartbf3a60c2008-04-04 19:10:21 +0000289 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_START_RECORDING,
290 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000291#if 0
bart3772a982008-03-15 08:11:03 +0000292 pthread_cond_wait(&vgargs.cond, &vgargs.mutex);
293 pthread_mutex_unlock(&vgargs.mutex);
294 pthread_cond_destroy(&vgargs.cond);
295 pthread_mutex_destroy(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000296#else
bart3772a982008-03-15 08:11:03 +0000297 // Yes, you see it correctly, busy waiting ... The problem is that
298 // POSIX threads functions cannot be called here -- the functions defined
299 // in this file (drd_intercepts.c) would be called instead of those in
300 // libpthread.so. This loop is necessary because vgargs is allocated on the
301 // stack, and the created thread reads it.
302 if (ret == 0)
303 {
304 while (! vgargs.wrapper_started)
305 {
306 sched_yield();
307 }
308 }
sewardjaf44c822007-11-25 14:01:38 +0000309#endif
bart3772a982008-03-15 08:11:03 +0000310 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000311}
312
313// pthread_join
314PTH_FUNC(int, pthreadZujoin, // pthread_join
bart3772a982008-03-15 08:11:03 +0000315 pthread_t pt_joinee, void **thread_return)
sewardjaf44c822007-11-25 14:01:38 +0000316{
bart3772a982008-03-15 08:11:03 +0000317 int ret;
318 int res;
319 OrigFn fn;
sewardjaf44c822007-11-25 14:01:38 +0000320
bart3772a982008-03-15 08:11:03 +0000321 VALGRIND_GET_ORIG_FN(fn);
322 CALL_FN_W_WW(ret, fn, pt_joinee, thread_return);
323 if (ret == 0)
324 {
325 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_JOIN,
326 pt_joinee, 0, 0, 0, 0);
327 }
328 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000329}
330
331// pthread_detach
332PTH_FUNC(int, pthreadZudetach, pthread_t pt_thread)
333{
bart3772a982008-03-15 08:11:03 +0000334 int ret;
335 OrigFn fn;
336 VALGRIND_GET_ORIG_FN(fn);
337 {
338 CALL_FN_W_W(ret, fn, pt_thread);
339 if (ret == 0)
340 {
341 vg_set_joinable(pt_thread, 0);
342 }
343 }
344 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000345}
346
347// pthread_mutex_init
348PTH_FUNC(int, pthreadZumutexZuinit,
bart3772a982008-03-15 08:11:03 +0000349 pthread_mutex_t *mutex,
350 const pthread_mutexattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000351{
bart3772a982008-03-15 08:11:03 +0000352 int ret;
353 int res;
354 OrigFn fn;
355 int mt;
356 VALGRIND_GET_ORIG_FN(fn);
357 mt = PTHREAD_MUTEX_DEFAULT;
358 if (attr)
359 pthread_mutexattr_gettype(attr, &mt);
360 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
361 mutex, pthread_to_drd_mutex_type(mt), 0, 0, 0);
362 CALL_FN_W_WW(ret, fn, mutex, attr);
363 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT,
364 mutex, 0, 0, 0, 0);
365 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000366}
367
368// pthread_mutex_destroy
369PTH_FUNC(int, pthreadZumutexZudestroy,
bart3772a982008-03-15 08:11:03 +0000370 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000371{
bart3772a982008-03-15 08:11:03 +0000372 int ret;
373 int res;
374 OrigFn fn;
375 VALGRIND_GET_ORIG_FN(fn);
376 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
377 mutex, 0, 0, 0, 0);
378 CALL_FN_W_W(ret, fn, mutex);
379 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
380 mutex, mutex_type(mutex), 0, 0, 0);
381 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000382}
383
384// pthread_mutex_lock
385PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
bart3772a982008-03-15 08:11:03 +0000386 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000387{
bart3772a982008-03-15 08:11:03 +0000388 int ret;
389 int res;
390 OrigFn fn;
391 VALGRIND_GET_ORIG_FN(fn);
392 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
393 mutex, mutex_type(mutex), 0, 0, 0);
394 CALL_FN_W_W(ret, fn, mutex);
395 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_MUTEX_LOCK,
396 mutex, ret == 0, 0, 0, 0);
397 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000398}
399
400// pthread_mutex_trylock
401PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
bart3772a982008-03-15 08:11:03 +0000402 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +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,
bart2e3a3c12008-03-24 08:33:47 +0000409 mutex, mutex_type(mutex), 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000410 CALL_FN_W_W(ret, fn, mutex);
411 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
412 mutex, ret == 0, 0, 0, 0);
413 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000414}
415
sewardj85642922008-01-14 11:54:56 +0000416// pthread_mutex_timedlock
417PTH_FUNC(int, pthreadZumutexZutimedlock, // pthread_mutex_timedlock
bart3772a982008-03-15 08:11:03 +0000418 pthread_mutex_t *mutex,
419 const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000420{
bart3772a982008-03-15 08:11:03 +0000421 int ret;
422 int res;
423 OrigFn fn;
424 VALGRIND_GET_ORIG_FN(fn);
425 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
426 mutex, mutex_type(mutex), 0, 0, 0);
427 CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
428 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
429 mutex, ret == 0, 0, 0, 0);
430 return ret;
sewardj85642922008-01-14 11:54:56 +0000431}
432
sewardjaf44c822007-11-25 14:01:38 +0000433// pthread_mutex_unlock
434PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
bart3772a982008-03-15 08:11:03 +0000435 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000436{
bart3772a982008-03-15 08:11:03 +0000437 int ret;
438 int res;
439 OrigFn fn;
440 VALGRIND_GET_ORIG_FN(fn);
441 VALGRIND_DO_CLIENT_REQUEST(res, -1,
442 VG_USERREQ__PRE_MUTEX_UNLOCK,
443 mutex, mutex_type(mutex), 0, 0, 0);
444 CALL_FN_W_W(ret, fn, mutex);
445 VALGRIND_DO_CLIENT_REQUEST(res, -1,
446 VG_USERREQ__POST_MUTEX_UNLOCK,
447 mutex, 0, 0, 0, 0);
448 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000449}
450
451// pthread_cond_init
sewardj347eeba2008-01-21 14:19:07 +0000452PTH_FUNC(int, pthreadZucondZuinitZa, // pthread_cond_init*
bart3772a982008-03-15 08:11:03 +0000453 pthread_cond_t* cond,
454 const pthread_condattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000455{
bart3772a982008-03-15 08:11:03 +0000456 int ret;
457 int res;
458 OrigFn fn;
459 VALGRIND_GET_ORIG_FN(fn);
460 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_INIT,
461 cond, 0, 0, 0, 0);
462 CALL_FN_W_WW(ret, fn, cond, attr);
463 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000464}
465
466// pthread_cond_destroy
sewardj347eeba2008-01-21 14:19:07 +0000467PTH_FUNC(int, pthreadZucondZudestroyZa, // pthread_cond_destroy*
bart3772a982008-03-15 08:11:03 +0000468 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000469{
bart3772a982008-03-15 08:11:03 +0000470 int ret;
471 int res;
472 OrigFn fn;
473 VALGRIND_GET_ORIG_FN(fn);
474 CALL_FN_W_W(ret, fn, cond);
475 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_DESTROY,
476 cond, 0, 0, 0, 0);
477 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000478}
479
480// pthread_cond_wait
sewardj347eeba2008-01-21 14:19:07 +0000481PTH_FUNC(int, pthreadZucondZuwaitZa, // pthread_cond_wait*
bart3772a982008-03-15 08:11:03 +0000482 pthread_cond_t *cond,
483 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000484{
bart3772a982008-03-15 08:11:03 +0000485 int ret;
486 int res;
487 OrigFn fn;
488 VALGRIND_GET_ORIG_FN(fn);
489 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
490 cond, mutex, mutex_type(mutex), 0, 0);
491 CALL_FN_W_WW(ret, fn, cond, mutex);
492 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000493 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000494 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000495}
496
497// pthread_cond_timedwait
sewardj347eeba2008-01-21 14:19:07 +0000498PTH_FUNC(int, pthreadZucondZutimedwaitZa, // pthread_cond_timedwait*
bart3772a982008-03-15 08:11:03 +0000499 pthread_cond_t *cond,
500 pthread_mutex_t *mutex,
501 const struct timespec* abstime)
sewardjaf44c822007-11-25 14:01:38 +0000502{
bart3772a982008-03-15 08:11:03 +0000503 int ret;
504 int res;
505 OrigFn fn;
506 VALGRIND_GET_ORIG_FN(fn);
507 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
508 cond, mutex, mutex_type(mutex), 0, 0);
509 CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
510 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000511 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000512 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000513}
514
515// pthread_cond_signal
sewardj347eeba2008-01-21 14:19:07 +0000516PTH_FUNC(int, pthreadZucondZusignalZa, // pthread_cond_signal*
bart3772a982008-03-15 08:11:03 +0000517 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000518{
bart3772a982008-03-15 08:11:03 +0000519 int ret;
520 int res;
521 OrigFn fn;
522 VALGRIND_GET_ORIG_FN(fn);
523 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_SIGNAL,
524 cond, 0, 0, 0, 0);
525 CALL_FN_W_W(ret, fn, cond);
526 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000527}
528
529// pthread_cond_broadcast
sewardj347eeba2008-01-21 14:19:07 +0000530PTH_FUNC(int, pthreadZucondZubroadcastZa, // pthread_cond_broadcast*
bart3772a982008-03-15 08:11:03 +0000531 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000532{
bart3772a982008-03-15 08:11:03 +0000533 int ret;
534 int res;
535 OrigFn fn;
536 VALGRIND_GET_ORIG_FN(fn);
537 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_BROADCAST,
538 cond, 0, 0, 0, 0);
539 CALL_FN_W_W(ret, fn, cond);
540 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000541}
542
543
544// pthread_spin_init
545PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
bart3772a982008-03-15 08:11:03 +0000546 pthread_spinlock_t *spinlock,
547 int pshared)
sewardjaf44c822007-11-25 14:01:38 +0000548{
bart3772a982008-03-15 08:11:03 +0000549 int ret;
550 int res;
551 OrigFn fn;
552 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000553 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
554 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000555 CALL_FN_W_WW(ret, fn, spinlock, pshared);
bartf4f05812008-07-07 08:10:56 +0000556 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
557 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000558 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000559}
560
561// pthread_spin_destroy
562PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
bart3772a982008-03-15 08:11:03 +0000563 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000564{
bart3772a982008-03-15 08:11:03 +0000565 int ret;
566 int res;
567 OrigFn fn;
568 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000569 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
570 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000571 CALL_FN_W_W(ret, fn, spinlock);
572 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
573 spinlock, mutex_type_spinlock, 0, 0, 0);
574 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000575}
576
577// pthread_spin_lock
578PTH_FUNC(int, pthreadZuspinZulock, // pthread_spin_lock
bart3772a982008-03-15 08:11:03 +0000579 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000580{
bart3772a982008-03-15 08:11:03 +0000581 int ret;
582 int res;
583 OrigFn fn;
584 VALGRIND_GET_ORIG_FN(fn);
585 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
586 spinlock, mutex_type_spinlock, 0, 0, 0);
587 CALL_FN_W_W(ret, fn, spinlock);
588 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
589 spinlock, ret == 0, 0, 0, 0);
590 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000591}
592
593// pthread_spin_trylock
594PTH_FUNC(int, pthreadZuspinZutrylock, // pthread_spin_trylock
bart3772a982008-03-15 08:11:03 +0000595 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000596{
bart3772a982008-03-15 08:11:03 +0000597 int ret;
598 int res;
599 OrigFn fn;
600 VALGRIND_GET_ORIG_FN(fn);
601 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
602 spinlock, mutex_type_spinlock, 0, 0, 0);
603 CALL_FN_W_W(ret, fn, spinlock);
604 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
605 spinlock, ret == 0, 0, 0, 0);
606 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000607}
608
609// pthread_spin_unlock
610PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock
bart3772a982008-03-15 08:11:03 +0000611 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000612{
bart3772a982008-03-15 08:11:03 +0000613 int ret;
614 int res;
615 OrigFn fn;
616 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000617 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
bart3772a982008-03-15 08:11:03 +0000618 spinlock, mutex_type_spinlock, 0, 0, 0);
619 CALL_FN_W_W(ret, fn, spinlock);
bartf4f05812008-07-07 08:10:56 +0000620 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
621 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000622 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000623}
624
sewardj85642922008-01-14 11:54:56 +0000625// pthread_barrier_init
626PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
bart3772a982008-03-15 08:11:03 +0000627 pthread_barrier_t* barrier,
628 const pthread_barrierattr_t* attr,
629 unsigned count)
sewardj85642922008-01-14 11:54:56 +0000630{
bart3772a982008-03-15 08:11:03 +0000631 int ret;
632 int res;
633 OrigFn fn;
634 VALGRIND_GET_ORIG_FN(fn);
635 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_INIT,
636 barrier, pthread_barrier, count, 0, 0);
637 CALL_FN_W_WWW(ret, fn, barrier, attr, count);
638 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_INIT,
639 barrier, pthread_barrier, 0, 0, 0);
640 return ret;
sewardj85642922008-01-14 11:54:56 +0000641}
642
643// pthread_barrier_destroy
644PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
bart3772a982008-03-15 08:11:03 +0000645 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000646{
bart3772a982008-03-15 08:11:03 +0000647 int ret;
648 int res;
649 OrigFn fn;
650 VALGRIND_GET_ORIG_FN(fn);
651 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_DESTROY,
652 barrier, pthread_barrier, 0, 0, 0);
653 CALL_FN_W_W(ret, fn, barrier);
654 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_DESTROY,
655 barrier, pthread_barrier, 0, 0, 0);
656 return ret;
sewardj85642922008-01-14 11:54:56 +0000657}
658
659// pthread_barrier_wait
660PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
bart3772a982008-03-15 08:11:03 +0000661 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000662{
bart3772a982008-03-15 08:11:03 +0000663 int ret;
664 int res;
665 OrigFn fn;
666 VALGRIND_GET_ORIG_FN(fn);
667 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT,
668 barrier, pthread_barrier, 0, 0, 0);
669 CALL_FN_W_W(ret, fn, barrier);
670 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
671 barrier, pthread_barrier,
672 ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
673 0, 0);
674 return ret;
sewardj85642922008-01-14 11:54:56 +0000675}
676
677
sewardj85642922008-01-14 11:54:56 +0000678// sem_init
bart368ec982008-03-11 20:39:01 +0000679PTH_FUNC(int, semZuinitZa, // sem_init*
bart3772a982008-03-15 08:11:03 +0000680 sem_t *sem,
681 int pshared,
682 unsigned int value)
sewardj85642922008-01-14 11:54:56 +0000683{
bart3772a982008-03-15 08:11:03 +0000684 int ret;
685 int res;
686 OrigFn fn;
687 VALGRIND_GET_ORIG_FN(fn);
688 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_INIT,
689 sem, pshared, value, 0, 0);
690 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
691 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_INIT,
692 sem, 0, 0, 0, 0);
693 return ret;
sewardj85642922008-01-14 11:54:56 +0000694}
695
696// sem_destroy
bart00344642008-03-01 15:27:41 +0000697PTH_FUNC(int, semZudestroyZa, // sem_destroy*
bart3772a982008-03-15 08:11:03 +0000698 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000699{
bart3772a982008-03-15 08:11:03 +0000700 int ret;
701 int res;
702 OrigFn fn;
703 VALGRIND_GET_ORIG_FN(fn);
704 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_DESTROY,
705 sem, 0, 0, 0, 0);
706 CALL_FN_W_W(ret, fn, sem);
707 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_DESTROY,
708 sem, 0, 0, 0, 0);
709 return ret;
sewardj85642922008-01-14 11:54:56 +0000710}
711
712// sem_wait
bart368ec982008-03-11 20:39:01 +0000713PTH_FUNC(int, semZuwaitZa, // sem_wait*
bart3772a982008-03-15 08:11:03 +0000714 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000715{
bart3772a982008-03-15 08:11:03 +0000716 int ret;
717 int res;
718 OrigFn fn;
719 VALGRIND_GET_ORIG_FN(fn);
720 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
721 sem, 0, 0, 0, 0);
722 CALL_FN_W_W(ret, fn, sem);
723 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
724 sem, ret == 0, 0, 0, 0);
725 return ret;
sewardj85642922008-01-14 11:54:56 +0000726}
727
728// sem_trywait
bart00344642008-03-01 15:27:41 +0000729PTH_FUNC(int, semZutrywaitZa, // sem_trywait*
bart3772a982008-03-15 08:11:03 +0000730 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000731{
bart3772a982008-03-15 08:11:03 +0000732 int ret;
733 int res;
734 OrigFn fn;
735 VALGRIND_GET_ORIG_FN(fn);
736 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
737 sem, 0, 0, 0, 0);
738 CALL_FN_W_W(ret, fn, sem);
739 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
740 sem, ret == 0, 0, 0, 0);
741 return ret;
sewardj85642922008-01-14 11:54:56 +0000742}
743
744// sem_timedwait
bart00344642008-03-01 15:27:41 +0000745PTH_FUNC(int, semZutimedwait, // sem_timedwait
bart3772a982008-03-15 08:11:03 +0000746 sem_t *sem, const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000747{
bart3772a982008-03-15 08:11:03 +0000748 int ret;
749 int res;
750 OrigFn fn;
751 VALGRIND_GET_ORIG_FN(fn);
752 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
753 sem, 0, 0, 0, 0);
754 CALL_FN_W_WW(ret, fn, sem, abs_timeout);
755 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
756 sem, ret == 0, 0, 0, 0);
757 return ret;
sewardj85642922008-01-14 11:54:56 +0000758}
759
760// sem_post
bart368ec982008-03-11 20:39:01 +0000761PTH_FUNC(int, semZupostZa, // sem_post*
bart3772a982008-03-15 08:11:03 +0000762 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000763{
bart3772a982008-03-15 08:11:03 +0000764 int ret;
765 int res;
766 OrigFn fn;
767 VALGRIND_GET_ORIG_FN(fn);
768 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
769 sem, 0, 0, 0, 0);
770 CALL_FN_W_W(ret, fn, sem);
771 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
772 sem, ret == 0, 0, 0, 0);
773 return ret;
sewardj85642922008-01-14 11:54:56 +0000774}
775
bart00344642008-03-01 15:27:41 +0000776// pthread_rwlock_init
777PTH_FUNC(int,
778 pthreadZurwlockZuinitZa, // pthread_rwlock_init*
779 pthread_rwlock_t* rwlock,
780 const pthread_rwlockattr_t* attr)
781{
bart3772a982008-03-15 08:11:03 +0000782 int ret;
783 int res;
784 OrigFn fn;
785 VALGRIND_GET_ORIG_FN(fn);
786 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_INIT,
787 rwlock, 0, 0, 0, 0);
788 CALL_FN_W_WW(ret, fn, rwlock, attr);
789 return ret;
bart00344642008-03-01 15:27:41 +0000790}
791
792// pthread_rwlock_destroy
793PTH_FUNC(int,
794 pthreadZurwlockZudestroyZa, // pthread_rwlock_destroy*
795 pthread_rwlock_t* rwlock)
796{
bart3772a982008-03-15 08:11:03 +0000797 int ret;
798 int res;
799 OrigFn fn;
800 VALGRIND_GET_ORIG_FN(fn);
801 CALL_FN_W_W(ret, fn, rwlock);
802 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_DESTROY,
803 rwlock, 0, 0, 0, 0);
804 return ret;
bart00344642008-03-01 15:27:41 +0000805}
806
807// pthread_rwlock_rdlock
808PTH_FUNC(int,
809 pthreadZurwlockZurdlockZa, // pthread_rwlock_rdlock*
810 pthread_rwlock_t* rwlock)
811{
bart3772a982008-03-15 08:11:03 +0000812 int ret;
813 int res;
814 OrigFn fn;
815 VALGRIND_GET_ORIG_FN(fn);
816 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
817 rwlock, 0, 0, 0, 0);
818 CALL_FN_W_W(ret, fn, rwlock);
819 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
820 rwlock, ret == 0, 0, 0, 0);
821 return ret;
bart00344642008-03-01 15:27:41 +0000822}
823
824// pthread_rwlock_wrlock
825PTH_FUNC(int,
826 pthreadZurwlockZuwrlockZa, // pthread_rwlock_wrlock*
827 pthread_rwlock_t* rwlock)
828{
bart3772a982008-03-15 08:11:03 +0000829 int ret;
830 int res;
831 OrigFn fn;
832 VALGRIND_GET_ORIG_FN(fn);
833 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
834 rwlock, 0, 0, 0, 0);
835 CALL_FN_W_W(ret, fn, rwlock);
836 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
837 rwlock, ret == 0, 0, 0, 0);
838 return ret;
bart00344642008-03-01 15:27:41 +0000839}
840
841// pthread_rwlock_timedrdlock
842PTH_FUNC(int,
843 pthreadZurwlockZutimedrdlockZa, // pthread_rwlock_timedrdlock*
844 pthread_rwlock_t* rwlock)
845{
bart3772a982008-03-15 08:11:03 +0000846 int ret;
847 int res;
848 OrigFn fn;
849 VALGRIND_GET_ORIG_FN(fn);
850 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
851 rwlock, 0, 0, 0, 0);
852 CALL_FN_W_W(ret, fn, rwlock);
853 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
854 rwlock, ret == 0, 0, 0, 0);
855 return ret;
bart00344642008-03-01 15:27:41 +0000856}
857
858// pthread_rwlock_timedwrlock
859PTH_FUNC(int,
860 pthreadZurwlockZutimedwrlockZa, // pthread_rwlock_timedwrlock*
861 pthread_rwlock_t* rwlock)
862{
bart3772a982008-03-15 08:11:03 +0000863 int ret;
864 int res;
865 OrigFn fn;
866 VALGRIND_GET_ORIG_FN(fn);
867 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
868 rwlock, 0, 0, 0, 0);
869 CALL_FN_W_W(ret, fn, rwlock);
870 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
871 rwlock, ret == 0, 0, 0, 0);
872 return ret;
bart00344642008-03-01 15:27:41 +0000873}
874
875// pthread_rwlock_tryrdlock
876PTH_FUNC(int,
877 pthreadZurwlockZutryrdlockZa, // pthread_rwlock_tryrdlock*
878 pthread_rwlock_t* rwlock)
879{
bart3772a982008-03-15 08:11:03 +0000880 int ret;
881 int res;
882 OrigFn fn;
883 VALGRIND_GET_ORIG_FN(fn);
884 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
885 rwlock, 0, 0, 0, 0);
886 CALL_FN_W_W(ret, fn, rwlock);
887 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
888 rwlock, ret == 0, 0, 0, 0);
889 return ret;
bart00344642008-03-01 15:27:41 +0000890}
891
892// pthread_rwlock_trywrlock
893PTH_FUNC(int,
894 pthreadZurwlockZutrywrlockZa, // pthread_rwlock_trywrlock*
895 pthread_rwlock_t* rwlock)
896{
bart3772a982008-03-15 08:11:03 +0000897 int ret;
898 int res;
899 OrigFn fn;
900 VALGRIND_GET_ORIG_FN(fn);
901 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
902 rwlock, 0, 0, 0, 0);
903 CALL_FN_W_W(ret, fn, rwlock);
904 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
905 rwlock, ret == 0, 0, 0, 0);
906 return ret;
bart00344642008-03-01 15:27:41 +0000907}
908
909// pthread_rwlock_unlock
910PTH_FUNC(int,
911 pthreadZurwlockZuunlockZa, // pthread_rwlock_unlock*
912 pthread_rwlock_t* rwlock)
913{
bart3772a982008-03-15 08:11:03 +0000914 int ret;
915 int res;
916 OrigFn fn;
917 VALGRIND_GET_ORIG_FN(fn);
918 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_UNLOCK,
919 rwlock, 0, 0, 0, 0);
920 CALL_FN_W_W(ret, fn, rwlock);
921 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_UNLOCK,
922 rwlock, ret == 0, 0, 0, 0);
923 return ret;
bart00344642008-03-01 15:27:41 +0000924}