blob: 7e6c5a3ce67204ad64b6a66ae28af20ebafa124b [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()
bart5e389f12008-04-05 12:53:15 +000057#include "config.h"
sewardjaf44c822007-11-25 14:01:38 +000058#include "drd_clientreq.h"
sewardj85642922008-01-14 11:54:56 +000059#include "pub_tool_redir.h"
sewardjaf44c822007-11-25 14:01:38 +000060
61
62// Defines.
63
bart3772a982008-03-15 08:11:03 +000064#define PTH_FUNC(ret_ty, f, args...) \
65 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args); \
66 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args)
sewardjaf44c822007-11-25 14:01:38 +000067
68
bart6f07b252008-04-04 16:45:20 +000069/* Local data structures. */
sewardjaf44c822007-11-25 14:01:38 +000070
71typedef struct
72{
bart3772a982008-03-15 08:11:03 +000073 void* (*start)(void*);
74 void* arg;
75 int detachstate;
sewardjaf44c822007-11-25 14:01:38 +000076#if 0
bart3772a982008-03-15 08:11:03 +000077 pthread_mutex_t mutex;
78 pthread_cond_t cond;
sewardjaf44c822007-11-25 14:01:38 +000079#else
bart3772a982008-03-15 08:11:03 +000080 int wrapper_started;
sewardjaf44c822007-11-25 14:01:38 +000081#endif
82} VgPosixThreadArgs;
83
84
bart6f07b252008-04-04 16:45:20 +000085/* Function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000086
bart44ceea22008-04-16 18:19:45 +000087static void init(void) __attribute__((constructor));
bart6f07b252008-04-04 16:45:20 +000088static void check_threading_library(void);
89static void vg_set_main_thread_state(void);
sewardjaf44c822007-11-25 14:01:38 +000090
91
bart6f07b252008-04-04 16:45:20 +000092/* Function definitions. */
93
94/** Shared library initialization function: the _init() function is called
95 * after dlopen() has loaded the shared library. This function must not
96 * be declared static.
97 */
bart44ceea22008-04-16 18:19:45 +000098static void init(void)
bart6f07b252008-04-04 16:45:20 +000099{
100 check_threading_library();
bart0baacb32008-05-03 09:00:40 +0000101 vg_set_main_thread_state();
bart280990e2008-10-11 18:29:46 +0000102 /* glibc up to and including version 2.8 triggers conflicting accesses */
bart25d30032008-04-06 07:51:24 +0000103 /* on stdout and stderr when sending output to one of these streams from */
104 /* more than one thread. Suppress data race reports on these objects. */
105 DRD_IGNORE_VAR(*stdout);
106 DRD_IGNORE_VAR(*stderr);
bart280990e2008-10-11 18:29:46 +0000107#if defined(HAVE_BITS_LIBC_LOCK_H)
bart3a979cb2008-10-11 19:04:40 +0000108 DRD_IGNORE_VAR(*(pthread_mutex_t*)(stdout->_lock));
109 DRD_IGNORE_VAR(*(pthread_mutex_t*)(stderr->_lock));
bart280990e2008-10-11 18:29:46 +0000110#endif
bart6f07b252008-04-04 16:45:20 +0000111}
sewardjaf44c822007-11-25 14:01:38 +0000112
bart5357fcb2008-02-27 15:46:00 +0000113static MutexT pthread_to_drd_mutex_type(const int kind)
114{
bart3772a982008-03-15 08:11:03 +0000115 switch (kind)
116 {
117 /* PTHREAD_MUTEX_RECURSIVE_NP */
118 case PTHREAD_MUTEX_RECURSIVE:
119 return mutex_type_recursive_mutex;
120 /* PTHREAD_MUTEX_ERRORCHECK_NP */
121 case PTHREAD_MUTEX_ERRORCHECK:
122 return mutex_type_errorcheck_mutex;
123 /* PTHREAD_MUTEX_TIMED_NP */
124 /* PTHREAD_MUTEX_NORMAL */
125 case PTHREAD_MUTEX_DEFAULT:
bart85569572008-05-03 09:15:25 +0000126#if defined(HAVE_PTHREAD_MUTEX_ADAPTIVE_NP)
bart3772a982008-03-15 08:11:03 +0000127 case PTHREAD_MUTEX_ADAPTIVE_NP:
bart85569572008-05-03 09:15:25 +0000128#endif
bart3772a982008-03-15 08:11:03 +0000129 return mutex_type_default_mutex;
130 }
131 return mutex_type_invalid_mutex;
bart5357fcb2008-02-27 15:46:00 +0000132}
133
bart2bc9c102008-09-27 12:40:57 +0000134/** @note The function mutex_type() has been declared inline in order
135 * to avoid that it shows up in call stacks.
136 */
137static __inline__ MutexT mutex_type(pthread_mutex_t* mutex)
bart5357fcb2008-02-27 15:46:00 +0000138{
bart5e389f12008-04-05 12:53:15 +0000139#if defined(HAVE_PTHREAD_MUTEX_T__M_KIND)
140 /* LinuxThreads. */
bart3772a982008-03-15 08:11:03 +0000141 const int kind = mutex->__m_kind;
bart5e389f12008-04-05 12:53:15 +0000142#elif defined(HAVE_PTHREAD_MUTEX_T__DATA__KIND)
143 /* NPTL. */
bart3772a982008-03-15 08:11:03 +0000144 const int kind = mutex->__data.__kind;
bartc9463c42008-02-28 07:36:04 +0000145#else
bart5e389f12008-04-05 12:53:15 +0000146 /* Another POSIX threads implementation. Regression tests will fail. */
bart3772a982008-03-15 08:11:03 +0000147 const int kind = PTHREAD_MUTEX_DEFAULT;
bart5e389f12008-04-05 12:53:15 +0000148 fprintf(stderr,
149 "Did not recognize your POSIX threads implementation. Giving up.\n");
150 assert(0);
bartc9463c42008-02-28 07:36:04 +0000151#endif
bart3772a982008-03-15 08:11:03 +0000152 return pthread_to_drd_mutex_type(kind);
bart5357fcb2008-02-27 15:46:00 +0000153}
154
sewardjaf44c822007-11-25 14:01:38 +0000155static void vg_start_suppression(const void* const p, size_t const size)
156{
bart3772a982008-03-15 08:11:03 +0000157 int res;
158 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
bartf5bb46a2008-03-29 13:18:02 +0000159 p, size, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000160}
161
162static void vg_set_joinable(const pthread_t tid, const int joinable)
163{
bart3772a982008-03-15 08:11:03 +0000164 int res;
165 assert(joinable == 0 || joinable == 1);
166 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_JOINABLE,
167 tid, joinable, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000168}
169
170static void* vg_thread_wrapper(void* arg)
171{
bart3772a982008-03-15 08:11:03 +0000172 int res;
bart0d063002008-03-01 07:25:13 +0000173
bart3772a982008-03-15 08:11:03 +0000174 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
175 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000176
bart3772a982008-03-15 08:11:03 +0000177 {
178 VgPosixThreadArgs* const arg_ptr = (VgPosixThreadArgs*)arg;
179 VgPosixThreadArgs const arg_copy = *arg_ptr;
180 void* result;
sewardjaf44c822007-11-25 14:01:38 +0000181
182#if 0
bart3772a982008-03-15 08:11:03 +0000183 pthread_mutex_lock(arg_ptr->mutex);
184 pthread_cond_signal(arg_ptr->cond);
185 pthread_mutex_unlock(arg_ptr->mutex);
sewardjaf44c822007-11-25 14:01:38 +0000186#else
bart3772a982008-03-15 08:11:03 +0000187 arg_ptr->wrapper_started = 1;
sewardjaf44c822007-11-25 14:01:38 +0000188#endif
189
bart3772a982008-03-15 08:11:03 +0000190 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
191 pthread_self(), 0, 0, 0, 0);
192 vg_set_joinable(pthread_self(),
193 arg_copy.detachstate == PTHREAD_CREATE_JOINABLE);
194 result = (arg_copy.start)(arg_copy.arg);
195 return result;
196 }
sewardjaf44c822007-11-25 14:01:38 +0000197}
198
bart6f07b252008-04-04 16:45:20 +0000199/** Return 1 if LinuxThread has been detected, and 0 otherwise. */
bart4501d5c2008-03-04 18:36:23 +0000200static int detected_linuxthreads(void)
201{
202#if defined(linux)
203#if defined(_CS_GNU_LIBPTHREAD_VERSION)
bart3772a982008-03-15 08:11:03 +0000204 /* Linux with a recent glibc. */
205 char buffer[256];
206 unsigned len;
207 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
208 assert(len <= sizeof(buffer));
209 return len > 0 && buffer[0] == 'l';
bart4501d5c2008-03-04 18:36:23 +0000210#else
bart3772a982008-03-15 08:11:03 +0000211 /* Linux without _CS_GNU_LIBPTHREAD_VERSION: most likely LinuxThreads. */
212 return 1;
bart4501d5c2008-03-04 18:36:23 +0000213#endif
214#else
bart3772a982008-03-15 08:11:03 +0000215 /* Another OS than Linux, hence no LinuxThreads. */
216 return 0;
bart4501d5c2008-03-04 18:36:23 +0000217#endif
218}
219
bart6f07b252008-04-04 16:45:20 +0000220/** Stop and print an error message in case a non-supported threading
221 * library (LinuxThreads) has been detected.
222 */
223static void check_threading_library(void)
sewardjaf44c822007-11-25 14:01:38 +0000224{
bart3772a982008-03-15 08:11:03 +0000225 if (detected_linuxthreads())
226 {
227 if (getenv("LD_ASSUME_KERNEL"))
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 unset the environment variable LD_ASSUME_KERNEL. Giving up.\n"
233 );
234 }
235 else
236 {
237 fprintf(stderr,
238 "Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
239 "the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
240 "after having upgraded to a newer version of your Linux distribution.\n"
241 "Giving up.\n"
242 );
243 }
244 abort();
245 }
bart6f07b252008-04-04 16:45:20 +0000246}
247
248static void vg_set_main_thread_state(void)
249{
250 int res;
bart0d063002008-03-01 07:25:13 +0000251
bart3772a982008-03-15 08:11:03 +0000252 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
253 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000254
bart3772a982008-03-15 08:11:03 +0000255 // Make sure that DRD knows about the main thread's POSIX thread ID.
256 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
257 pthread_self(), 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000258
259}
260
261// pthread_create
sewardj347eeba2008-01-21 14:19:07 +0000262PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
bart3772a982008-03-15 08:11:03 +0000263 pthread_t *thread, const pthread_attr_t *attr,
264 void *(*start) (void *), void *arg)
sewardjaf44c822007-11-25 14:01:38 +0000265{
bartbf3a60c2008-04-04 19:10:21 +0000266 int res;
bart3772a982008-03-15 08:11:03 +0000267 int ret;
268 OrigFn fn;
269 VgPosixThreadArgs vgargs;
sewardjaf44c822007-11-25 14:01:38 +0000270
bart3772a982008-03-15 08:11:03 +0000271 VALGRIND_GET_ORIG_FN(fn);
sewardjaf44c822007-11-25 14:01:38 +0000272
bart3772a982008-03-15 08:11:03 +0000273 vg_start_suppression(&vgargs.wrapper_started,
274 sizeof(vgargs.wrapper_started));
275 vgargs.start = start;
276 vgargs.arg = arg;
277 vgargs.wrapper_started = 0;
278 vgargs.detachstate = PTHREAD_CREATE_JOINABLE;
279 if (attr)
280 {
281 if (pthread_attr_getdetachstate(attr, &vgargs.detachstate) != 0)
282 {
283 assert(0);
284 }
285 }
286 assert(vgargs.detachstate == PTHREAD_CREATE_JOINABLE
287 || vgargs.detachstate == PTHREAD_CREATE_DETACHED);
sewardjaf44c822007-11-25 14:01:38 +0000288#if 0
bart3772a982008-03-15 08:11:03 +0000289 pthread_mutex_init(&vgargs.mutex, 0);
290 pthread_cond_init(&vgargs.cond, 0);
291 pthread_mutex_lock(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000292#endif
bartbf3a60c2008-04-04 19:10:21 +0000293 /* Suppress NPTL-specific conflicts between creator and created thread. */
294 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_STOP_RECORDING,
295 0, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000296 CALL_FN_W_WWWW(ret, fn, thread, attr, vg_thread_wrapper, &vgargs);
bartbf3a60c2008-04-04 19:10:21 +0000297 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_START_RECORDING,
298 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000299#if 0
bart3772a982008-03-15 08:11:03 +0000300 pthread_cond_wait(&vgargs.cond, &vgargs.mutex);
301 pthread_mutex_unlock(&vgargs.mutex);
302 pthread_cond_destroy(&vgargs.cond);
303 pthread_mutex_destroy(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000304#else
bart3772a982008-03-15 08:11:03 +0000305 // Yes, you see it correctly, busy waiting ... The problem is that
306 // POSIX threads functions cannot be called here -- the functions defined
307 // in this file (drd_intercepts.c) would be called instead of those in
308 // libpthread.so. This loop is necessary because vgargs is allocated on the
309 // stack, and the created thread reads it.
310 if (ret == 0)
311 {
312 while (! vgargs.wrapper_started)
313 {
314 sched_yield();
315 }
316 }
sewardjaf44c822007-11-25 14:01:38 +0000317#endif
bart3772a982008-03-15 08:11:03 +0000318 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000319}
320
321// pthread_join
322PTH_FUNC(int, pthreadZujoin, // pthread_join
bart3772a982008-03-15 08:11:03 +0000323 pthread_t pt_joinee, void **thread_return)
sewardjaf44c822007-11-25 14:01:38 +0000324{
bart3772a982008-03-15 08:11:03 +0000325 int ret;
326 int res;
327 OrigFn fn;
sewardjaf44c822007-11-25 14:01:38 +0000328
bart3772a982008-03-15 08:11:03 +0000329 VALGRIND_GET_ORIG_FN(fn);
330 CALL_FN_W_WW(ret, fn, pt_joinee, thread_return);
331 if (ret == 0)
332 {
333 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_JOIN,
334 pt_joinee, 0, 0, 0, 0);
335 }
336 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000337}
338
339// pthread_detach
340PTH_FUNC(int, pthreadZudetach, pthread_t pt_thread)
341{
bart3772a982008-03-15 08:11:03 +0000342 int ret;
343 OrigFn fn;
344 VALGRIND_GET_ORIG_FN(fn);
345 {
346 CALL_FN_W_W(ret, fn, pt_thread);
347 if (ret == 0)
348 {
349 vg_set_joinable(pt_thread, 0);
350 }
351 }
352 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000353}
354
bart2bc9c102008-09-27 12:40:57 +0000355// pthread_cancel
356PTH_FUNC(int, pthreadZucancel, pthread_t pt_thread)
357{
358 int res;
359 int ret;
360 OrigFn fn;
361 VALGRIND_GET_ORIG_FN(fn);
362 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_THREAD_CANCEL,
363 pt_thread, 0, 0, 0, 0);
364 CALL_FN_W_W(ret, fn, pt_thread);
365 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_CANCEL,
366 pt_thread, ret==0, 0, 0, 0);
367 return ret;
368}
369
sewardjaf44c822007-11-25 14:01:38 +0000370// pthread_mutex_init
371PTH_FUNC(int, pthreadZumutexZuinit,
bart3772a982008-03-15 08:11:03 +0000372 pthread_mutex_t *mutex,
373 const pthread_mutexattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000374{
bart3772a982008-03-15 08:11:03 +0000375 int ret;
376 int res;
377 OrigFn fn;
378 int mt;
379 VALGRIND_GET_ORIG_FN(fn);
380 mt = PTHREAD_MUTEX_DEFAULT;
381 if (attr)
382 pthread_mutexattr_gettype(attr, &mt);
383 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
384 mutex, pthread_to_drd_mutex_type(mt), 0, 0, 0);
385 CALL_FN_W_WW(ret, fn, mutex, attr);
386 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT,
387 mutex, 0, 0, 0, 0);
388 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000389}
390
391// pthread_mutex_destroy
392PTH_FUNC(int, pthreadZumutexZudestroy,
bart3772a982008-03-15 08:11:03 +0000393 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000394{
bart3772a982008-03-15 08:11:03 +0000395 int ret;
396 int res;
397 OrigFn fn;
398 VALGRIND_GET_ORIG_FN(fn);
399 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
400 mutex, 0, 0, 0, 0);
401 CALL_FN_W_W(ret, fn, mutex);
402 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
403 mutex, mutex_type(mutex), 0, 0, 0);
404 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000405}
406
407// pthread_mutex_lock
408PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
bart3772a982008-03-15 08:11:03 +0000409 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000410{
bart3772a982008-03-15 08:11:03 +0000411 int ret;
412 int res;
413 OrigFn fn;
414 VALGRIND_GET_ORIG_FN(fn);
415 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
416 mutex, mutex_type(mutex), 0, 0, 0);
417 CALL_FN_W_W(ret, fn, mutex);
418 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_MUTEX_LOCK,
419 mutex, ret == 0, 0, 0, 0);
420 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000421}
422
423// pthread_mutex_trylock
424PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
bart3772a982008-03-15 08:11:03 +0000425 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000426{
bart3772a982008-03-15 08:11:03 +0000427 int ret;
428 int res;
429 OrigFn fn;
430 VALGRIND_GET_ORIG_FN(fn);
431 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
bart2e3a3c12008-03-24 08:33:47 +0000432 mutex, mutex_type(mutex), 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000433 CALL_FN_W_W(ret, fn, mutex);
434 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
435 mutex, ret == 0, 0, 0, 0);
436 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000437}
438
sewardj85642922008-01-14 11:54:56 +0000439// pthread_mutex_timedlock
440PTH_FUNC(int, pthreadZumutexZutimedlock, // pthread_mutex_timedlock
bart3772a982008-03-15 08:11:03 +0000441 pthread_mutex_t *mutex,
442 const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000443{
bart3772a982008-03-15 08:11:03 +0000444 int ret;
445 int res;
446 OrigFn fn;
447 VALGRIND_GET_ORIG_FN(fn);
448 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
449 mutex, mutex_type(mutex), 0, 0, 0);
450 CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
451 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
452 mutex, ret == 0, 0, 0, 0);
453 return ret;
sewardj85642922008-01-14 11:54:56 +0000454}
455
sewardjaf44c822007-11-25 14:01:38 +0000456// pthread_mutex_unlock
457PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
bart3772a982008-03-15 08:11:03 +0000458 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000459{
bart3772a982008-03-15 08:11:03 +0000460 int ret;
461 int res;
462 OrigFn fn;
463 VALGRIND_GET_ORIG_FN(fn);
464 VALGRIND_DO_CLIENT_REQUEST(res, -1,
465 VG_USERREQ__PRE_MUTEX_UNLOCK,
466 mutex, mutex_type(mutex), 0, 0, 0);
467 CALL_FN_W_W(ret, fn, mutex);
468 VALGRIND_DO_CLIENT_REQUEST(res, -1,
469 VG_USERREQ__POST_MUTEX_UNLOCK,
470 mutex, 0, 0, 0, 0);
471 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000472}
473
474// pthread_cond_init
sewardj347eeba2008-01-21 14:19:07 +0000475PTH_FUNC(int, pthreadZucondZuinitZa, // pthread_cond_init*
bart3772a982008-03-15 08:11:03 +0000476 pthread_cond_t* cond,
477 const pthread_condattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000478{
bart3772a982008-03-15 08:11:03 +0000479 int ret;
480 int res;
481 OrigFn fn;
482 VALGRIND_GET_ORIG_FN(fn);
483 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_INIT,
484 cond, 0, 0, 0, 0);
485 CALL_FN_W_WW(ret, fn, cond, attr);
bart3f4623e2008-07-07 16:53:07 +0000486 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_INIT,
487 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000488 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000489}
490
491// pthread_cond_destroy
sewardj347eeba2008-01-21 14:19:07 +0000492PTH_FUNC(int, pthreadZucondZudestroyZa, // pthread_cond_destroy*
bart3772a982008-03-15 08:11:03 +0000493 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000494{
bart3772a982008-03-15 08:11:03 +0000495 int ret;
496 int res;
497 OrigFn fn;
498 VALGRIND_GET_ORIG_FN(fn);
bart3f4623e2008-07-07 16:53:07 +0000499 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_DESTROY,
500 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000501 CALL_FN_W_W(ret, fn, cond);
502 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_DESTROY,
503 cond, 0, 0, 0, 0);
504 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000505}
506
507// pthread_cond_wait
sewardj347eeba2008-01-21 14:19:07 +0000508PTH_FUNC(int, pthreadZucondZuwaitZa, // pthread_cond_wait*
bart3772a982008-03-15 08:11:03 +0000509 pthread_cond_t *cond,
510 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000511{
bart3772a982008-03-15 08:11:03 +0000512 int ret;
513 int res;
514 OrigFn fn;
515 VALGRIND_GET_ORIG_FN(fn);
516 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
517 cond, mutex, mutex_type(mutex), 0, 0);
518 CALL_FN_W_WW(ret, fn, cond, mutex);
519 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000520 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000521 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000522}
523
524// pthread_cond_timedwait
sewardj347eeba2008-01-21 14:19:07 +0000525PTH_FUNC(int, pthreadZucondZutimedwaitZa, // pthread_cond_timedwait*
bart3772a982008-03-15 08:11:03 +0000526 pthread_cond_t *cond,
527 pthread_mutex_t *mutex,
528 const struct timespec* abstime)
sewardjaf44c822007-11-25 14:01:38 +0000529{
bart3772a982008-03-15 08:11:03 +0000530 int ret;
531 int res;
532 OrigFn fn;
533 VALGRIND_GET_ORIG_FN(fn);
534 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
535 cond, mutex, mutex_type(mutex), 0, 0);
536 CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
537 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000538 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000539 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000540}
541
542// pthread_cond_signal
sewardj347eeba2008-01-21 14:19:07 +0000543PTH_FUNC(int, pthreadZucondZusignalZa, // pthread_cond_signal*
bart3772a982008-03-15 08:11:03 +0000544 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000545{
bart3772a982008-03-15 08:11:03 +0000546 int ret;
547 int res;
548 OrigFn fn;
549 VALGRIND_GET_ORIG_FN(fn);
550 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_SIGNAL,
551 cond, 0, 0, 0, 0);
552 CALL_FN_W_W(ret, fn, cond);
bart3f4623e2008-07-07 16:53:07 +0000553 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_SIGNAL,
554 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000555 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000556}
557
558// pthread_cond_broadcast
sewardj347eeba2008-01-21 14:19:07 +0000559PTH_FUNC(int, pthreadZucondZubroadcastZa, // pthread_cond_broadcast*
bart3772a982008-03-15 08:11:03 +0000560 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000561{
bart3772a982008-03-15 08:11:03 +0000562 int ret;
563 int res;
564 OrigFn fn;
565 VALGRIND_GET_ORIG_FN(fn);
566 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_BROADCAST,
567 cond, 0, 0, 0, 0);
568 CALL_FN_W_W(ret, fn, cond);
bart3f4623e2008-07-07 16:53:07 +0000569 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_BROADCAST,
570 cond, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000571 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000572}
573
574
575// pthread_spin_init
576PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
bart3772a982008-03-15 08:11:03 +0000577 pthread_spinlock_t *spinlock,
578 int pshared)
sewardjaf44c822007-11-25 14:01:38 +0000579{
bart3772a982008-03-15 08:11:03 +0000580 int ret;
581 int res;
582 OrigFn fn;
583 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000584 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
585 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000586 CALL_FN_W_WW(ret, fn, spinlock, pshared);
bartf4f05812008-07-07 08:10:56 +0000587 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
588 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000589 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000590}
591
592// pthread_spin_destroy
593PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
bart3772a982008-03-15 08:11:03 +0000594 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000595{
bart3772a982008-03-15 08:11:03 +0000596 int ret;
597 int res;
598 OrigFn fn;
599 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000600 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
601 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000602 CALL_FN_W_W(ret, fn, spinlock);
603 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
604 spinlock, mutex_type_spinlock, 0, 0, 0);
605 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000606}
607
608// pthread_spin_lock
609PTH_FUNC(int, pthreadZuspinZulock, // pthread_spin_lock
bart3772a982008-03-15 08:11:03 +0000610 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000611{
bart3772a982008-03-15 08:11:03 +0000612 int ret;
613 int res;
614 OrigFn fn;
615 VALGRIND_GET_ORIG_FN(fn);
616 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
617 spinlock, mutex_type_spinlock, 0, 0, 0);
618 CALL_FN_W_W(ret, fn, spinlock);
619 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
620 spinlock, ret == 0, 0, 0, 0);
621 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000622}
623
624// pthread_spin_trylock
625PTH_FUNC(int, pthreadZuspinZutrylock, // pthread_spin_trylock
bart3772a982008-03-15 08:11:03 +0000626 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000627{
bart3772a982008-03-15 08:11:03 +0000628 int ret;
629 int res;
630 OrigFn fn;
631 VALGRIND_GET_ORIG_FN(fn);
632 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
633 spinlock, mutex_type_spinlock, 0, 0, 0);
634 CALL_FN_W_W(ret, fn, spinlock);
635 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
636 spinlock, ret == 0, 0, 0, 0);
637 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000638}
639
640// pthread_spin_unlock
641PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock
bart3772a982008-03-15 08:11:03 +0000642 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000643{
bart3772a982008-03-15 08:11:03 +0000644 int ret;
645 int res;
646 OrigFn fn;
647 VALGRIND_GET_ORIG_FN(fn);
bartf4f05812008-07-07 08:10:56 +0000648 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK,
bart3772a982008-03-15 08:11:03 +0000649 spinlock, mutex_type_spinlock, 0, 0, 0);
650 CALL_FN_W_W(ret, fn, spinlock);
bartf4f05812008-07-07 08:10:56 +0000651 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK,
652 spinlock, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000653 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000654}
655
sewardj85642922008-01-14 11:54:56 +0000656// pthread_barrier_init
657PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
bart3772a982008-03-15 08:11:03 +0000658 pthread_barrier_t* barrier,
659 const pthread_barrierattr_t* attr,
660 unsigned count)
sewardj85642922008-01-14 11:54:56 +0000661{
bart3772a982008-03-15 08:11:03 +0000662 int ret;
663 int res;
664 OrigFn fn;
665 VALGRIND_GET_ORIG_FN(fn);
666 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_INIT,
667 barrier, pthread_barrier, count, 0, 0);
668 CALL_FN_W_WWW(ret, fn, barrier, attr, count);
669 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_INIT,
670 barrier, pthread_barrier, 0, 0, 0);
671 return ret;
sewardj85642922008-01-14 11:54:56 +0000672}
673
674// pthread_barrier_destroy
675PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
bart3772a982008-03-15 08:11:03 +0000676 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000677{
bart3772a982008-03-15 08:11:03 +0000678 int ret;
679 int res;
680 OrigFn fn;
681 VALGRIND_GET_ORIG_FN(fn);
682 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_DESTROY,
683 barrier, pthread_barrier, 0, 0, 0);
684 CALL_FN_W_W(ret, fn, barrier);
685 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_DESTROY,
686 barrier, pthread_barrier, 0, 0, 0);
687 return ret;
sewardj85642922008-01-14 11:54:56 +0000688}
689
690// pthread_barrier_wait
691PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
bart3772a982008-03-15 08:11:03 +0000692 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000693{
bart3772a982008-03-15 08:11:03 +0000694 int ret;
695 int res;
696 OrigFn fn;
697 VALGRIND_GET_ORIG_FN(fn);
698 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT,
699 barrier, pthread_barrier, 0, 0, 0);
700 CALL_FN_W_W(ret, fn, barrier);
701 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
702 barrier, pthread_barrier,
703 ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
704 0, 0);
705 return ret;
sewardj85642922008-01-14 11:54:56 +0000706}
707
708
sewardj85642922008-01-14 11:54:56 +0000709// sem_init
bart368ec982008-03-11 20:39:01 +0000710PTH_FUNC(int, semZuinitZa, // sem_init*
bart3772a982008-03-15 08:11:03 +0000711 sem_t *sem,
712 int pshared,
713 unsigned int value)
sewardj85642922008-01-14 11:54:56 +0000714{
bart3772a982008-03-15 08:11:03 +0000715 int ret;
716 int res;
717 OrigFn fn;
718 VALGRIND_GET_ORIG_FN(fn);
719 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_INIT,
720 sem, pshared, value, 0, 0);
721 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
722 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_INIT,
723 sem, 0, 0, 0, 0);
724 return ret;
sewardj85642922008-01-14 11:54:56 +0000725}
726
727// sem_destroy
bart00344642008-03-01 15:27:41 +0000728PTH_FUNC(int, semZudestroyZa, // sem_destroy*
bart3772a982008-03-15 08:11:03 +0000729 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000730{
bart3772a982008-03-15 08:11:03 +0000731 int ret;
732 int res;
733 OrigFn fn;
734 VALGRIND_GET_ORIG_FN(fn);
735 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_DESTROY,
736 sem, 0, 0, 0, 0);
737 CALL_FN_W_W(ret, fn, sem);
738 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_DESTROY,
739 sem, 0, 0, 0, 0);
740 return ret;
sewardj85642922008-01-14 11:54:56 +0000741}
742
743// sem_wait
bart368ec982008-03-11 20:39:01 +0000744PTH_FUNC(int, semZuwaitZa, // sem_wait*
bart3772a982008-03-15 08:11:03 +0000745 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000746{
bart3772a982008-03-15 08:11:03 +0000747 int ret;
748 int res;
749 OrigFn fn;
750 VALGRIND_GET_ORIG_FN(fn);
751 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
752 sem, 0, 0, 0, 0);
753 CALL_FN_W_W(ret, fn, sem);
754 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
755 sem, ret == 0, 0, 0, 0);
756 return ret;
sewardj85642922008-01-14 11:54:56 +0000757}
758
759// sem_trywait
bart00344642008-03-01 15:27:41 +0000760PTH_FUNC(int, semZutrywaitZa, // sem_trywait*
bart3772a982008-03-15 08:11:03 +0000761 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000762{
bart3772a982008-03-15 08:11:03 +0000763 int ret;
764 int res;
765 OrigFn fn;
766 VALGRIND_GET_ORIG_FN(fn);
767 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
768 sem, 0, 0, 0, 0);
769 CALL_FN_W_W(ret, fn, sem);
770 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
771 sem, ret == 0, 0, 0, 0);
772 return ret;
sewardj85642922008-01-14 11:54:56 +0000773}
774
775// sem_timedwait
bart00344642008-03-01 15:27:41 +0000776PTH_FUNC(int, semZutimedwait, // sem_timedwait
bart3772a982008-03-15 08:11:03 +0000777 sem_t *sem, const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000778{
bart3772a982008-03-15 08:11:03 +0000779 int ret;
780 int res;
781 OrigFn fn;
782 VALGRIND_GET_ORIG_FN(fn);
783 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
784 sem, 0, 0, 0, 0);
785 CALL_FN_W_WW(ret, fn, sem, abs_timeout);
786 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
787 sem, ret == 0, 0, 0, 0);
788 return ret;
sewardj85642922008-01-14 11:54:56 +0000789}
790
791// sem_post
bart368ec982008-03-11 20:39:01 +0000792PTH_FUNC(int, semZupostZa, // sem_post*
bart3772a982008-03-15 08:11:03 +0000793 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000794{
bart3772a982008-03-15 08:11:03 +0000795 int ret;
796 int res;
797 OrigFn fn;
798 VALGRIND_GET_ORIG_FN(fn);
799 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
800 sem, 0, 0, 0, 0);
801 CALL_FN_W_W(ret, fn, sem);
802 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
803 sem, ret == 0, 0, 0, 0);
804 return ret;
sewardj85642922008-01-14 11:54:56 +0000805}
806
bart00344642008-03-01 15:27:41 +0000807// pthread_rwlock_init
808PTH_FUNC(int,
809 pthreadZurwlockZuinitZa, // pthread_rwlock_init*
810 pthread_rwlock_t* rwlock,
811 const pthread_rwlockattr_t* attr)
812{
bart3772a982008-03-15 08:11:03 +0000813 int ret;
814 int res;
815 OrigFn fn;
816 VALGRIND_GET_ORIG_FN(fn);
817 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_INIT,
818 rwlock, 0, 0, 0, 0);
819 CALL_FN_W_WW(ret, fn, rwlock, attr);
820 return ret;
bart00344642008-03-01 15:27:41 +0000821}
822
823// pthread_rwlock_destroy
824PTH_FUNC(int,
825 pthreadZurwlockZudestroyZa, // pthread_rwlock_destroy*
826 pthread_rwlock_t* rwlock)
827{
bart3772a982008-03-15 08:11:03 +0000828 int ret;
829 int res;
830 OrigFn fn;
831 VALGRIND_GET_ORIG_FN(fn);
832 CALL_FN_W_W(ret, fn, rwlock);
833 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_DESTROY,
834 rwlock, 0, 0, 0, 0);
835 return ret;
bart00344642008-03-01 15:27:41 +0000836}
837
838// pthread_rwlock_rdlock
839PTH_FUNC(int,
840 pthreadZurwlockZurdlockZa, // pthread_rwlock_rdlock*
841 pthread_rwlock_t* rwlock)
842{
bart3772a982008-03-15 08:11:03 +0000843 int ret;
844 int res;
845 OrigFn fn;
846 VALGRIND_GET_ORIG_FN(fn);
847 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
848 rwlock, 0, 0, 0, 0);
849 CALL_FN_W_W(ret, fn, rwlock);
850 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
851 rwlock, ret == 0, 0, 0, 0);
852 return ret;
bart00344642008-03-01 15:27:41 +0000853}
854
855// pthread_rwlock_wrlock
856PTH_FUNC(int,
857 pthreadZurwlockZuwrlockZa, // pthread_rwlock_wrlock*
858 pthread_rwlock_t* rwlock)
859{
bart3772a982008-03-15 08:11:03 +0000860 int ret;
861 int res;
862 OrigFn fn;
863 VALGRIND_GET_ORIG_FN(fn);
864 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
865 rwlock, 0, 0, 0, 0);
866 CALL_FN_W_W(ret, fn, rwlock);
867 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
868 rwlock, ret == 0, 0, 0, 0);
869 return ret;
bart00344642008-03-01 15:27:41 +0000870}
871
872// pthread_rwlock_timedrdlock
873PTH_FUNC(int,
874 pthreadZurwlockZutimedrdlockZa, // pthread_rwlock_timedrdlock*
875 pthread_rwlock_t* rwlock)
876{
bart3772a982008-03-15 08:11:03 +0000877 int ret;
878 int res;
879 OrigFn fn;
880 VALGRIND_GET_ORIG_FN(fn);
881 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
882 rwlock, 0, 0, 0, 0);
883 CALL_FN_W_W(ret, fn, rwlock);
884 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
885 rwlock, ret == 0, 0, 0, 0);
886 return ret;
bart00344642008-03-01 15:27:41 +0000887}
888
889// pthread_rwlock_timedwrlock
890PTH_FUNC(int,
891 pthreadZurwlockZutimedwrlockZa, // pthread_rwlock_timedwrlock*
892 pthread_rwlock_t* rwlock)
893{
bart3772a982008-03-15 08:11:03 +0000894 int ret;
895 int res;
896 OrigFn fn;
897 VALGRIND_GET_ORIG_FN(fn);
898 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
899 rwlock, 0, 0, 0, 0);
900 CALL_FN_W_W(ret, fn, rwlock);
901 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
902 rwlock, ret == 0, 0, 0, 0);
903 return ret;
bart00344642008-03-01 15:27:41 +0000904}
905
906// pthread_rwlock_tryrdlock
907PTH_FUNC(int,
908 pthreadZurwlockZutryrdlockZa, // pthread_rwlock_tryrdlock*
909 pthread_rwlock_t* rwlock)
910{
bart3772a982008-03-15 08:11:03 +0000911 int ret;
912 int res;
913 OrigFn fn;
914 VALGRIND_GET_ORIG_FN(fn);
915 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
916 rwlock, 0, 0, 0, 0);
917 CALL_FN_W_W(ret, fn, rwlock);
918 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
919 rwlock, ret == 0, 0, 0, 0);
920 return ret;
bart00344642008-03-01 15:27:41 +0000921}
922
923// pthread_rwlock_trywrlock
924PTH_FUNC(int,
925 pthreadZurwlockZutrywrlockZa, // pthread_rwlock_trywrlock*
926 pthread_rwlock_t* rwlock)
927{
bart3772a982008-03-15 08:11:03 +0000928 int ret;
929 int res;
930 OrigFn fn;
931 VALGRIND_GET_ORIG_FN(fn);
932 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
933 rwlock, 0, 0, 0, 0);
934 CALL_FN_W_W(ret, fn, rwlock);
935 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
936 rwlock, ret == 0, 0, 0, 0);
937 return ret;
bart00344642008-03-01 15:27:41 +0000938}
939
940// pthread_rwlock_unlock
941PTH_FUNC(int,
942 pthreadZurwlockZuunlockZa, // pthread_rwlock_unlock*
943 pthread_rwlock_t* rwlock)
944{
bart3772a982008-03-15 08:11:03 +0000945 int ret;
946 int res;
947 OrigFn fn;
948 VALGRIND_GET_ORIG_FN(fn);
949 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_UNLOCK,
950 rwlock, 0, 0, 0, 0);
951 CALL_FN_W_W(ret, fn, rwlock);
952 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_UNLOCK,
953 rwlock, ret == 0, 0, 0, 0);
954 return ret;
bart00344642008-03-01 15:27:41 +0000955}