blob: 2c1b7734dad920e595390155e65673ca2b80c85a [file] [log] [blame]
sewardjaf44c822007-11-25 14:01:38 +00001
2/*--------------------------------------------------------------------*/
sewardj85642922008-01-14 11:54:56 +00003/*--- Client-space code for drd. drd_intercepts.c ---*/
sewardjaf44c822007-11-25 14:01:38 +00004/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of drd, a data race detector.
8
sewardj85642922008-01-14 11:54:56 +00009 Copyright (C) 2006-2008 Bart Van Assche
sewardjaf44c822007-11-25 14:01:38 +000010 bart.vanassche@gmail.com
11
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 02111-1307, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28*/
29
30/* ---------------------------------------------------------------------
31 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
32
33 These functions are not called directly - they're the targets of code
34 redirection or load notifications (see pub_core_redir.h for info).
35 They're named weirdly so that the intercept code can find them when the
36 shared object is initially loaded.
37
38 Note that this filename has the "drd_" prefix because it can appear
39 in stack traces, and the "drd_" makes it a little clearer that it
40 originates from Valgrind.
41 ------------------------------------------------------------------ */
42
bart5e85d262008-03-01 10:49:37 +000043// Make sure pthread_spinlock_t is available when compiling with older glibc
44// versions (2.3 or before).
sewardjaf44c822007-11-25 14:01:38 +000045#ifndef _GNU_SOURCE
46#define _GNU_SOURCE
47#endif
48
49#include <assert.h>
bart4501d5c2008-03-04 18:36:23 +000050#include <inttypes.h> // uintptr_t
sewardj85642922008-01-14 11:54:56 +000051#include <pthread.h>
52#include <semaphore.h>
sewardjaf44c822007-11-25 14:01:38 +000053#include <stdio.h>
bart0d063002008-03-01 07:25:13 +000054#include <stdlib.h>
bart4501d5c2008-03-04 18:36:23 +000055#include <unistd.h> // confstr()
sewardjaf44c822007-11-25 14:01:38 +000056#include "drd_clientreq.h"
sewardj85642922008-01-14 11:54:56 +000057#include "pub_tool_redir.h"
sewardjaf44c822007-11-25 14:01:38 +000058
59
60// Defines.
61
bart3772a982008-03-15 08:11:03 +000062#define PTH_FUNC(ret_ty, f, args...) \
63 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args); \
64 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args)
sewardjaf44c822007-11-25 14:01:38 +000065
66
bart6f07b252008-04-04 16:45:20 +000067/* Local data structures. */
sewardjaf44c822007-11-25 14:01:38 +000068
69typedef struct
70{
bart3772a982008-03-15 08:11:03 +000071 void* (*start)(void*);
72 void* arg;
73 int detachstate;
sewardjaf44c822007-11-25 14:01:38 +000074#if 0
bart3772a982008-03-15 08:11:03 +000075 pthread_mutex_t mutex;
76 pthread_cond_t cond;
sewardjaf44c822007-11-25 14:01:38 +000077#else
bart3772a982008-03-15 08:11:03 +000078 int wrapper_started;
sewardjaf44c822007-11-25 14:01:38 +000079#endif
80} VgPosixThreadArgs;
81
82
bart6f07b252008-04-04 16:45:20 +000083/* Function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000084
bart6f07b252008-04-04 16:45:20 +000085void _init(void);
86static void check_threading_library(void);
87static void vg_set_main_thread_state(void);
sewardjaf44c822007-11-25 14:01:38 +000088
89
bart6f07b252008-04-04 16:45:20 +000090/* Function definitions. */
91
92/** Shared library initialization function: the _init() function is called
93 * after dlopen() has loaded the shared library. This function must not
94 * be declared static.
95 */
96void _init(void)
97{
98 check_threading_library();
99 vg_set_main_thread_state();
100}
sewardjaf44c822007-11-25 14:01:38 +0000101
bart5357fcb2008-02-27 15:46:00 +0000102static MutexT pthread_to_drd_mutex_type(const int kind)
103{
bart3772a982008-03-15 08:11:03 +0000104 switch (kind)
105 {
106 /* PTHREAD_MUTEX_RECURSIVE_NP */
107 case PTHREAD_MUTEX_RECURSIVE:
108 return mutex_type_recursive_mutex;
109 /* PTHREAD_MUTEX_ERRORCHECK_NP */
110 case PTHREAD_MUTEX_ERRORCHECK:
111 return mutex_type_errorcheck_mutex;
112 /* PTHREAD_MUTEX_TIMED_NP */
113 /* PTHREAD_MUTEX_NORMAL */
114 case PTHREAD_MUTEX_DEFAULT:
115 case PTHREAD_MUTEX_ADAPTIVE_NP:
116 return mutex_type_default_mutex;
117 }
118 return mutex_type_invalid_mutex;
bart5357fcb2008-02-27 15:46:00 +0000119}
120
121static MutexT mutex_type(pthread_mutex_t* mutex)
122{
bartc9463c42008-02-28 07:36:04 +0000123#if defined(_PTHREAD_DESCR_DEFINED)
bart3772a982008-03-15 08:11:03 +0000124 // Linuxthreads.
125 const int kind = mutex->__m_kind;
bartc9463c42008-02-28 07:36:04 +0000126#elif defined(__SIZEOF_PTHREAD_MUTEX_T)
bart3772a982008-03-15 08:11:03 +0000127 // NPTL.
128 const int kind = mutex->__data.__kind;
bartc9463c42008-02-28 07:36:04 +0000129#else
bart3772a982008-03-15 08:11:03 +0000130 // Another POSIX threads implementation. Regression tests will fail.
131 const int kind = PTHREAD_MUTEX_DEFAULT;
bartc9463c42008-02-28 07:36:04 +0000132#endif
bart3772a982008-03-15 08:11:03 +0000133 return pthread_to_drd_mutex_type(kind);
bart5357fcb2008-02-27 15:46:00 +0000134}
135
sewardjaf44c822007-11-25 14:01:38 +0000136static void vg_start_suppression(const void* const p, size_t const size)
137{
bart3772a982008-03-15 08:11:03 +0000138 int res;
139 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
bartf5bb46a2008-03-29 13:18:02 +0000140 p, size, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000141}
142
143static void vg_set_joinable(const pthread_t tid, const int joinable)
144{
bart3772a982008-03-15 08:11:03 +0000145 int res;
146 assert(joinable == 0 || joinable == 1);
147 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_JOINABLE,
148 tid, joinable, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000149}
150
151static void* vg_thread_wrapper(void* arg)
152{
bart3772a982008-03-15 08:11:03 +0000153 int res;
bart0d063002008-03-01 07:25:13 +0000154
bart3772a982008-03-15 08:11:03 +0000155 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
156 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000157
bart3772a982008-03-15 08:11:03 +0000158 {
159 VgPosixThreadArgs* const arg_ptr = (VgPosixThreadArgs*)arg;
160 VgPosixThreadArgs const arg_copy = *arg_ptr;
161 void* result;
sewardjaf44c822007-11-25 14:01:38 +0000162
163#if 0
bart3772a982008-03-15 08:11:03 +0000164 pthread_mutex_lock(arg_ptr->mutex);
165 pthread_cond_signal(arg_ptr->cond);
166 pthread_mutex_unlock(arg_ptr->mutex);
sewardjaf44c822007-11-25 14:01:38 +0000167#else
bart3772a982008-03-15 08:11:03 +0000168 arg_ptr->wrapper_started = 1;
sewardjaf44c822007-11-25 14:01:38 +0000169#endif
170
bart3772a982008-03-15 08:11:03 +0000171 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
172 pthread_self(), 0, 0, 0, 0);
173 vg_set_joinable(pthread_self(),
174 arg_copy.detachstate == PTHREAD_CREATE_JOINABLE);
175 result = (arg_copy.start)(arg_copy.arg);
176 return result;
177 }
sewardjaf44c822007-11-25 14:01:38 +0000178}
179
bart6f07b252008-04-04 16:45:20 +0000180/** Return 1 if LinuxThread has been detected, and 0 otherwise. */
bart4501d5c2008-03-04 18:36:23 +0000181static int detected_linuxthreads(void)
182{
183#if defined(linux)
184#if defined(_CS_GNU_LIBPTHREAD_VERSION)
bart3772a982008-03-15 08:11:03 +0000185 /* Linux with a recent glibc. */
186 char buffer[256];
187 unsigned len;
188 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
189 assert(len <= sizeof(buffer));
190 return len > 0 && buffer[0] == 'l';
bart4501d5c2008-03-04 18:36:23 +0000191#else
bart3772a982008-03-15 08:11:03 +0000192 /* Linux without _CS_GNU_LIBPTHREAD_VERSION: most likely LinuxThreads. */
193 return 1;
bart4501d5c2008-03-04 18:36:23 +0000194#endif
195#else
bart3772a982008-03-15 08:11:03 +0000196 /* Another OS than Linux, hence no LinuxThreads. */
197 return 0;
bart4501d5c2008-03-04 18:36:23 +0000198#endif
199}
200
bart6f07b252008-04-04 16:45:20 +0000201/** Stop and print an error message in case a non-supported threading
202 * library (LinuxThreads) has been detected.
203 */
204static void check_threading_library(void)
sewardjaf44c822007-11-25 14:01:38 +0000205{
bart3772a982008-03-15 08:11:03 +0000206 if (detected_linuxthreads())
207 {
208 if (getenv("LD_ASSUME_KERNEL"))
209 {
210 fprintf(stderr,
211 "Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
212 "the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
213 "after having unset the environment variable LD_ASSUME_KERNEL. Giving up.\n"
214 );
215 }
216 else
217 {
218 fprintf(stderr,
219 "Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
220 "the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
221 "after having upgraded to a newer version of your Linux distribution.\n"
222 "Giving up.\n"
223 );
224 }
225 abort();
226 }
bart6f07b252008-04-04 16:45:20 +0000227}
228
229static void vg_set_main_thread_state(void)
230{
231 int res;
bart0d063002008-03-01 07:25:13 +0000232
bart3772a982008-03-15 08:11:03 +0000233 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
234 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000235
bart3772a982008-03-15 08:11:03 +0000236 // Make sure that DRD knows about the main thread's POSIX thread ID.
237 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
238 pthread_self(), 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000239
240}
241
242// pthread_create
sewardj347eeba2008-01-21 14:19:07 +0000243PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
bart3772a982008-03-15 08:11:03 +0000244 pthread_t *thread, const pthread_attr_t *attr,
245 void *(*start) (void *), void *arg)
sewardjaf44c822007-11-25 14:01:38 +0000246{
bartbf3a60c2008-04-04 19:10:21 +0000247 int res;
bart3772a982008-03-15 08:11:03 +0000248 int ret;
249 OrigFn fn;
250 VgPosixThreadArgs vgargs;
sewardjaf44c822007-11-25 14:01:38 +0000251
bart3772a982008-03-15 08:11:03 +0000252 VALGRIND_GET_ORIG_FN(fn);
sewardjaf44c822007-11-25 14:01:38 +0000253
bart3772a982008-03-15 08:11:03 +0000254 vg_start_suppression(&vgargs.wrapper_started,
255 sizeof(vgargs.wrapper_started));
256 vgargs.start = start;
257 vgargs.arg = arg;
258 vgargs.wrapper_started = 0;
259 vgargs.detachstate = PTHREAD_CREATE_JOINABLE;
260 if (attr)
261 {
262 if (pthread_attr_getdetachstate(attr, &vgargs.detachstate) != 0)
263 {
264 assert(0);
265 }
266 }
267 assert(vgargs.detachstate == PTHREAD_CREATE_JOINABLE
268 || vgargs.detachstate == PTHREAD_CREATE_DETACHED);
sewardjaf44c822007-11-25 14:01:38 +0000269#if 0
bart3772a982008-03-15 08:11:03 +0000270 pthread_mutex_init(&vgargs.mutex, 0);
271 pthread_cond_init(&vgargs.cond, 0);
272 pthread_mutex_lock(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000273#endif
bartbf3a60c2008-04-04 19:10:21 +0000274 /* Suppress NPTL-specific conflicts between creator and created thread. */
275 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_STOP_RECORDING,
276 0, 0, 0, 0, 0);
bart3772a982008-03-15 08:11:03 +0000277 CALL_FN_W_WWWW(ret, fn, thread, attr, vg_thread_wrapper, &vgargs);
bartbf3a60c2008-04-04 19:10:21 +0000278 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_START_RECORDING,
279 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000280#if 0
bart3772a982008-03-15 08:11:03 +0000281 pthread_cond_wait(&vgargs.cond, &vgargs.mutex);
282 pthread_mutex_unlock(&vgargs.mutex);
283 pthread_cond_destroy(&vgargs.cond);
284 pthread_mutex_destroy(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000285#else
bart3772a982008-03-15 08:11:03 +0000286 // Yes, you see it correctly, busy waiting ... The problem is that
287 // POSIX threads functions cannot be called here -- the functions defined
288 // in this file (drd_intercepts.c) would be called instead of those in
289 // libpthread.so. This loop is necessary because vgargs is allocated on the
290 // stack, and the created thread reads it.
291 if (ret == 0)
292 {
293 while (! vgargs.wrapper_started)
294 {
295 sched_yield();
296 }
297 }
sewardjaf44c822007-11-25 14:01:38 +0000298#endif
bart3772a982008-03-15 08:11:03 +0000299 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000300}
301
302// pthread_join
303PTH_FUNC(int, pthreadZujoin, // pthread_join
bart3772a982008-03-15 08:11:03 +0000304 pthread_t pt_joinee, void **thread_return)
sewardjaf44c822007-11-25 14:01:38 +0000305{
bart3772a982008-03-15 08:11:03 +0000306 int ret;
307 int res;
308 OrigFn fn;
sewardjaf44c822007-11-25 14:01:38 +0000309
bart3772a982008-03-15 08:11:03 +0000310 VALGRIND_GET_ORIG_FN(fn);
311 CALL_FN_W_WW(ret, fn, pt_joinee, thread_return);
312 if (ret == 0)
313 {
314 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_JOIN,
315 pt_joinee, 0, 0, 0, 0);
316 }
317 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000318}
319
320// pthread_detach
321PTH_FUNC(int, pthreadZudetach, pthread_t pt_thread)
322{
bart3772a982008-03-15 08:11:03 +0000323 int ret;
324 OrigFn fn;
325 VALGRIND_GET_ORIG_FN(fn);
326 {
327 CALL_FN_W_W(ret, fn, pt_thread);
328 if (ret == 0)
329 {
330 vg_set_joinable(pt_thread, 0);
331 }
332 }
333 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000334}
335
336// pthread_mutex_init
337PTH_FUNC(int, pthreadZumutexZuinit,
bart3772a982008-03-15 08:11:03 +0000338 pthread_mutex_t *mutex,
339 const pthread_mutexattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000340{
bart3772a982008-03-15 08:11:03 +0000341 int ret;
342 int res;
343 OrigFn fn;
344 int mt;
345 VALGRIND_GET_ORIG_FN(fn);
346 mt = PTHREAD_MUTEX_DEFAULT;
347 if (attr)
348 pthread_mutexattr_gettype(attr, &mt);
349 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
350 mutex, pthread_to_drd_mutex_type(mt), 0, 0, 0);
351 CALL_FN_W_WW(ret, fn, mutex, attr);
352 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT,
353 mutex, 0, 0, 0, 0);
354 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000355}
356
357// pthread_mutex_destroy
358PTH_FUNC(int, pthreadZumutexZudestroy,
bart3772a982008-03-15 08:11:03 +0000359 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000360{
bart3772a982008-03-15 08:11:03 +0000361 int ret;
362 int res;
363 OrigFn fn;
364 VALGRIND_GET_ORIG_FN(fn);
365 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
366 mutex, 0, 0, 0, 0);
367 CALL_FN_W_W(ret, fn, mutex);
368 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
369 mutex, mutex_type(mutex), 0, 0, 0);
370 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000371}
372
373// pthread_mutex_lock
374PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
bart3772a982008-03-15 08:11:03 +0000375 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000376{
bart3772a982008-03-15 08:11:03 +0000377 int ret;
378 int res;
379 OrigFn fn;
380 VALGRIND_GET_ORIG_FN(fn);
381 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
382 mutex, mutex_type(mutex), 0, 0, 0);
383 CALL_FN_W_W(ret, fn, mutex);
384 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_MUTEX_LOCK,
385 mutex, ret == 0, 0, 0, 0);
386 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000387}
388
389// pthread_mutex_trylock
390PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
bart3772a982008-03-15 08:11:03 +0000391 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000392{
bart3772a982008-03-15 08:11:03 +0000393 int ret;
394 int res;
395 OrigFn fn;
396 VALGRIND_GET_ORIG_FN(fn);
397 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
bart2e3a3c12008-03-24 08:33:47 +0000398 mutex, mutex_type(mutex), 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000399 CALL_FN_W_W(ret, fn, mutex);
400 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
401 mutex, ret == 0, 0, 0, 0);
402 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000403}
404
sewardj85642922008-01-14 11:54:56 +0000405// pthread_mutex_timedlock
406PTH_FUNC(int, pthreadZumutexZutimedlock, // pthread_mutex_timedlock
bart3772a982008-03-15 08:11:03 +0000407 pthread_mutex_t *mutex,
408 const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000409{
bart3772a982008-03-15 08:11:03 +0000410 int ret;
411 int res;
412 OrigFn fn;
413 VALGRIND_GET_ORIG_FN(fn);
414 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
415 mutex, mutex_type(mutex), 0, 0, 0);
416 CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
417 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
418 mutex, ret == 0, 0, 0, 0);
419 return ret;
sewardj85642922008-01-14 11:54:56 +0000420}
421
sewardjaf44c822007-11-25 14:01:38 +0000422// pthread_mutex_unlock
423PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
bart3772a982008-03-15 08:11:03 +0000424 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000425{
bart3772a982008-03-15 08:11:03 +0000426 int ret;
427 int res;
428 OrigFn fn;
429 VALGRIND_GET_ORIG_FN(fn);
430 VALGRIND_DO_CLIENT_REQUEST(res, -1,
431 VG_USERREQ__PRE_MUTEX_UNLOCK,
432 mutex, mutex_type(mutex), 0, 0, 0);
433 CALL_FN_W_W(ret, fn, mutex);
434 VALGRIND_DO_CLIENT_REQUEST(res, -1,
435 VG_USERREQ__POST_MUTEX_UNLOCK,
436 mutex, 0, 0, 0, 0);
437 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000438}
439
440// pthread_cond_init
sewardj347eeba2008-01-21 14:19:07 +0000441PTH_FUNC(int, pthreadZucondZuinitZa, // pthread_cond_init*
bart3772a982008-03-15 08:11:03 +0000442 pthread_cond_t* cond,
443 const pthread_condattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000444{
bart3772a982008-03-15 08:11:03 +0000445 int ret;
446 int res;
447 OrigFn fn;
448 VALGRIND_GET_ORIG_FN(fn);
449 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_INIT,
450 cond, 0, 0, 0, 0);
451 CALL_FN_W_WW(ret, fn, cond, attr);
452 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000453}
454
455// pthread_cond_destroy
sewardj347eeba2008-01-21 14:19:07 +0000456PTH_FUNC(int, pthreadZucondZudestroyZa, // pthread_cond_destroy*
bart3772a982008-03-15 08:11:03 +0000457 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000458{
bart3772a982008-03-15 08:11:03 +0000459 int ret;
460 int res;
461 OrigFn fn;
462 VALGRIND_GET_ORIG_FN(fn);
463 CALL_FN_W_W(ret, fn, cond);
464 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_DESTROY,
465 cond, 0, 0, 0, 0);
466 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000467}
468
469// pthread_cond_wait
sewardj347eeba2008-01-21 14:19:07 +0000470PTH_FUNC(int, pthreadZucondZuwaitZa, // pthread_cond_wait*
bart3772a982008-03-15 08:11:03 +0000471 pthread_cond_t *cond,
472 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000473{
bart3772a982008-03-15 08:11:03 +0000474 int ret;
475 int res;
476 OrigFn fn;
477 VALGRIND_GET_ORIG_FN(fn);
478 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
479 cond, mutex, mutex_type(mutex), 0, 0);
480 CALL_FN_W_WW(ret, fn, cond, mutex);
481 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000482 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000483 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000484}
485
486// pthread_cond_timedwait
sewardj347eeba2008-01-21 14:19:07 +0000487PTH_FUNC(int, pthreadZucondZutimedwaitZa, // pthread_cond_timedwait*
bart3772a982008-03-15 08:11:03 +0000488 pthread_cond_t *cond,
489 pthread_mutex_t *mutex,
490 const struct timespec* abstime)
sewardjaf44c822007-11-25 14:01:38 +0000491{
bart3772a982008-03-15 08:11:03 +0000492 int ret;
493 int res;
494 OrigFn fn;
495 VALGRIND_GET_ORIG_FN(fn);
496 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
497 cond, mutex, mutex_type(mutex), 0, 0);
498 CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
499 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000500 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000501 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000502}
503
504// pthread_cond_signal
sewardj347eeba2008-01-21 14:19:07 +0000505PTH_FUNC(int, pthreadZucondZusignalZa, // pthread_cond_signal*
bart3772a982008-03-15 08:11:03 +0000506 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000507{
bart3772a982008-03-15 08:11:03 +0000508 int ret;
509 int res;
510 OrigFn fn;
511 VALGRIND_GET_ORIG_FN(fn);
512 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_SIGNAL,
513 cond, 0, 0, 0, 0);
514 CALL_FN_W_W(ret, fn, cond);
515 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000516}
517
518// pthread_cond_broadcast
sewardj347eeba2008-01-21 14:19:07 +0000519PTH_FUNC(int, pthreadZucondZubroadcastZa, // pthread_cond_broadcast*
bart3772a982008-03-15 08:11:03 +0000520 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000521{
bart3772a982008-03-15 08:11:03 +0000522 int ret;
523 int res;
524 OrigFn fn;
525 VALGRIND_GET_ORIG_FN(fn);
526 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_BROADCAST,
527 cond, 0, 0, 0, 0);
528 CALL_FN_W_W(ret, fn, cond);
529 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000530}
531
532
533// pthread_spin_init
534PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
bart3772a982008-03-15 08:11:03 +0000535 pthread_spinlock_t *spinlock,
536 int pshared)
sewardjaf44c822007-11-25 14:01:38 +0000537{
bart3772a982008-03-15 08:11:03 +0000538 int ret;
539 int res;
540 OrigFn fn;
541 VALGRIND_GET_ORIG_FN(fn);
542 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
543 spinlock, mutex_type_spinlock, 0, 0, 0);
544 CALL_FN_W_WW(ret, fn, spinlock, pshared);
545 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000546}
547
548// pthread_spin_destroy
549PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
bart3772a982008-03-15 08:11:03 +0000550 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000551{
bart3772a982008-03-15 08:11:03 +0000552 int ret;
553 int res;
554 OrigFn fn;
555 VALGRIND_GET_ORIG_FN(fn);
556 CALL_FN_W_W(ret, fn, spinlock);
557 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
558 spinlock, mutex_type_spinlock, 0, 0, 0);
559 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000560}
561
562// pthread_spin_lock
563PTH_FUNC(int, pthreadZuspinZulock, // pthread_spin_lock
bart3772a982008-03-15 08:11:03 +0000564 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000565{
bart3772a982008-03-15 08:11:03 +0000566 int ret;
567 int res;
568 OrigFn fn;
569 VALGRIND_GET_ORIG_FN(fn);
570 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
571 spinlock, mutex_type_spinlock, 0, 0, 0);
572 CALL_FN_W_W(ret, fn, spinlock);
573 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
574 spinlock, ret == 0, 0, 0, 0);
575 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000576}
577
578// pthread_spin_trylock
579PTH_FUNC(int, pthreadZuspinZutrylock, // pthread_spin_trylock
bart3772a982008-03-15 08:11:03 +0000580 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000581{
bart3772a982008-03-15 08:11:03 +0000582 int ret;
583 int res;
584 OrigFn fn;
585 VALGRIND_GET_ORIG_FN(fn);
586 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
587 spinlock, mutex_type_spinlock, 0, 0, 0);
588 CALL_FN_W_W(ret, fn, spinlock);
589 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
590 spinlock, ret == 0, 0, 0, 0);
591 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000592}
593
594// pthread_spin_unlock
595PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock
bart3772a982008-03-15 08:11:03 +0000596 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000597{
bart3772a982008-03-15 08:11:03 +0000598 int ret;
599 int res;
600 OrigFn fn;
601 VALGRIND_GET_ORIG_FN(fn);
602 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
603 spinlock, mutex_type_spinlock, 0, 0, 0);
604 CALL_FN_W_W(ret, fn, spinlock);
605 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000606}
607
sewardj85642922008-01-14 11:54:56 +0000608// pthread_barrier_init
609PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
bart3772a982008-03-15 08:11:03 +0000610 pthread_barrier_t* barrier,
611 const pthread_barrierattr_t* attr,
612 unsigned count)
sewardj85642922008-01-14 11:54:56 +0000613{
bart3772a982008-03-15 08:11:03 +0000614 int ret;
615 int res;
616 OrigFn fn;
617 VALGRIND_GET_ORIG_FN(fn);
618 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_INIT,
619 barrier, pthread_barrier, count, 0, 0);
620 CALL_FN_W_WWW(ret, fn, barrier, attr, count);
621 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_INIT,
622 barrier, pthread_barrier, 0, 0, 0);
623 return ret;
sewardj85642922008-01-14 11:54:56 +0000624}
625
626// pthread_barrier_destroy
627PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
bart3772a982008-03-15 08:11:03 +0000628 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000629{
bart3772a982008-03-15 08:11:03 +0000630 int ret;
631 int res;
632 OrigFn fn;
633 VALGRIND_GET_ORIG_FN(fn);
634 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_DESTROY,
635 barrier, pthread_barrier, 0, 0, 0);
636 CALL_FN_W_W(ret, fn, barrier);
637 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_DESTROY,
638 barrier, pthread_barrier, 0, 0, 0);
639 return ret;
sewardj85642922008-01-14 11:54:56 +0000640}
641
642// pthread_barrier_wait
643PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
bart3772a982008-03-15 08:11:03 +0000644 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000645{
bart3772a982008-03-15 08:11:03 +0000646 int ret;
647 int res;
648 OrigFn fn;
649 VALGRIND_GET_ORIG_FN(fn);
650 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT,
651 barrier, pthread_barrier, 0, 0, 0);
652 CALL_FN_W_W(ret, fn, barrier);
653 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
654 barrier, pthread_barrier,
655 ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
656 0, 0);
657 return ret;
sewardj85642922008-01-14 11:54:56 +0000658}
659
660
sewardj85642922008-01-14 11:54:56 +0000661// sem_init
bart368ec982008-03-11 20:39:01 +0000662PTH_FUNC(int, semZuinitZa, // sem_init*
bart3772a982008-03-15 08:11:03 +0000663 sem_t *sem,
664 int pshared,
665 unsigned int value)
sewardj85642922008-01-14 11:54:56 +0000666{
bart3772a982008-03-15 08:11:03 +0000667 int ret;
668 int res;
669 OrigFn fn;
670 VALGRIND_GET_ORIG_FN(fn);
671 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_INIT,
672 sem, pshared, value, 0, 0);
673 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
674 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_INIT,
675 sem, 0, 0, 0, 0);
676 return ret;
sewardj85642922008-01-14 11:54:56 +0000677}
678
679// sem_destroy
bart00344642008-03-01 15:27:41 +0000680PTH_FUNC(int, semZudestroyZa, // sem_destroy*
bart3772a982008-03-15 08:11:03 +0000681 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000682{
bart3772a982008-03-15 08:11:03 +0000683 int ret;
684 int res;
685 OrigFn fn;
686 VALGRIND_GET_ORIG_FN(fn);
687 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_DESTROY,
688 sem, 0, 0, 0, 0);
689 CALL_FN_W_W(ret, fn, sem);
690 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_DESTROY,
691 sem, 0, 0, 0, 0);
692 return ret;
sewardj85642922008-01-14 11:54:56 +0000693}
694
695// sem_wait
bart368ec982008-03-11 20:39:01 +0000696PTH_FUNC(int, semZuwaitZa, // sem_wait*
bart3772a982008-03-15 08:11:03 +0000697 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000698{
bart3772a982008-03-15 08:11:03 +0000699 int ret;
700 int res;
701 OrigFn fn;
702 VALGRIND_GET_ORIG_FN(fn);
703 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
704 sem, 0, 0, 0, 0);
705 CALL_FN_W_W(ret, fn, sem);
706 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
707 sem, ret == 0, 0, 0, 0);
708 return ret;
sewardj85642922008-01-14 11:54:56 +0000709}
710
711// sem_trywait
bart00344642008-03-01 15:27:41 +0000712PTH_FUNC(int, semZutrywaitZa, // sem_trywait*
bart3772a982008-03-15 08:11:03 +0000713 sem_t *sem)
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_WAIT,
720 sem, 0, 0, 0, 0);
721 CALL_FN_W_W(ret, fn, sem);
722 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
723 sem, ret == 0, 0, 0, 0);
724 return ret;
sewardj85642922008-01-14 11:54:56 +0000725}
726
727// sem_timedwait
bart00344642008-03-01 15:27:41 +0000728PTH_FUNC(int, semZutimedwait, // sem_timedwait
bart3772a982008-03-15 08:11:03 +0000729 sem_t *sem, const struct timespec *abs_timeout)
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_WAIT,
736 sem, 0, 0, 0, 0);
737 CALL_FN_W_WW(ret, fn, sem, abs_timeout);
738 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
739 sem, ret == 0, 0, 0, 0);
740 return ret;
sewardj85642922008-01-14 11:54:56 +0000741}
742
743// sem_post
bart368ec982008-03-11 20:39:01 +0000744PTH_FUNC(int, semZupostZa, // sem_post*
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_POST,
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_POST,
755 sem, ret == 0, 0, 0, 0);
756 return ret;
sewardj85642922008-01-14 11:54:56 +0000757}
758
bart00344642008-03-01 15:27:41 +0000759// pthread_rwlock_init
760PTH_FUNC(int,
761 pthreadZurwlockZuinitZa, // pthread_rwlock_init*
762 pthread_rwlock_t* rwlock,
763 const pthread_rwlockattr_t* attr)
764{
bart3772a982008-03-15 08:11:03 +0000765 int ret;
766 int res;
767 OrigFn fn;
768 VALGRIND_GET_ORIG_FN(fn);
769 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_INIT,
770 rwlock, 0, 0, 0, 0);
771 CALL_FN_W_WW(ret, fn, rwlock, attr);
772 return ret;
bart00344642008-03-01 15:27:41 +0000773}
774
775// pthread_rwlock_destroy
776PTH_FUNC(int,
777 pthreadZurwlockZudestroyZa, // pthread_rwlock_destroy*
778 pthread_rwlock_t* rwlock)
779{
bart3772a982008-03-15 08:11:03 +0000780 int ret;
781 int res;
782 OrigFn fn;
783 VALGRIND_GET_ORIG_FN(fn);
784 CALL_FN_W_W(ret, fn, rwlock);
785 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_DESTROY,
786 rwlock, 0, 0, 0, 0);
787 return ret;
bart00344642008-03-01 15:27:41 +0000788}
789
790// pthread_rwlock_rdlock
791PTH_FUNC(int,
792 pthreadZurwlockZurdlockZa, // pthread_rwlock_rdlock*
793 pthread_rwlock_t* rwlock)
794{
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_RWLOCK_RDLOCK,
800 rwlock, 0, 0, 0, 0);
801 CALL_FN_W_W(ret, fn, rwlock);
802 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
803 rwlock, ret == 0, 0, 0, 0);
804 return ret;
bart00344642008-03-01 15:27:41 +0000805}
806
807// pthread_rwlock_wrlock
808PTH_FUNC(int,
809 pthreadZurwlockZuwrlockZa, // pthread_rwlock_wrlock*
810 pthread_rwlock_t* rwlock)
811{
bart3772a982008-03-15 08:11:03 +0000812 int ret;
813 int res;
814 OrigFn fn;
815 VALGRIND_GET_ORIG_FN(fn);
816 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
817 rwlock, 0, 0, 0, 0);
818 CALL_FN_W_W(ret, fn, rwlock);
819 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
820 rwlock, ret == 0, 0, 0, 0);
821 return ret;
bart00344642008-03-01 15:27:41 +0000822}
823
824// pthread_rwlock_timedrdlock
825PTH_FUNC(int,
826 pthreadZurwlockZutimedrdlockZa, // pthread_rwlock_timedrdlock*
827 pthread_rwlock_t* rwlock)
828{
bart3772a982008-03-15 08:11:03 +0000829 int ret;
830 int res;
831 OrigFn fn;
832 VALGRIND_GET_ORIG_FN(fn);
833 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
834 rwlock, 0, 0, 0, 0);
835 CALL_FN_W_W(ret, fn, rwlock);
836 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
837 rwlock, ret == 0, 0, 0, 0);
838 return ret;
bart00344642008-03-01 15:27:41 +0000839}
840
841// pthread_rwlock_timedwrlock
842PTH_FUNC(int,
843 pthreadZurwlockZutimedwrlockZa, // pthread_rwlock_timedwrlock*
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_WRLOCK,
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_WRLOCK,
854 rwlock, ret == 0, 0, 0, 0);
855 return ret;
bart00344642008-03-01 15:27:41 +0000856}
857
858// pthread_rwlock_tryrdlock
859PTH_FUNC(int,
860 pthreadZurwlockZutryrdlockZa, // pthread_rwlock_tryrdlock*
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_RDLOCK,
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_RDLOCK,
871 rwlock, ret == 0, 0, 0, 0);
872 return ret;
bart00344642008-03-01 15:27:41 +0000873}
874
875// pthread_rwlock_trywrlock
876PTH_FUNC(int,
877 pthreadZurwlockZutrywrlockZa, // pthread_rwlock_trywrlock*
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_WRLOCK,
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_WRLOCK,
888 rwlock, ret == 0, 0, 0, 0);
889 return ret;
bart00344642008-03-01 15:27:41 +0000890}
891
892// pthread_rwlock_unlock
893PTH_FUNC(int,
894 pthreadZurwlockZuunlockZa, // pthread_rwlock_unlock*
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_UNLOCK,
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_UNLOCK,
905 rwlock, ret == 0, 0, 0, 0);
906 return ret;
bart00344642008-03-01 15:27:41 +0000907}