blob: ce4c52e8b69e09241a009091d39b86faa3a0514b [file] [log] [blame]
sewardjaf44c822007-11-25 14:01:38 +00001
2/*--------------------------------------------------------------------*/
bart3f4623e2008-07-07 16:53:07 +00003/*--- Client-space code for drd. drd_pthread_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
bart280990e2008-10-11 18:29:46 +000047#define _IO_MTSAFE_IO
sewardjaf44c822007-11-25 14:01:38 +000048#endif
49
50#include <assert.h>
bart4501d5c2008-03-04 18:36:23 +000051#include <inttypes.h> // uintptr_t
sewardj85642922008-01-14 11:54:56 +000052#include <pthread.h>
53#include <semaphore.h>
sewardjaf44c822007-11-25 14:01:38 +000054#include <stdio.h>
bart0d063002008-03-01 07:25:13 +000055#include <stdlib.h>
bart4501d5c2008-03-04 18:36:23 +000056#include <unistd.h> // confstr()
bart280990e2008-10-11 18:29:46 +000057#if defined(HAVE_BITS_LIBC_LOCK_H)
58#include <bits/libc-lock.h>
59#endif
bart5e389f12008-04-05 12:53:15 +000060#include "config.h"
sewardjaf44c822007-11-25 14:01:38 +000061#include "drd_clientreq.h"
sewardj85642922008-01-14 11:54:56 +000062#include "pub_tool_redir.h"
sewardjaf44c822007-11-25 14:01:38 +000063
64
65// Defines.
66
bart3772a982008-03-15 08:11:03 +000067#define PTH_FUNC(ret_ty, f, args...) \
68 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args); \
69 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args)
sewardjaf44c822007-11-25 14:01:38 +000070
71
bart6f07b252008-04-04 16:45:20 +000072/* Local data structures. */
sewardjaf44c822007-11-25 14:01:38 +000073
74typedef struct
75{
bart3772a982008-03-15 08:11:03 +000076 void* (*start)(void*);
77 void* arg;
78 int detachstate;
sewardjaf44c822007-11-25 14:01:38 +000079#if 0
bart3772a982008-03-15 08:11:03 +000080 pthread_mutex_t mutex;
81 pthread_cond_t cond;
sewardjaf44c822007-11-25 14:01:38 +000082#else
bart3772a982008-03-15 08:11:03 +000083 int wrapper_started;
sewardjaf44c822007-11-25 14:01:38 +000084#endif
85} VgPosixThreadArgs;
86
87
bart6f07b252008-04-04 16:45:20 +000088/* Function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000089
bart44ceea22008-04-16 18:19:45 +000090static void init(void) __attribute__((constructor));
bart6f07b252008-04-04 16:45:20 +000091static void check_threading_library(void);
92static void vg_set_main_thread_state(void);
sewardjaf44c822007-11-25 14:01:38 +000093
94
bart6f07b252008-04-04 16:45:20 +000095/* Function definitions. */
96
97/** Shared library initialization function: the _init() function is called
98 * after dlopen() has loaded the shared library. This function must not
99 * be declared static.
100 */
bart44ceea22008-04-16 18:19:45 +0000101static void init(void)
bart6f07b252008-04-04 16:45:20 +0000102{
103 check_threading_library();
bart0baacb32008-05-03 09:00:40 +0000104 vg_set_main_thread_state();
bart280990e2008-10-11 18:29:46 +0000105 /* glibc up to and including version 2.8 triggers conflicting accesses */
bart25d30032008-04-06 07:51:24 +0000106 /* on stdout and stderr when sending output to one of these streams from */
107 /* more than one thread. Suppress data race reports on these objects. */
108 DRD_IGNORE_VAR(*stdout);
109 DRD_IGNORE_VAR(*stderr);
bart280990e2008-10-11 18:29:46 +0000110#if defined(HAVE_BITS_LIBC_LOCK_H)
111 DRD_IGNORE_VAR(*(__libc_lock_recursive_t*)(stdout->_lock));
112 DRD_IGNORE_VAR(*(__libc_lock_recursive_t*)(stderr->_lock));
113#endif
bart6f07b252008-04-04 16:45:20 +0000114}
sewardjaf44c822007-11-25 14:01:38 +0000115
bart5357fcb2008-02-27 15:46:00 +0000116static MutexT pthread_to_drd_mutex_type(const int kind)
117{
bart3772a982008-03-15 08:11:03 +0000118 switch (kind)
119 {
120 /* PTHREAD_MUTEX_RECURSIVE_NP */
121 case PTHREAD_MUTEX_RECURSIVE:
122 return mutex_type_recursive_mutex;
123 /* PTHREAD_MUTEX_ERRORCHECK_NP */
124 case PTHREAD_MUTEX_ERRORCHECK:
125 return mutex_type_errorcheck_mutex;
126 /* PTHREAD_MUTEX_TIMED_NP */
127 /* PTHREAD_MUTEX_NORMAL */
128 case PTHREAD_MUTEX_DEFAULT:
bart85569572008-05-03 09:15:25 +0000129#if defined(HAVE_PTHREAD_MUTEX_ADAPTIVE_NP)
bart3772a982008-03-15 08:11:03 +0000130 case PTHREAD_MUTEX_ADAPTIVE_NP:
bart85569572008-05-03 09:15:25 +0000131#endif
bart3772a982008-03-15 08:11:03 +0000132 return mutex_type_default_mutex;
133 }
134 return mutex_type_invalid_mutex;
bart5357fcb2008-02-27 15:46:00 +0000135}
136
bart2bc9c102008-09-27 12:40:57 +0000137/** @note The function mutex_type() has been declared inline in order
138 * to avoid that it shows up in call stacks.
139 */
140static __inline__ MutexT mutex_type(pthread_mutex_t* mutex)
bart5357fcb2008-02-27 15:46:00 +0000141{
bart5e389f12008-04-05 12:53:15 +0000142#if defined(HAVE_PTHREAD_MUTEX_T__M_KIND)
143 /* LinuxThreads. */
bart3772a982008-03-15 08:11:03 +0000144 const int kind = mutex->__m_kind;
bart5e389f12008-04-05 12:53:15 +0000145#elif defined(HAVE_PTHREAD_MUTEX_T__DATA__KIND)
146 /* NPTL. */
bart3772a982008-03-15 08:11:03 +0000147 const int kind = mutex->__data.__kind;
bartc9463c42008-02-28 07:36:04 +0000148#else
bart5e389f12008-04-05 12:53:15 +0000149 /* Another POSIX threads implementation. Regression tests will fail. */
bart3772a982008-03-15 08:11:03 +0000150 const int kind = PTHREAD_MUTEX_DEFAULT;
bart5e389f12008-04-05 12:53:15 +0000151 fprintf(stderr,
152 "Did not recognize your POSIX threads implementation. Giving up.\n");
153 assert(0);
bartc9463c42008-02-28 07:36:04 +0000154#endif
bart3772a982008-03-15 08:11:03 +0000155 return pthread_to_drd_mutex_type(kind);
bart5357fcb2008-02-27 15:46:00 +0000156}
157
sewardjaf44c822007-11-25 14:01:38 +0000158static void vg_start_suppression(const void* const p, size_t const size)
159{
bart3772a982008-03-15 08:11:03 +0000160 int res;
161 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
bartf5bb46a2008-03-29 13:18:02 +0000162 p, size, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000163}
164
165static void vg_set_joinable(const pthread_t tid, const int joinable)
166{
bart3772a982008-03-15 08:11:03 +0000167 int res;
168 assert(joinable == 0 || joinable == 1);
169 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_JOINABLE,
170 tid, joinable, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000171}
172
173static void* vg_thread_wrapper(void* arg)
174{
bart3772a982008-03-15 08:11:03 +0000175 int res;
bart0d063002008-03-01 07:25:13 +0000176
bart3772a982008-03-15 08:11:03 +0000177 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
178 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000179
bart3772a982008-03-15 08:11:03 +0000180 {
181 VgPosixThreadArgs* const arg_ptr = (VgPosixThreadArgs*)arg;
182 VgPosixThreadArgs const arg_copy = *arg_ptr;
183 void* result;
sewardjaf44c822007-11-25 14:01:38 +0000184
185#if 0
bart3772a982008-03-15 08:11:03 +0000186 pthread_mutex_lock(arg_ptr->mutex);
187 pthread_cond_signal(arg_ptr->cond);
188 pthread_mutex_unlock(arg_ptr->mutex);
sewardjaf44c822007-11-25 14:01:38 +0000189#else
bart3772a982008-03-15 08:11:03 +0000190 arg_ptr->wrapper_started = 1;
sewardjaf44c822007-11-25 14:01:38 +0000191#endif
192
bart3772a982008-03-15 08:11:03 +0000193 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
194 pthread_self(), 0, 0, 0, 0);
195 vg_set_joinable(pthread_self(),
196 arg_copy.detachstate == PTHREAD_CREATE_JOINABLE);
197 result = (arg_copy.start)(arg_copy.arg);
198 return result;
199 }
sewardjaf44c822007-11-25 14:01:38 +0000200}
201
bart6f07b252008-04-04 16:45:20 +0000202/** Return 1 if LinuxThread has been detected, and 0 otherwise. */
bart4501d5c2008-03-04 18:36:23 +0000203static int detected_linuxthreads(void)
204{
205#if defined(linux)
206#if defined(_CS_GNU_LIBPTHREAD_VERSION)
bart3772a982008-03-15 08:11:03 +0000207 /* Linux with a recent glibc. */
208 char buffer[256];
209 unsigned len;
210 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
211 assert(len <= sizeof(buffer));
212 return len > 0 && buffer[0] == 'l';
bart4501d5c2008-03-04 18:36:23 +0000213#else
bart3772a982008-03-15 08:11:03 +0000214 /* Linux without _CS_GNU_LIBPTHREAD_VERSION: most likely LinuxThreads. */
215 return 1;
bart4501d5c2008-03-04 18:36:23 +0000216#endif
217#else
bart3772a982008-03-15 08:11:03 +0000218 /* Another OS than Linux, hence no LinuxThreads. */
219 return 0;
bart4501d5c2008-03-04 18:36:23 +0000220#endif
221}
222
bart6f07b252008-04-04 16:45:20 +0000223/** Stop and print an error message in case a non-supported threading
224 * library (LinuxThreads) has been detected.
225 */
226static void check_threading_library(void)
sewardjaf44c822007-11-25 14:01:38 +0000227{
bart3772a982008-03-15 08:11:03 +0000228 if (detected_linuxthreads())
229 {
230 if (getenv("LD_ASSUME_KERNEL"))
231 {
232 fprintf(stderr,
233 "Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
234 "the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
235 "after having unset the environment variable LD_ASSUME_KERNEL. Giving up.\n"
236 );
237 }
238 else
239 {
240 fprintf(stderr,
241 "Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
242 "the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
243 "after having upgraded to a newer version of your Linux distribution.\n"
244 "Giving up.\n"
245 );
246 }
247 abort();
248 }
bart6f07b252008-04-04 16:45:20 +0000249}
250
251static void vg_set_main_thread_state(void)
252{
253 int res;
bart0d063002008-03-01 07:25:13 +0000254
bart3772a982008-03-15 08:11:03 +0000255 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
256 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000257
bart3772a982008-03-15 08:11:03 +0000258 // Make sure that DRD knows about the main thread's POSIX thread ID.
259 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
260 pthread_self(), 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000261
262}
263
264// pthread_create
sewardj347eeba2008-01-21 14:19:07 +0000265PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
bart3772a982008-03-15 08:11:03 +0000266 pthread_t *thread, const pthread_attr_t *attr,
267 void *(*start) (void *), void *arg)
sewardjaf44c822007-11-25 14:01:38 +0000268{
bartbf3a60c2008-04-04 19:10:21 +0000269 int res;
bart3772a982008-03-15 08:11:03 +0000270 int ret;
271 OrigFn fn;
272 VgPosixThreadArgs vgargs;
sewardjaf44c822007-11-25 14:01:38 +0000273
bart3772a982008-03-15 08:11:03 +0000274 VALGRIND_GET_ORIG_FN(fn);
sewardjaf44c822007-11-25 14:01:38 +0000275
bart3772a982008-03-15 08:11:03 +0000276 vg_start_suppression(&vgargs.wrapper_started,
277 sizeof(vgargs.wrapper_started));
278 vgargs.start = start;
279 vgargs.arg = arg;
280 vgargs.wrapper_started = 0;
281 vgargs.detachstate = PTHREAD_CREATE_JOINABLE;
282 if (attr)
283 {
284 if (pthread_attr_getdetachstate(attr, &vgargs.detachstate) != 0)
285 {
286 assert(0);
287 }
288 }
289 assert(vgargs.detachstate == PTHREAD_CREATE_JOINABLE
290 || vgargs.detachstate == PTHREAD_CREATE_DETACHED);
sewardjaf44c822007-11-25 14:01:38 +0000291#if 0
bart3772a982008-03-15 08:11:03 +0000292 pthread_mutex_init(&vgargs.mutex, 0);
293 pthread_cond_init(&vgargs.cond, 0);
294 pthread_mutex_lock(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000295#endif
bartbf3a60c2008-04-04 19:10:21 +0000296 /* Suppress NPTL-specific conflicts between creator and created thread. */
297 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_STOP_RECORDING,
298 0, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000299 CALL_FN_W_WWWW(ret, fn, thread, attr, vg_thread_wrapper, &vgargs);
bartbf3a60c2008-04-04 19:10:21 +0000300 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_START_RECORDING,
301 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000302#if 0
bart3772a982008-03-15 08:11:03 +0000303 pthread_cond_wait(&vgargs.cond, &vgargs.mutex);
304 pthread_mutex_unlock(&vgargs.mutex);
305 pthread_cond_destroy(&vgargs.cond);
306 pthread_mutex_destroy(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000307#else
bart3772a982008-03-15 08:11:03 +0000308 // Yes, you see it correctly, busy waiting ... The problem is that
309 // POSIX threads functions cannot be called here -- the functions defined
310 // in this file (drd_intercepts.c) would be called instead of those in
311 // libpthread.so. This loop is necessary because vgargs is allocated on the
312 // stack, and the created thread reads it.
313 if (ret == 0)
314 {
315 while (! vgargs.wrapper_started)
316 {
317 sched_yield();
318 }
319 }
sewardjaf44c822007-11-25 14:01:38 +0000320#endif
bart3772a982008-03-15 08:11:03 +0000321 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000322}
323
324// pthread_join
325PTH_FUNC(int, pthreadZujoin, // pthread_join
bart3772a982008-03-15 08:11:03 +0000326 pthread_t pt_joinee, void **thread_return)
sewardjaf44c822007-11-25 14:01:38 +0000327{
bart3772a982008-03-15 08:11:03 +0000328 int ret;
329 int res;
330 OrigFn fn;
sewardjaf44c822007-11-25 14:01:38 +0000331
bart3772a982008-03-15 08:11:03 +0000332 VALGRIND_GET_ORIG_FN(fn);
333 CALL_FN_W_WW(ret, fn, pt_joinee, thread_return);
334 if (ret == 0)
335 {
336 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_JOIN,
337 pt_joinee, 0, 0, 0, 0);
338 }
339 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000340}
341
342// pthread_detach
343PTH_FUNC(int, pthreadZudetach, pthread_t pt_thread)
344{
bart3772a982008-03-15 08:11:03 +0000345 int ret;
346 OrigFn fn;
347 VALGRIND_GET_ORIG_FN(fn);
348 {
349 CALL_FN_W_W(ret, fn, pt_thread);
350 if (ret == 0)
351 {
352 vg_set_joinable(pt_thread, 0);
353 }
354 }
355 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000356}
357
bart2bc9c102008-09-27 12:40:57 +0000358// pthread_cancel
359PTH_FUNC(int, pthreadZucancel, pthread_t pt_thread)
360{
361 int res;
362 int ret;
363 OrigFn fn;
364 VALGRIND_GET_ORIG_FN(fn);
365 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_THREAD_CANCEL,
366 pt_thread, 0, 0, 0, 0);
367 CALL_FN_W_W(ret, fn, pt_thread);
368 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_CANCEL,
369 pt_thread, ret==0, 0, 0, 0);
370 return ret;
371}
372
sewardjaf44c822007-11-25 14:01:38 +0000373// pthread_mutex_init
374PTH_FUNC(int, pthreadZumutexZuinit,
bart3772a982008-03-15 08:11:03 +0000375 pthread_mutex_t *mutex,
376 const pthread_mutexattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000377{
bart3772a982008-03-15 08:11:03 +0000378 int ret;
379 int res;
380 OrigFn fn;
381 int mt;
382 VALGRIND_GET_ORIG_FN(fn);
383 mt = PTHREAD_MUTEX_DEFAULT;
384 if (attr)
385 pthread_mutexattr_gettype(attr, &mt);
386 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
387 mutex, pthread_to_drd_mutex_type(mt), 0, 0, 0);
388 CALL_FN_W_WW(ret, fn, mutex, attr);
389 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT,
390 mutex, 0, 0, 0, 0);
391 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000392}
393
394// pthread_mutex_destroy
395PTH_FUNC(int, pthreadZumutexZudestroy,
bart3772a982008-03-15 08:11:03 +0000396 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000397{
bart3772a982008-03-15 08:11:03 +0000398 int ret;
399 int res;
400 OrigFn fn;
401 VALGRIND_GET_ORIG_FN(fn);
402 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
403 mutex, 0, 0, 0, 0);
404 CALL_FN_W_W(ret, fn, mutex);
405 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
406 mutex, mutex_type(mutex), 0, 0, 0);
407 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000408}
409
410// pthread_mutex_lock
411PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
bart3772a982008-03-15 08:11:03 +0000412 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000413{
bart3772a982008-03-15 08:11:03 +0000414 int ret;
415 int res;
416 OrigFn fn;
417 VALGRIND_GET_ORIG_FN(fn);
418 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
419 mutex, mutex_type(mutex), 0, 0, 0);
420 CALL_FN_W_W(ret, fn, mutex);
421 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_MUTEX_LOCK,
422 mutex, ret == 0, 0, 0, 0);
423 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000424}
425
426// pthread_mutex_trylock
427PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
bart3772a982008-03-15 08:11:03 +0000428 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000429{
bart3772a982008-03-15 08:11:03 +0000430 int ret;
431 int res;
432 OrigFn fn;
433 VALGRIND_GET_ORIG_FN(fn);
434 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
bart2e3a3c12008-03-24 08:33:47 +0000435 mutex, mutex_type(mutex), 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000436 CALL_FN_W_W(ret, fn, mutex);
437 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
438 mutex, ret == 0, 0, 0, 0);
439 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000440}
441
sewardj85642922008-01-14 11:54:56 +0000442// pthread_mutex_timedlock
443PTH_FUNC(int, pthreadZumutexZutimedlock, // pthread_mutex_timedlock
bart3772a982008-03-15 08:11:03 +0000444 pthread_mutex_t *mutex,
445 const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000446{
bart3772a982008-03-15 08:11:03 +0000447 int ret;
448 int res;
449 OrigFn fn;
450 VALGRIND_GET_ORIG_FN(fn);
451 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
452 mutex, mutex_type(mutex), 0, 0, 0);
453 CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
454 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
455 mutex, ret == 0, 0, 0, 0);
456 return ret;
sewardj85642922008-01-14 11:54:56 +0000457}
458
sewardjaf44c822007-11-25 14:01:38 +0000459// pthread_mutex_unlock
460PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
bart3772a982008-03-15 08:11:03 +0000461 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000462{
bart3772a982008-03-15 08:11:03 +0000463 int ret;
464 int res;
465 OrigFn fn;
466 VALGRIND_GET_ORIG_FN(fn);
467 VALGRIND_DO_CLIENT_REQUEST(res, -1,
468 VG_USERREQ__PRE_MUTEX_UNLOCK,
469 mutex, mutex_type(mutex), 0, 0, 0);
470 CALL_FN_W_W(ret, fn, mutex);
471 VALGRIND_DO_CLIENT_REQUEST(res, -1,
472 VG_USERREQ__POST_MUTEX_UNLOCK,
473 mutex, 0, 0, 0, 0);
474 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000475}
476
477// pthread_cond_init
sewardj347eeba2008-01-21 14:19:07 +0000478PTH_FUNC(int, pthreadZucondZuinitZa, // pthread_cond_init*
bart3772a982008-03-15 08:11:03 +0000479 pthread_cond_t* cond,
480 const pthread_condattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000481{
bart3772a982008-03-15 08:11:03 +0000482 int ret;
483 int res;
484 OrigFn fn;
485 VALGRIND_GET_ORIG_FN(fn);
486 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_INIT,
487 cond, 0, 0, 0, 0);
488 CALL_FN_W_WW(ret, fn, cond, attr);
bart3f4623e2008-07-07 16:53:07 +0000489 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_INIT,
490 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000491 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000492}
493
494// pthread_cond_destroy
sewardj347eeba2008-01-21 14:19:07 +0000495PTH_FUNC(int, pthreadZucondZudestroyZa, // pthread_cond_destroy*
bart3772a982008-03-15 08:11:03 +0000496 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000497{
bart3772a982008-03-15 08:11:03 +0000498 int ret;
499 int res;
500 OrigFn fn;
501 VALGRIND_GET_ORIG_FN(fn);
bart3f4623e2008-07-07 16:53:07 +0000502 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_DESTROY,
503 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000504 CALL_FN_W_W(ret, fn, cond);
505 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_DESTROY,
506 cond, 0, 0, 0, 0);
507 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000508}
509
510// pthread_cond_wait
sewardj347eeba2008-01-21 14:19:07 +0000511PTH_FUNC(int, pthreadZucondZuwaitZa, // pthread_cond_wait*
bart3772a982008-03-15 08:11:03 +0000512 pthread_cond_t *cond,
513 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000514{
bart3772a982008-03-15 08:11:03 +0000515 int ret;
516 int res;
517 OrigFn fn;
518 VALGRIND_GET_ORIG_FN(fn);
519 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
520 cond, mutex, mutex_type(mutex), 0, 0);
521 CALL_FN_W_WW(ret, fn, cond, mutex);
522 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000523 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000524 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000525}
526
527// pthread_cond_timedwait
sewardj347eeba2008-01-21 14:19:07 +0000528PTH_FUNC(int, pthreadZucondZutimedwaitZa, // pthread_cond_timedwait*
bart3772a982008-03-15 08:11:03 +0000529 pthread_cond_t *cond,
530 pthread_mutex_t *mutex,
531 const struct timespec* abstime)
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_WAIT,
538 cond, mutex, mutex_type(mutex), 0, 0);
539 CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
540 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000541 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000542 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000543}
544
545// pthread_cond_signal
sewardj347eeba2008-01-21 14:19:07 +0000546PTH_FUNC(int, pthreadZucondZusignalZa, // pthread_cond_signal*
bart3772a982008-03-15 08:11:03 +0000547 pthread_cond_t* cond)
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);
553 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_SIGNAL,
554 cond, 0, 0, 0, 0);
555 CALL_FN_W_W(ret, fn, cond);
bart3f4623e2008-07-07 16:53:07 +0000556 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_SIGNAL,
557 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000558 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000559}
560
561// pthread_cond_broadcast
sewardj347eeba2008-01-21 14:19:07 +0000562PTH_FUNC(int, pthreadZucondZubroadcastZa, // pthread_cond_broadcast*
bart3772a982008-03-15 08:11:03 +0000563 pthread_cond_t* cond)
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);
569 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_BROADCAST,
570 cond, 0, 0, 0, 0);
571 CALL_FN_W_W(ret, fn, cond);
bart3f4623e2008-07-07 16:53:07 +0000572 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_BROADCAST,
573 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000574 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000575}
576
577
578// pthread_spin_init
579PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
bart3772a982008-03-15 08:11:03 +0000580 pthread_spinlock_t *spinlock,
581 int pshared)
sewardjaf44c822007-11-25 14:01:38 +0000582{
bart3772a982008-03-15 08:11:03 +0000583 int ret;
584 int res;
585 OrigFn fn;
586 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000587 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
588 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000589 CALL_FN_W_WW(ret, fn, spinlock, pshared);
bartf4f05812008-07-07 08:10:56 +0000590 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
591 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000592 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000593}
594
595// pthread_spin_destroy
596PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
bart3772a982008-03-15 08:11:03 +0000597 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000598{
bart3772a982008-03-15 08:11:03 +0000599 int ret;
600 int res;
601 OrigFn fn;
602 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000603 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
604 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000605 CALL_FN_W_W(ret, fn, spinlock);
606 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
607 spinlock, mutex_type_spinlock, 0, 0, 0);
608 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000609}
610
611// pthread_spin_lock
612PTH_FUNC(int, pthreadZuspinZulock, // pthread_spin_lock
bart3772a982008-03-15 08:11:03 +0000613 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000614{
bart3772a982008-03-15 08:11:03 +0000615 int ret;
616 int res;
617 OrigFn fn;
618 VALGRIND_GET_ORIG_FN(fn);
619 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
620 spinlock, mutex_type_spinlock, 0, 0, 0);
621 CALL_FN_W_W(ret, fn, spinlock);
622 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
623 spinlock, ret == 0, 0, 0, 0);
624 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000625}
626
627// pthread_spin_trylock
628PTH_FUNC(int, pthreadZuspinZutrylock, // pthread_spin_trylock
bart3772a982008-03-15 08:11:03 +0000629 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +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, 0, VG_USERREQ__PRE_MUTEX_LOCK,
636 spinlock, mutex_type_spinlock, 0, 0, 0);
637 CALL_FN_W_W(ret, fn, spinlock);
638 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
639 spinlock, ret == 0, 0, 0, 0);
640 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000641}
642
643// pthread_spin_unlock
644PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock
bart3772a982008-03-15 08:11:03 +0000645 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000646{
bart3772a982008-03-15 08:11:03 +0000647 int ret;
648 int res;
649 OrigFn fn;
650 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000651 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
bart3772a982008-03-15 08:11:03 +0000652 spinlock, mutex_type_spinlock, 0, 0, 0);
653 CALL_FN_W_W(ret, fn, spinlock);
bartf4f05812008-07-07 08:10:56 +0000654 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
655 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000656 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000657}
658
sewardj85642922008-01-14 11:54:56 +0000659// pthread_barrier_init
660PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
bart3772a982008-03-15 08:11:03 +0000661 pthread_barrier_t* barrier,
662 const pthread_barrierattr_t* attr,
663 unsigned count)
sewardj85642922008-01-14 11:54:56 +0000664{
bart3772a982008-03-15 08:11:03 +0000665 int ret;
666 int res;
667 OrigFn fn;
668 VALGRIND_GET_ORIG_FN(fn);
669 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_INIT,
670 barrier, pthread_barrier, count, 0, 0);
671 CALL_FN_W_WWW(ret, fn, barrier, attr, count);
672 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_INIT,
673 barrier, pthread_barrier, 0, 0, 0);
674 return ret;
sewardj85642922008-01-14 11:54:56 +0000675}
676
677// pthread_barrier_destroy
678PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
bart3772a982008-03-15 08:11:03 +0000679 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000680{
bart3772a982008-03-15 08:11:03 +0000681 int ret;
682 int res;
683 OrigFn fn;
684 VALGRIND_GET_ORIG_FN(fn);
685 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_DESTROY,
686 barrier, pthread_barrier, 0, 0, 0);
687 CALL_FN_W_W(ret, fn, barrier);
688 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_DESTROY,
689 barrier, pthread_barrier, 0, 0, 0);
690 return ret;
sewardj85642922008-01-14 11:54:56 +0000691}
692
693// pthread_barrier_wait
694PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
bart3772a982008-03-15 08:11:03 +0000695 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000696{
bart3772a982008-03-15 08:11:03 +0000697 int ret;
698 int res;
699 OrigFn fn;
700 VALGRIND_GET_ORIG_FN(fn);
701 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT,
702 barrier, pthread_barrier, 0, 0, 0);
703 CALL_FN_W_W(ret, fn, barrier);
704 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
705 barrier, pthread_barrier,
706 ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
707 0, 0);
708 return ret;
sewardj85642922008-01-14 11:54:56 +0000709}
710
711
sewardj85642922008-01-14 11:54:56 +0000712// sem_init
bart368ec982008-03-11 20:39:01 +0000713PTH_FUNC(int, semZuinitZa, // sem_init*
bart3772a982008-03-15 08:11:03 +0000714 sem_t *sem,
715 int pshared,
716 unsigned int value)
sewardj85642922008-01-14 11:54:56 +0000717{
bart3772a982008-03-15 08:11:03 +0000718 int ret;
719 int res;
720 OrigFn fn;
721 VALGRIND_GET_ORIG_FN(fn);
722 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_INIT,
723 sem, pshared, value, 0, 0);
724 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
725 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_INIT,
726 sem, 0, 0, 0, 0);
727 return ret;
sewardj85642922008-01-14 11:54:56 +0000728}
729
730// sem_destroy
bart00344642008-03-01 15:27:41 +0000731PTH_FUNC(int, semZudestroyZa, // sem_destroy*
bart3772a982008-03-15 08:11:03 +0000732 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000733{
bart3772a982008-03-15 08:11:03 +0000734 int ret;
735 int res;
736 OrigFn fn;
737 VALGRIND_GET_ORIG_FN(fn);
738 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_DESTROY,
739 sem, 0, 0, 0, 0);
740 CALL_FN_W_W(ret, fn, sem);
741 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_DESTROY,
742 sem, 0, 0, 0, 0);
743 return ret;
sewardj85642922008-01-14 11:54:56 +0000744}
745
746// sem_wait
bart368ec982008-03-11 20:39:01 +0000747PTH_FUNC(int, semZuwaitZa, // sem_wait*
bart3772a982008-03-15 08:11:03 +0000748 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000749{
bart3772a982008-03-15 08:11:03 +0000750 int ret;
751 int res;
752 OrigFn fn;
753 VALGRIND_GET_ORIG_FN(fn);
754 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
755 sem, 0, 0, 0, 0);
756 CALL_FN_W_W(ret, fn, sem);
757 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
758 sem, ret == 0, 0, 0, 0);
759 return ret;
sewardj85642922008-01-14 11:54:56 +0000760}
761
762// sem_trywait
bart00344642008-03-01 15:27:41 +0000763PTH_FUNC(int, semZutrywaitZa, // sem_trywait*
bart3772a982008-03-15 08:11:03 +0000764 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000765{
bart3772a982008-03-15 08:11:03 +0000766 int ret;
767 int res;
768 OrigFn fn;
769 VALGRIND_GET_ORIG_FN(fn);
770 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
771 sem, 0, 0, 0, 0);
772 CALL_FN_W_W(ret, fn, sem);
773 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
774 sem, ret == 0, 0, 0, 0);
775 return ret;
sewardj85642922008-01-14 11:54:56 +0000776}
777
778// sem_timedwait
bart00344642008-03-01 15:27:41 +0000779PTH_FUNC(int, semZutimedwait, // sem_timedwait
bart3772a982008-03-15 08:11:03 +0000780 sem_t *sem, const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000781{
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_SEM_WAIT,
787 sem, 0, 0, 0, 0);
788 CALL_FN_W_WW(ret, fn, sem, abs_timeout);
789 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
790 sem, ret == 0, 0, 0, 0);
791 return ret;
sewardj85642922008-01-14 11:54:56 +0000792}
793
794// sem_post
bart368ec982008-03-11 20:39:01 +0000795PTH_FUNC(int, semZupostZa, // sem_post*
bart3772a982008-03-15 08:11:03 +0000796 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000797{
bart3772a982008-03-15 08:11:03 +0000798 int ret;
799 int res;
800 OrigFn fn;
801 VALGRIND_GET_ORIG_FN(fn);
802 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
803 sem, 0, 0, 0, 0);
804 CALL_FN_W_W(ret, fn, sem);
805 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
806 sem, ret == 0, 0, 0, 0);
807 return ret;
sewardj85642922008-01-14 11:54:56 +0000808}
809
bart00344642008-03-01 15:27:41 +0000810// pthread_rwlock_init
811PTH_FUNC(int,
812 pthreadZurwlockZuinitZa, // pthread_rwlock_init*
813 pthread_rwlock_t* rwlock,
814 const pthread_rwlockattr_t* attr)
815{
bart3772a982008-03-15 08:11:03 +0000816 int ret;
817 int res;
818 OrigFn fn;
819 VALGRIND_GET_ORIG_FN(fn);
820 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_INIT,
821 rwlock, 0, 0, 0, 0);
822 CALL_FN_W_WW(ret, fn, rwlock, attr);
823 return ret;
bart00344642008-03-01 15:27:41 +0000824}
825
826// pthread_rwlock_destroy
827PTH_FUNC(int,
828 pthreadZurwlockZudestroyZa, // pthread_rwlock_destroy*
829 pthread_rwlock_t* rwlock)
830{
bart3772a982008-03-15 08:11:03 +0000831 int ret;
832 int res;
833 OrigFn fn;
834 VALGRIND_GET_ORIG_FN(fn);
835 CALL_FN_W_W(ret, fn, rwlock);
836 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_DESTROY,
837 rwlock, 0, 0, 0, 0);
838 return ret;
bart00344642008-03-01 15:27:41 +0000839}
840
841// pthread_rwlock_rdlock
842PTH_FUNC(int,
843 pthreadZurwlockZurdlockZa, // pthread_rwlock_rdlock*
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_wrlock
859PTH_FUNC(int,
860 pthreadZurwlockZuwrlockZa, // pthread_rwlock_wrlock*
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_timedrdlock
876PTH_FUNC(int,
877 pthreadZurwlockZutimedrdlockZa, // pthread_rwlock_timedrdlock*
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_timedwrlock
893PTH_FUNC(int,
894 pthreadZurwlockZutimedwrlockZa, // pthread_rwlock_timedwrlock*
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_tryrdlock
910PTH_FUNC(int,
911 pthreadZurwlockZutryrdlockZa, // pthread_rwlock_tryrdlock*
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_RDLOCK,
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_RDLOCK,
922 rwlock, ret == 0, 0, 0, 0);
923 return ret;
bart00344642008-03-01 15:27:41 +0000924}
925
926// pthread_rwlock_trywrlock
927PTH_FUNC(int,
928 pthreadZurwlockZutrywrlockZa, // pthread_rwlock_trywrlock*
929 pthread_rwlock_t* rwlock)
930{
bart3772a982008-03-15 08:11:03 +0000931 int ret;
932 int res;
933 OrigFn fn;
934 VALGRIND_GET_ORIG_FN(fn);
935 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
936 rwlock, 0, 0, 0, 0);
937 CALL_FN_W_W(ret, fn, rwlock);
938 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
939 rwlock, ret == 0, 0, 0, 0);
940 return ret;
bart00344642008-03-01 15:27:41 +0000941}
942
943// pthread_rwlock_unlock
944PTH_FUNC(int,
945 pthreadZurwlockZuunlockZa, // pthread_rwlock_unlock*
946 pthread_rwlock_t* rwlock)
947{
bart3772a982008-03-15 08:11:03 +0000948 int ret;
949 int res;
950 OrigFn fn;
951 VALGRIND_GET_ORIG_FN(fn);
952 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_UNLOCK,
953 rwlock, 0, 0, 0, 0);
954 CALL_FN_W_W(ret, fn, rwlock);
955 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_UNLOCK,
956 rwlock, ret == 0, 0, 0, 0);
957 return ret;
bart00344642008-03-01 15:27:41 +0000958}