blob: 064804e13ec0134f2f5afc7843785b03b0513ce5 [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
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);
bart3f4623e2008-07-07 16:53:07 +0000463 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_INIT,
464 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000465 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000466}
467
468// pthread_cond_destroy
sewardj347eeba2008-01-21 14:19:07 +0000469PTH_FUNC(int, pthreadZucondZudestroyZa, // pthread_cond_destroy*
bart3772a982008-03-15 08:11:03 +0000470 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000471{
bart3772a982008-03-15 08:11:03 +0000472 int ret;
473 int res;
474 OrigFn fn;
475 VALGRIND_GET_ORIG_FN(fn);
bart3f4623e2008-07-07 16:53:07 +0000476 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_DESTROY,
477 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000478 CALL_FN_W_W(ret, fn, cond);
479 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_DESTROY,
480 cond, 0, 0, 0, 0);
481 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000482}
483
484// pthread_cond_wait
sewardj347eeba2008-01-21 14:19:07 +0000485PTH_FUNC(int, pthreadZucondZuwaitZa, // pthread_cond_wait*
bart3772a982008-03-15 08:11:03 +0000486 pthread_cond_t *cond,
487 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000488{
bart3772a982008-03-15 08:11:03 +0000489 int ret;
490 int res;
491 OrigFn fn;
492 VALGRIND_GET_ORIG_FN(fn);
493 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
494 cond, mutex, mutex_type(mutex), 0, 0);
495 CALL_FN_W_WW(ret, fn, cond, mutex);
496 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000497 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000498 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000499}
500
501// pthread_cond_timedwait
sewardj347eeba2008-01-21 14:19:07 +0000502PTH_FUNC(int, pthreadZucondZutimedwaitZa, // pthread_cond_timedwait*
bart3772a982008-03-15 08:11:03 +0000503 pthread_cond_t *cond,
504 pthread_mutex_t *mutex,
505 const struct timespec* abstime)
sewardjaf44c822007-11-25 14:01:38 +0000506{
bart3772a982008-03-15 08:11:03 +0000507 int ret;
508 int res;
509 OrigFn fn;
510 VALGRIND_GET_ORIG_FN(fn);
511 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
512 cond, mutex, mutex_type(mutex), 0, 0);
513 CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
514 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000515 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000516 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000517}
518
519// pthread_cond_signal
sewardj347eeba2008-01-21 14:19:07 +0000520PTH_FUNC(int, pthreadZucondZusignalZa, // pthread_cond_signal*
bart3772a982008-03-15 08:11:03 +0000521 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000522{
bart3772a982008-03-15 08:11:03 +0000523 int ret;
524 int res;
525 OrigFn fn;
526 VALGRIND_GET_ORIG_FN(fn);
527 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_SIGNAL,
528 cond, 0, 0, 0, 0);
529 CALL_FN_W_W(ret, fn, cond);
bart3f4623e2008-07-07 16:53:07 +0000530 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_SIGNAL,
531 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000532 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000533}
534
535// pthread_cond_broadcast
sewardj347eeba2008-01-21 14:19:07 +0000536PTH_FUNC(int, pthreadZucondZubroadcastZa, // pthread_cond_broadcast*
bart3772a982008-03-15 08:11:03 +0000537 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000538{
bart3772a982008-03-15 08:11:03 +0000539 int ret;
540 int res;
541 OrigFn fn;
542 VALGRIND_GET_ORIG_FN(fn);
543 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_BROADCAST,
544 cond, 0, 0, 0, 0);
545 CALL_FN_W_W(ret, fn, cond);
bart3f4623e2008-07-07 16:53:07 +0000546 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_BROADCAST,
547 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000548 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000549}
550
551
552// pthread_spin_init
553PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
bart3772a982008-03-15 08:11:03 +0000554 pthread_spinlock_t *spinlock,
555 int pshared)
sewardjaf44c822007-11-25 14:01:38 +0000556{
bart3772a982008-03-15 08:11:03 +0000557 int ret;
558 int res;
559 OrigFn fn;
560 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000561 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
562 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000563 CALL_FN_W_WW(ret, fn, spinlock, pshared);
bartf4f05812008-07-07 08:10:56 +0000564 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
565 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000566 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000567}
568
569// pthread_spin_destroy
570PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
bart3772a982008-03-15 08:11:03 +0000571 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000572{
bart3772a982008-03-15 08:11:03 +0000573 int ret;
574 int res;
575 OrigFn fn;
576 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000577 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
578 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000579 CALL_FN_W_W(ret, fn, spinlock);
580 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
581 spinlock, mutex_type_spinlock, 0, 0, 0);
582 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000583}
584
585// pthread_spin_lock
586PTH_FUNC(int, pthreadZuspinZulock, // pthread_spin_lock
bart3772a982008-03-15 08:11:03 +0000587 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000588{
bart3772a982008-03-15 08:11:03 +0000589 int ret;
590 int res;
591 OrigFn fn;
592 VALGRIND_GET_ORIG_FN(fn);
593 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
594 spinlock, mutex_type_spinlock, 0, 0, 0);
595 CALL_FN_W_W(ret, fn, spinlock);
596 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
597 spinlock, ret == 0, 0, 0, 0);
598 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000599}
600
601// pthread_spin_trylock
602PTH_FUNC(int, pthreadZuspinZutrylock, // pthread_spin_trylock
bart3772a982008-03-15 08:11:03 +0000603 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000604{
bart3772a982008-03-15 08:11:03 +0000605 int ret;
606 int res;
607 OrigFn fn;
608 VALGRIND_GET_ORIG_FN(fn);
609 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
610 spinlock, mutex_type_spinlock, 0, 0, 0);
611 CALL_FN_W_W(ret, fn, spinlock);
612 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
613 spinlock, ret == 0, 0, 0, 0);
614 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000615}
616
617// pthread_spin_unlock
618PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock
bart3772a982008-03-15 08:11:03 +0000619 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000620{
bart3772a982008-03-15 08:11:03 +0000621 int ret;
622 int res;
623 OrigFn fn;
624 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000625 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
bart3772a982008-03-15 08:11:03 +0000626 spinlock, mutex_type_spinlock, 0, 0, 0);
627 CALL_FN_W_W(ret, fn, spinlock);
bartf4f05812008-07-07 08:10:56 +0000628 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
629 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000630 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000631}
632
sewardj85642922008-01-14 11:54:56 +0000633// pthread_barrier_init
634PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
bart3772a982008-03-15 08:11:03 +0000635 pthread_barrier_t* barrier,
636 const pthread_barrierattr_t* attr,
637 unsigned count)
sewardj85642922008-01-14 11:54:56 +0000638{
bart3772a982008-03-15 08:11:03 +0000639 int ret;
640 int res;
641 OrigFn fn;
642 VALGRIND_GET_ORIG_FN(fn);
643 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_INIT,
644 barrier, pthread_barrier, count, 0, 0);
645 CALL_FN_W_WWW(ret, fn, barrier, attr, count);
646 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_INIT,
647 barrier, pthread_barrier, 0, 0, 0);
648 return ret;
sewardj85642922008-01-14 11:54:56 +0000649}
650
651// pthread_barrier_destroy
652PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
bart3772a982008-03-15 08:11:03 +0000653 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000654{
bart3772a982008-03-15 08:11:03 +0000655 int ret;
656 int res;
657 OrigFn fn;
658 VALGRIND_GET_ORIG_FN(fn);
659 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_DESTROY,
660 barrier, pthread_barrier, 0, 0, 0);
661 CALL_FN_W_W(ret, fn, barrier);
662 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_DESTROY,
663 barrier, pthread_barrier, 0, 0, 0);
664 return ret;
sewardj85642922008-01-14 11:54:56 +0000665}
666
667// pthread_barrier_wait
668PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
bart3772a982008-03-15 08:11:03 +0000669 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000670{
bart3772a982008-03-15 08:11:03 +0000671 int ret;
672 int res;
673 OrigFn fn;
674 VALGRIND_GET_ORIG_FN(fn);
675 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT,
676 barrier, pthread_barrier, 0, 0, 0);
677 CALL_FN_W_W(ret, fn, barrier);
678 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
679 barrier, pthread_barrier,
680 ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
681 0, 0);
682 return ret;
sewardj85642922008-01-14 11:54:56 +0000683}
684
685
sewardj85642922008-01-14 11:54:56 +0000686// sem_init
bart368ec982008-03-11 20:39:01 +0000687PTH_FUNC(int, semZuinitZa, // sem_init*
bart3772a982008-03-15 08:11:03 +0000688 sem_t *sem,
689 int pshared,
690 unsigned int value)
sewardj85642922008-01-14 11:54:56 +0000691{
bart3772a982008-03-15 08:11:03 +0000692 int ret;
693 int res;
694 OrigFn fn;
695 VALGRIND_GET_ORIG_FN(fn);
696 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_INIT,
697 sem, pshared, value, 0, 0);
698 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
699 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_INIT,
700 sem, 0, 0, 0, 0);
701 return ret;
sewardj85642922008-01-14 11:54:56 +0000702}
703
704// sem_destroy
bart00344642008-03-01 15:27:41 +0000705PTH_FUNC(int, semZudestroyZa, // sem_destroy*
bart3772a982008-03-15 08:11:03 +0000706 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000707{
bart3772a982008-03-15 08:11:03 +0000708 int ret;
709 int res;
710 OrigFn fn;
711 VALGRIND_GET_ORIG_FN(fn);
712 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_DESTROY,
713 sem, 0, 0, 0, 0);
714 CALL_FN_W_W(ret, fn, sem);
715 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_DESTROY,
716 sem, 0, 0, 0, 0);
717 return ret;
sewardj85642922008-01-14 11:54:56 +0000718}
719
720// sem_wait
bart368ec982008-03-11 20:39:01 +0000721PTH_FUNC(int, semZuwaitZa, // sem_wait*
bart3772a982008-03-15 08:11:03 +0000722 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000723{
bart3772a982008-03-15 08:11:03 +0000724 int ret;
725 int res;
726 OrigFn fn;
727 VALGRIND_GET_ORIG_FN(fn);
728 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
729 sem, 0, 0, 0, 0);
730 CALL_FN_W_W(ret, fn, sem);
731 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
732 sem, ret == 0, 0, 0, 0);
733 return ret;
sewardj85642922008-01-14 11:54:56 +0000734}
735
736// sem_trywait
bart00344642008-03-01 15:27:41 +0000737PTH_FUNC(int, semZutrywaitZa, // sem_trywait*
bart3772a982008-03-15 08:11:03 +0000738 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000739{
bart3772a982008-03-15 08:11:03 +0000740 int ret;
741 int res;
742 OrigFn fn;
743 VALGRIND_GET_ORIG_FN(fn);
744 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
745 sem, 0, 0, 0, 0);
746 CALL_FN_W_W(ret, fn, sem);
747 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
748 sem, ret == 0, 0, 0, 0);
749 return ret;
sewardj85642922008-01-14 11:54:56 +0000750}
751
752// sem_timedwait
bart00344642008-03-01 15:27:41 +0000753PTH_FUNC(int, semZutimedwait, // sem_timedwait
bart3772a982008-03-15 08:11:03 +0000754 sem_t *sem, const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000755{
bart3772a982008-03-15 08:11:03 +0000756 int ret;
757 int res;
758 OrigFn fn;
759 VALGRIND_GET_ORIG_FN(fn);
760 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
761 sem, 0, 0, 0, 0);
762 CALL_FN_W_WW(ret, fn, sem, abs_timeout);
763 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
764 sem, ret == 0, 0, 0, 0);
765 return ret;
sewardj85642922008-01-14 11:54:56 +0000766}
767
768// sem_post
bart368ec982008-03-11 20:39:01 +0000769PTH_FUNC(int, semZupostZa, // sem_post*
bart3772a982008-03-15 08:11:03 +0000770 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000771{
bart3772a982008-03-15 08:11:03 +0000772 int ret;
773 int res;
774 OrigFn fn;
775 VALGRIND_GET_ORIG_FN(fn);
776 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
777 sem, 0, 0, 0, 0);
778 CALL_FN_W_W(ret, fn, sem);
779 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
780 sem, ret == 0, 0, 0, 0);
781 return ret;
sewardj85642922008-01-14 11:54:56 +0000782}
783
bart00344642008-03-01 15:27:41 +0000784// pthread_rwlock_init
785PTH_FUNC(int,
786 pthreadZurwlockZuinitZa, // pthread_rwlock_init*
787 pthread_rwlock_t* rwlock,
788 const pthread_rwlockattr_t* attr)
789{
bart3772a982008-03-15 08:11:03 +0000790 int ret;
791 int res;
792 OrigFn fn;
793 VALGRIND_GET_ORIG_FN(fn);
794 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_INIT,
795 rwlock, 0, 0, 0, 0);
796 CALL_FN_W_WW(ret, fn, rwlock, attr);
797 return ret;
bart00344642008-03-01 15:27:41 +0000798}
799
800// pthread_rwlock_destroy
801PTH_FUNC(int,
802 pthreadZurwlockZudestroyZa, // pthread_rwlock_destroy*
803 pthread_rwlock_t* rwlock)
804{
bart3772a982008-03-15 08:11:03 +0000805 int ret;
806 int res;
807 OrigFn fn;
808 VALGRIND_GET_ORIG_FN(fn);
809 CALL_FN_W_W(ret, fn, rwlock);
810 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_DESTROY,
811 rwlock, 0, 0, 0, 0);
812 return ret;
bart00344642008-03-01 15:27:41 +0000813}
814
815// pthread_rwlock_rdlock
816PTH_FUNC(int,
817 pthreadZurwlockZurdlockZa, // pthread_rwlock_rdlock*
818 pthread_rwlock_t* rwlock)
819{
bart3772a982008-03-15 08:11:03 +0000820 int ret;
821 int res;
822 OrigFn fn;
823 VALGRIND_GET_ORIG_FN(fn);
824 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
825 rwlock, 0, 0, 0, 0);
826 CALL_FN_W_W(ret, fn, rwlock);
827 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
828 rwlock, ret == 0, 0, 0, 0);
829 return ret;
bart00344642008-03-01 15:27:41 +0000830}
831
832// pthread_rwlock_wrlock
833PTH_FUNC(int,
834 pthreadZurwlockZuwrlockZa, // pthread_rwlock_wrlock*
835 pthread_rwlock_t* rwlock)
836{
bart3772a982008-03-15 08:11:03 +0000837 int ret;
838 int res;
839 OrigFn fn;
840 VALGRIND_GET_ORIG_FN(fn);
841 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
842 rwlock, 0, 0, 0, 0);
843 CALL_FN_W_W(ret, fn, rwlock);
844 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
845 rwlock, ret == 0, 0, 0, 0);
846 return ret;
bart00344642008-03-01 15:27:41 +0000847}
848
849// pthread_rwlock_timedrdlock
850PTH_FUNC(int,
851 pthreadZurwlockZutimedrdlockZa, // pthread_rwlock_timedrdlock*
852 pthread_rwlock_t* rwlock)
853{
bart3772a982008-03-15 08:11:03 +0000854 int ret;
855 int res;
856 OrigFn fn;
857 VALGRIND_GET_ORIG_FN(fn);
858 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
859 rwlock, 0, 0, 0, 0);
860 CALL_FN_W_W(ret, fn, rwlock);
861 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
862 rwlock, ret == 0, 0, 0, 0);
863 return ret;
bart00344642008-03-01 15:27:41 +0000864}
865
866// pthread_rwlock_timedwrlock
867PTH_FUNC(int,
868 pthreadZurwlockZutimedwrlockZa, // pthread_rwlock_timedwrlock*
869 pthread_rwlock_t* rwlock)
870{
bart3772a982008-03-15 08:11:03 +0000871 int ret;
872 int res;
873 OrigFn fn;
874 VALGRIND_GET_ORIG_FN(fn);
875 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
876 rwlock, 0, 0, 0, 0);
877 CALL_FN_W_W(ret, fn, rwlock);
878 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
879 rwlock, ret == 0, 0, 0, 0);
880 return ret;
bart00344642008-03-01 15:27:41 +0000881}
882
883// pthread_rwlock_tryrdlock
884PTH_FUNC(int,
885 pthreadZurwlockZutryrdlockZa, // pthread_rwlock_tryrdlock*
886 pthread_rwlock_t* rwlock)
887{
bart3772a982008-03-15 08:11:03 +0000888 int ret;
889 int res;
890 OrigFn fn;
891 VALGRIND_GET_ORIG_FN(fn);
892 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
893 rwlock, 0, 0, 0, 0);
894 CALL_FN_W_W(ret, fn, rwlock);
895 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
896 rwlock, ret == 0, 0, 0, 0);
897 return ret;
bart00344642008-03-01 15:27:41 +0000898}
899
900// pthread_rwlock_trywrlock
901PTH_FUNC(int,
902 pthreadZurwlockZutrywrlockZa, // pthread_rwlock_trywrlock*
903 pthread_rwlock_t* rwlock)
904{
bart3772a982008-03-15 08:11:03 +0000905 int ret;
906 int res;
907 OrigFn fn;
908 VALGRIND_GET_ORIG_FN(fn);
909 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
910 rwlock, 0, 0, 0, 0);
911 CALL_FN_W_W(ret, fn, rwlock);
912 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
913 rwlock, ret == 0, 0, 0, 0);
914 return ret;
bart00344642008-03-01 15:27:41 +0000915}
916
917// pthread_rwlock_unlock
918PTH_FUNC(int,
919 pthreadZurwlockZuunlockZa, // pthread_rwlock_unlock*
920 pthread_rwlock_t* rwlock)
921{
bart3772a982008-03-15 08:11:03 +0000922 int ret;
923 int res;
924 OrigFn fn;
925 VALGRIND_GET_ORIG_FN(fn);
926 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_UNLOCK,
927 rwlock, 0, 0, 0, 0);
928 CALL_FN_W_W(ret, fn, rwlock);
929 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_UNLOCK,
930 rwlock, ret == 0, 0, 0, 0);
931 return ret;
bart00344642008-03-01 15:27:41 +0000932}