blob: b52d5ed3c80acaae11c2a23f17407f780a34bac0 [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
67// Local data structures.
68
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
83// Local variables.
84
85static int vg_main_thread_state_is_set = 0;
86
87
88// Function definitions.
89
bart5357fcb2008-02-27 15:46:00 +000090static MutexT pthread_to_drd_mutex_type(const int kind)
91{
bart3772a982008-03-15 08:11:03 +000092 switch (kind)
93 {
94 /* PTHREAD_MUTEX_RECURSIVE_NP */
95 case PTHREAD_MUTEX_RECURSIVE:
96 return mutex_type_recursive_mutex;
97 /* PTHREAD_MUTEX_ERRORCHECK_NP */
98 case PTHREAD_MUTEX_ERRORCHECK:
99 return mutex_type_errorcheck_mutex;
100 /* PTHREAD_MUTEX_TIMED_NP */
101 /* PTHREAD_MUTEX_NORMAL */
102 case PTHREAD_MUTEX_DEFAULT:
103 case PTHREAD_MUTEX_ADAPTIVE_NP:
104 return mutex_type_default_mutex;
105 }
106 return mutex_type_invalid_mutex;
bart5357fcb2008-02-27 15:46:00 +0000107}
108
109static MutexT mutex_type(pthread_mutex_t* mutex)
110{
bartc9463c42008-02-28 07:36:04 +0000111#if defined(_PTHREAD_DESCR_DEFINED)
bart3772a982008-03-15 08:11:03 +0000112 // Linuxthreads.
113 const int kind = mutex->__m_kind;
bartc9463c42008-02-28 07:36:04 +0000114#elif defined(__SIZEOF_PTHREAD_MUTEX_T)
bart3772a982008-03-15 08:11:03 +0000115 // NPTL.
116 const int kind = mutex->__data.__kind;
bartc9463c42008-02-28 07:36:04 +0000117#else
bart3772a982008-03-15 08:11:03 +0000118 // Another POSIX threads implementation. Regression tests will fail.
119 const int kind = PTHREAD_MUTEX_DEFAULT;
bartc9463c42008-02-28 07:36:04 +0000120#endif
bart3772a982008-03-15 08:11:03 +0000121 return pthread_to_drd_mutex_type(kind);
bart5357fcb2008-02-27 15:46:00 +0000122}
123
sewardjaf44c822007-11-25 14:01:38 +0000124static void vg_start_suppression(const void* const p, size_t const size)
125{
bart3772a982008-03-15 08:11:03 +0000126 int res;
127 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
bartf5bb46a2008-03-29 13:18:02 +0000128 p, size, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000129}
130
131static void vg_set_joinable(const pthread_t tid, const int joinable)
132{
bart3772a982008-03-15 08:11:03 +0000133 int res;
134 assert(joinable == 0 || joinable == 1);
135 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_JOINABLE,
136 tid, joinable, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000137}
138
139static void* vg_thread_wrapper(void* arg)
140{
bart3772a982008-03-15 08:11:03 +0000141 int res;
bart0d063002008-03-01 07:25:13 +0000142
bart3772a982008-03-15 08:11:03 +0000143 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
144 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000145
bart3772a982008-03-15 08:11:03 +0000146 {
147 VgPosixThreadArgs* const arg_ptr = (VgPosixThreadArgs*)arg;
148 VgPosixThreadArgs const arg_copy = *arg_ptr;
149 void* result;
sewardjaf44c822007-11-25 14:01:38 +0000150
151#if 0
bart3772a982008-03-15 08:11:03 +0000152 pthread_mutex_lock(arg_ptr->mutex);
153 pthread_cond_signal(arg_ptr->cond);
154 pthread_mutex_unlock(arg_ptr->mutex);
sewardjaf44c822007-11-25 14:01:38 +0000155#else
bart3772a982008-03-15 08:11:03 +0000156 arg_ptr->wrapper_started = 1;
sewardjaf44c822007-11-25 14:01:38 +0000157#endif
158
bart3772a982008-03-15 08:11:03 +0000159 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
160 pthread_self(), 0, 0, 0, 0);
161 vg_set_joinable(pthread_self(),
162 arg_copy.detachstate == PTHREAD_CREATE_JOINABLE);
163 result = (arg_copy.start)(arg_copy.arg);
164 return result;
165 }
sewardjaf44c822007-11-25 14:01:38 +0000166}
167
bart4501d5c2008-03-04 18:36:23 +0000168static int detected_linuxthreads(void)
169{
170#if defined(linux)
171#if defined(_CS_GNU_LIBPTHREAD_VERSION)
bart3772a982008-03-15 08:11:03 +0000172 /* Linux with a recent glibc. */
173 char buffer[256];
174 unsigned len;
175 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
176 assert(len <= sizeof(buffer));
177 return len > 0 && buffer[0] == 'l';
bart4501d5c2008-03-04 18:36:23 +0000178#else
bart3772a982008-03-15 08:11:03 +0000179 /* Linux without _CS_GNU_LIBPTHREAD_VERSION: most likely LinuxThreads. */
180 return 1;
bart4501d5c2008-03-04 18:36:23 +0000181#endif
182#else
bart3772a982008-03-15 08:11:03 +0000183 /* Another OS than Linux, hence no LinuxThreads. */
184 return 0;
bart4501d5c2008-03-04 18:36:23 +0000185#endif
186}
187
sewardjaf44c822007-11-25 14:01:38 +0000188static void vg_set_main_thread_state(void)
189{
bart3772a982008-03-15 08:11:03 +0000190 int res;
sewardjaf44c822007-11-25 14:01:38 +0000191
bart3772a982008-03-15 08:11:03 +0000192 if (detected_linuxthreads())
193 {
194 if (getenv("LD_ASSUME_KERNEL"))
195 {
196 fprintf(stderr,
197 "Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
198 "the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
199 "after having unset the environment variable LD_ASSUME_KERNEL. Giving up.\n"
200 );
201 }
202 else
203 {
204 fprintf(stderr,
205 "Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
206 "the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
207 "after having upgraded to a newer version of your Linux distribution.\n"
208 "Giving up.\n"
209 );
210 }
211 abort();
212 }
bart0d063002008-03-01 07:25:13 +0000213
bart3772a982008-03-15 08:11:03 +0000214 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
215 0, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000216
bart3772a982008-03-15 08:11:03 +0000217 // Make sure that DRD knows about the main thread's POSIX thread ID.
218 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
219 pthread_self(), 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000220
221}
222
223// pthread_create
sewardj347eeba2008-01-21 14:19:07 +0000224PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
bart3772a982008-03-15 08:11:03 +0000225 pthread_t *thread, const pthread_attr_t *attr,
226 void *(*start) (void *), void *arg)
sewardjaf44c822007-11-25 14:01:38 +0000227{
bart3772a982008-03-15 08:11:03 +0000228 int ret;
229 OrigFn fn;
230 VgPosixThreadArgs vgargs;
sewardjaf44c822007-11-25 14:01:38 +0000231
bart3772a982008-03-15 08:11:03 +0000232 VALGRIND_GET_ORIG_FN(fn);
sewardjaf44c822007-11-25 14:01:38 +0000233
bart3772a982008-03-15 08:11:03 +0000234 if (vg_main_thread_state_is_set == 0)
235 {
236 vg_set_main_thread_state();
237 vg_main_thread_state_is_set = 1;
238 }
239 vg_start_suppression(&vgargs.wrapper_started,
240 sizeof(vgargs.wrapper_started));
241 vgargs.start = start;
242 vgargs.arg = arg;
243 vgargs.wrapper_started = 0;
244 vgargs.detachstate = PTHREAD_CREATE_JOINABLE;
245 if (attr)
246 {
247 if (pthread_attr_getdetachstate(attr, &vgargs.detachstate) != 0)
248 {
249 assert(0);
250 }
251 }
252 assert(vgargs.detachstate == PTHREAD_CREATE_JOINABLE
253 || vgargs.detachstate == PTHREAD_CREATE_DETACHED);
sewardjaf44c822007-11-25 14:01:38 +0000254#if 0
bart3772a982008-03-15 08:11:03 +0000255 pthread_mutex_init(&vgargs.mutex, 0);
256 pthread_cond_init(&vgargs.cond, 0);
257 pthread_mutex_lock(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000258#endif
bart3772a982008-03-15 08:11:03 +0000259 CALL_FN_W_WWWW(ret, fn, thread, attr, vg_thread_wrapper, &vgargs);
sewardjaf44c822007-11-25 14:01:38 +0000260#if 0
bart3772a982008-03-15 08:11:03 +0000261 pthread_cond_wait(&vgargs.cond, &vgargs.mutex);
262 pthread_mutex_unlock(&vgargs.mutex);
263 pthread_cond_destroy(&vgargs.cond);
264 pthread_mutex_destroy(&vgargs.mutex);
sewardjaf44c822007-11-25 14:01:38 +0000265#else
bart3772a982008-03-15 08:11:03 +0000266 // Yes, you see it correctly, busy waiting ... The problem is that
267 // POSIX threads functions cannot be called here -- the functions defined
268 // in this file (drd_intercepts.c) would be called instead of those in
269 // libpthread.so. This loop is necessary because vgargs is allocated on the
270 // stack, and the created thread reads it.
271 if (ret == 0)
272 {
273 while (! vgargs.wrapper_started)
274 {
275 sched_yield();
276 }
277 }
sewardjaf44c822007-11-25 14:01:38 +0000278#endif
bart3772a982008-03-15 08:11:03 +0000279 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000280}
281
282// pthread_join
283PTH_FUNC(int, pthreadZujoin, // pthread_join
bart3772a982008-03-15 08:11:03 +0000284 pthread_t pt_joinee, void **thread_return)
sewardjaf44c822007-11-25 14:01:38 +0000285{
bart3772a982008-03-15 08:11:03 +0000286 int ret;
287 int res;
288 OrigFn fn;
sewardjaf44c822007-11-25 14:01:38 +0000289
bart3772a982008-03-15 08:11:03 +0000290 VALGRIND_GET_ORIG_FN(fn);
291 CALL_FN_W_WW(ret, fn, pt_joinee, thread_return);
292 if (ret == 0)
293 {
294 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_JOIN,
295 pt_joinee, 0, 0, 0, 0);
296 }
297 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000298}
299
300// pthread_detach
301PTH_FUNC(int, pthreadZudetach, pthread_t pt_thread)
302{
bart3772a982008-03-15 08:11:03 +0000303 int ret;
304 OrigFn fn;
305 VALGRIND_GET_ORIG_FN(fn);
306 {
307 CALL_FN_W_W(ret, fn, pt_thread);
308 if (ret == 0)
309 {
310 vg_set_joinable(pt_thread, 0);
311 }
312 }
313 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000314}
315
316// pthread_mutex_init
317PTH_FUNC(int, pthreadZumutexZuinit,
bart3772a982008-03-15 08:11:03 +0000318 pthread_mutex_t *mutex,
319 const pthread_mutexattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000320{
bart3772a982008-03-15 08:11:03 +0000321 int ret;
322 int res;
323 OrigFn fn;
324 int mt;
325 VALGRIND_GET_ORIG_FN(fn);
326 mt = PTHREAD_MUTEX_DEFAULT;
327 if (attr)
328 pthread_mutexattr_gettype(attr, &mt);
329 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
330 mutex, pthread_to_drd_mutex_type(mt), 0, 0, 0);
331 CALL_FN_W_WW(ret, fn, mutex, attr);
332 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT,
333 mutex, 0, 0, 0, 0);
334 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000335}
336
337// pthread_mutex_destroy
338PTH_FUNC(int, pthreadZumutexZudestroy,
bart3772a982008-03-15 08:11:03 +0000339 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000340{
bart3772a982008-03-15 08:11:03 +0000341 int ret;
342 int res;
343 OrigFn fn;
344 VALGRIND_GET_ORIG_FN(fn);
345 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
346 mutex, 0, 0, 0, 0);
347 CALL_FN_W_W(ret, fn, mutex);
348 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
349 mutex, mutex_type(mutex), 0, 0, 0);
350 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000351}
352
353// pthread_mutex_lock
354PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
bart3772a982008-03-15 08:11:03 +0000355 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000356{
bart3772a982008-03-15 08:11:03 +0000357 int ret;
358 int res;
359 OrigFn fn;
360 VALGRIND_GET_ORIG_FN(fn);
361 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
362 mutex, mutex_type(mutex), 0, 0, 0);
363 CALL_FN_W_W(ret, fn, mutex);
364 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_MUTEX_LOCK,
365 mutex, ret == 0, 0, 0, 0);
366 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000367}
368
369// pthread_mutex_trylock
370PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
bart3772a982008-03-15 08:11:03 +0000371 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000372{
bart3772a982008-03-15 08:11:03 +0000373 int ret;
374 int res;
375 OrigFn fn;
376 VALGRIND_GET_ORIG_FN(fn);
377 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
bart2e3a3c12008-03-24 08:33:47 +0000378 mutex, mutex_type(mutex), 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000379 CALL_FN_W_W(ret, fn, mutex);
380 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
381 mutex, ret == 0, 0, 0, 0);
382 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000383}
384
sewardj85642922008-01-14 11:54:56 +0000385// pthread_mutex_timedlock
386PTH_FUNC(int, pthreadZumutexZutimedlock, // pthread_mutex_timedlock
bart3772a982008-03-15 08:11:03 +0000387 pthread_mutex_t *mutex,
388 const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000389{
bart3772a982008-03-15 08:11:03 +0000390 int ret;
391 int res;
392 OrigFn fn;
393 VALGRIND_GET_ORIG_FN(fn);
394 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
395 mutex, mutex_type(mutex), 0, 0, 0);
396 CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
397 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
398 mutex, ret == 0, 0, 0, 0);
399 return ret;
sewardj85642922008-01-14 11:54:56 +0000400}
401
sewardjaf44c822007-11-25 14:01:38 +0000402// pthread_mutex_unlock
403PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
bart3772a982008-03-15 08:11:03 +0000404 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000405{
bart3772a982008-03-15 08:11:03 +0000406 int ret;
407 int res;
408 OrigFn fn;
409 VALGRIND_GET_ORIG_FN(fn);
410 VALGRIND_DO_CLIENT_REQUEST(res, -1,
411 VG_USERREQ__PRE_MUTEX_UNLOCK,
412 mutex, mutex_type(mutex), 0, 0, 0);
413 CALL_FN_W_W(ret, fn, mutex);
414 VALGRIND_DO_CLIENT_REQUEST(res, -1,
415 VG_USERREQ__POST_MUTEX_UNLOCK,
416 mutex, 0, 0, 0, 0);
417 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000418}
419
420// pthread_cond_init
sewardj347eeba2008-01-21 14:19:07 +0000421PTH_FUNC(int, pthreadZucondZuinitZa, // pthread_cond_init*
bart3772a982008-03-15 08:11:03 +0000422 pthread_cond_t* cond,
423 const pthread_condattr_t* attr)
sewardjaf44c822007-11-25 14:01:38 +0000424{
bart3772a982008-03-15 08:11:03 +0000425 int ret;
426 int res;
427 OrigFn fn;
428 VALGRIND_GET_ORIG_FN(fn);
429 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_INIT,
430 cond, 0, 0, 0, 0);
431 CALL_FN_W_WW(ret, fn, cond, attr);
432 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000433}
434
435// pthread_cond_destroy
sewardj347eeba2008-01-21 14:19:07 +0000436PTH_FUNC(int, pthreadZucondZudestroyZa, // pthread_cond_destroy*
bart3772a982008-03-15 08:11:03 +0000437 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000438{
bart3772a982008-03-15 08:11:03 +0000439 int ret;
440 int res;
441 OrigFn fn;
442 VALGRIND_GET_ORIG_FN(fn);
443 CALL_FN_W_W(ret, fn, cond);
444 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_DESTROY,
445 cond, 0, 0, 0, 0);
446 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000447}
448
449// pthread_cond_wait
sewardj347eeba2008-01-21 14:19:07 +0000450PTH_FUNC(int, pthreadZucondZuwaitZa, // pthread_cond_wait*
bart3772a982008-03-15 08:11:03 +0000451 pthread_cond_t *cond,
452 pthread_mutex_t *mutex)
sewardjaf44c822007-11-25 14:01:38 +0000453{
bart3772a982008-03-15 08:11:03 +0000454 int ret;
455 int res;
456 OrigFn fn;
457 VALGRIND_GET_ORIG_FN(fn);
458 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
459 cond, mutex, mutex_type(mutex), 0, 0);
460 CALL_FN_W_WW(ret, fn, cond, mutex);
461 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000462 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000463 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000464}
465
466// pthread_cond_timedwait
sewardj347eeba2008-01-21 14:19:07 +0000467PTH_FUNC(int, pthreadZucondZutimedwaitZa, // pthread_cond_timedwait*
bart3772a982008-03-15 08:11:03 +0000468 pthread_cond_t *cond,
469 pthread_mutex_t *mutex,
470 const struct timespec* abstime)
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);
476 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT,
477 cond, mutex, mutex_type(mutex), 0, 0);
478 CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
479 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
bart1b7a8302008-03-30 08:39:51 +0000480 cond, mutex, 1, 0, 0);
bart3772a982008-03-15 08:11:03 +0000481 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000482}
483
484// pthread_cond_signal
sewardj347eeba2008-01-21 14:19:07 +0000485PTH_FUNC(int, pthreadZucondZusignalZa, // pthread_cond_signal*
bart3772a982008-03-15 08:11:03 +0000486 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000487{
bart3772a982008-03-15 08:11:03 +0000488 int ret;
489 int res;
490 OrigFn fn;
491 VALGRIND_GET_ORIG_FN(fn);
492 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_SIGNAL,
493 cond, 0, 0, 0, 0);
494 CALL_FN_W_W(ret, fn, cond);
495 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000496}
497
498// pthread_cond_broadcast
sewardj347eeba2008-01-21 14:19:07 +0000499PTH_FUNC(int, pthreadZucondZubroadcastZa, // pthread_cond_broadcast*
bart3772a982008-03-15 08:11:03 +0000500 pthread_cond_t* cond)
sewardjaf44c822007-11-25 14:01:38 +0000501{
bart3772a982008-03-15 08:11:03 +0000502 int ret;
503 int res;
504 OrigFn fn;
505 VALGRIND_GET_ORIG_FN(fn);
506 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_BROADCAST,
507 cond, 0, 0, 0, 0);
508 CALL_FN_W_W(ret, fn, cond);
509 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000510}
511
512
513// pthread_spin_init
514PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
bart3772a982008-03-15 08:11:03 +0000515 pthread_spinlock_t *spinlock,
516 int pshared)
sewardjaf44c822007-11-25 14:01:38 +0000517{
bart3772a982008-03-15 08:11:03 +0000518 int ret;
519 int res;
520 OrigFn fn;
521 VALGRIND_GET_ORIG_FN(fn);
522 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
523 spinlock, mutex_type_spinlock, 0, 0, 0);
524 CALL_FN_W_WW(ret, fn, spinlock, pshared);
525 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000526}
527
528// pthread_spin_destroy
529PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
bart3772a982008-03-15 08:11:03 +0000530 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000531{
bart3772a982008-03-15 08:11:03 +0000532 int ret;
533 int res;
534 OrigFn fn;
535 VALGRIND_GET_ORIG_FN(fn);
536 CALL_FN_W_W(ret, fn, spinlock);
537 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
538 spinlock, mutex_type_spinlock, 0, 0, 0);
539 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000540}
541
542// pthread_spin_lock
543PTH_FUNC(int, pthreadZuspinZulock, // pthread_spin_lock
bart3772a982008-03-15 08:11:03 +0000544 pthread_spinlock_t *spinlock)
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, 0, VG_USERREQ__PRE_MUTEX_LOCK,
551 spinlock, mutex_type_spinlock, 0, 0, 0);
552 CALL_FN_W_W(ret, fn, spinlock);
553 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
554 spinlock, ret == 0, 0, 0, 0);
555 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000556}
557
558// pthread_spin_trylock
559PTH_FUNC(int, pthreadZuspinZutrylock, // pthread_spin_trylock
bart3772a982008-03-15 08:11:03 +0000560 pthread_spinlock_t *spinlock)
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, 0, VG_USERREQ__PRE_MUTEX_LOCK,
567 spinlock, mutex_type_spinlock, 0, 0, 0);
568 CALL_FN_W_W(ret, fn, spinlock);
569 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
570 spinlock, ret == 0, 0, 0, 0);
571 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000572}
573
574// pthread_spin_unlock
575PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock
bart3772a982008-03-15 08:11:03 +0000576 pthread_spinlock_t *spinlock)
sewardjaf44c822007-11-25 14:01:38 +0000577{
bart3772a982008-03-15 08:11:03 +0000578 int ret;
579 int res;
580 OrigFn fn;
581 VALGRIND_GET_ORIG_FN(fn);
582 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
583 spinlock, mutex_type_spinlock, 0, 0, 0);
584 CALL_FN_W_W(ret, fn, spinlock);
585 return ret;
sewardjaf44c822007-11-25 14:01:38 +0000586}
587
sewardj85642922008-01-14 11:54:56 +0000588// pthread_barrier_init
589PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
bart3772a982008-03-15 08:11:03 +0000590 pthread_barrier_t* barrier,
591 const pthread_barrierattr_t* attr,
592 unsigned count)
sewardj85642922008-01-14 11:54:56 +0000593{
bart3772a982008-03-15 08:11:03 +0000594 int ret;
595 int res;
596 OrigFn fn;
597 VALGRIND_GET_ORIG_FN(fn);
598 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_INIT,
599 barrier, pthread_barrier, count, 0, 0);
600 CALL_FN_W_WWW(ret, fn, barrier, attr, count);
601 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_INIT,
602 barrier, pthread_barrier, 0, 0, 0);
603 return ret;
sewardj85642922008-01-14 11:54:56 +0000604}
605
606// pthread_barrier_destroy
607PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
bart3772a982008-03-15 08:11:03 +0000608 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000609{
bart3772a982008-03-15 08:11:03 +0000610 int ret;
611 int res;
612 OrigFn fn;
613 VALGRIND_GET_ORIG_FN(fn);
614 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_DESTROY,
615 barrier, pthread_barrier, 0, 0, 0);
616 CALL_FN_W_W(ret, fn, barrier);
617 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_DESTROY,
618 barrier, pthread_barrier, 0, 0, 0);
619 return ret;
sewardj85642922008-01-14 11:54:56 +0000620}
621
622// pthread_barrier_wait
623PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
bart3772a982008-03-15 08:11:03 +0000624 pthread_barrier_t* barrier)
sewardj85642922008-01-14 11:54:56 +0000625{
bart3772a982008-03-15 08:11:03 +0000626 int ret;
627 int res;
628 OrigFn fn;
629 VALGRIND_GET_ORIG_FN(fn);
630 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT,
631 barrier, pthread_barrier, 0, 0, 0);
632 CALL_FN_W_W(ret, fn, barrier);
633 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
634 barrier, pthread_barrier,
635 ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
636 0, 0);
637 return ret;
sewardj85642922008-01-14 11:54:56 +0000638}
639
640
sewardj85642922008-01-14 11:54:56 +0000641// sem_init
bart368ec982008-03-11 20:39:01 +0000642PTH_FUNC(int, semZuinitZa, // sem_init*
bart3772a982008-03-15 08:11:03 +0000643 sem_t *sem,
644 int pshared,
645 unsigned int value)
sewardj85642922008-01-14 11:54:56 +0000646{
bart3772a982008-03-15 08:11:03 +0000647 int ret;
648 int res;
649 OrigFn fn;
650 VALGRIND_GET_ORIG_FN(fn);
651 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_INIT,
652 sem, pshared, value, 0, 0);
653 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
654 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_INIT,
655 sem, 0, 0, 0, 0);
656 return ret;
sewardj85642922008-01-14 11:54:56 +0000657}
658
659// sem_destroy
bart00344642008-03-01 15:27:41 +0000660PTH_FUNC(int, semZudestroyZa, // sem_destroy*
bart3772a982008-03-15 08:11:03 +0000661 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000662{
bart3772a982008-03-15 08:11:03 +0000663 int ret;
664 int res;
665 OrigFn fn;
666 VALGRIND_GET_ORIG_FN(fn);
667 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_DESTROY,
668 sem, 0, 0, 0, 0);
669 CALL_FN_W_W(ret, fn, sem);
670 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_DESTROY,
671 sem, 0, 0, 0, 0);
672 return ret;
sewardj85642922008-01-14 11:54:56 +0000673}
674
675// sem_wait
bart368ec982008-03-11 20:39:01 +0000676PTH_FUNC(int, semZuwaitZa, // sem_wait*
bart3772a982008-03-15 08:11:03 +0000677 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000678{
bart3772a982008-03-15 08:11:03 +0000679 int ret;
680 int res;
681 OrigFn fn;
682 VALGRIND_GET_ORIG_FN(fn);
683 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
684 sem, 0, 0, 0, 0);
685 CALL_FN_W_W(ret, fn, sem);
686 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
687 sem, ret == 0, 0, 0, 0);
688 return ret;
sewardj85642922008-01-14 11:54:56 +0000689}
690
691// sem_trywait
bart00344642008-03-01 15:27:41 +0000692PTH_FUNC(int, semZutrywaitZa, // sem_trywait*
bart3772a982008-03-15 08:11:03 +0000693 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000694{
bart3772a982008-03-15 08:11:03 +0000695 int ret;
696 int res;
697 OrigFn fn;
698 VALGRIND_GET_ORIG_FN(fn);
699 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
700 sem, 0, 0, 0, 0);
701 CALL_FN_W_W(ret, fn, sem);
702 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
703 sem, ret == 0, 0, 0, 0);
704 return ret;
sewardj85642922008-01-14 11:54:56 +0000705}
706
707// sem_timedwait
bart00344642008-03-01 15:27:41 +0000708PTH_FUNC(int, semZutimedwait, // sem_timedwait
bart3772a982008-03-15 08:11:03 +0000709 sem_t *sem, const struct timespec *abs_timeout)
sewardj85642922008-01-14 11:54:56 +0000710{
bart3772a982008-03-15 08:11:03 +0000711 int ret;
712 int res;
713 OrigFn fn;
714 VALGRIND_GET_ORIG_FN(fn);
715 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
716 sem, 0, 0, 0, 0);
717 CALL_FN_W_WW(ret, fn, sem, abs_timeout);
718 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
719 sem, ret == 0, 0, 0, 0);
720 return ret;
sewardj85642922008-01-14 11:54:56 +0000721}
722
723// sem_post
bart368ec982008-03-11 20:39:01 +0000724PTH_FUNC(int, semZupostZa, // sem_post*
bart3772a982008-03-15 08:11:03 +0000725 sem_t *sem)
sewardj85642922008-01-14 11:54:56 +0000726{
bart3772a982008-03-15 08:11:03 +0000727 int ret;
728 int res;
729 OrigFn fn;
730 VALGRIND_GET_ORIG_FN(fn);
731 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
732 sem, 0, 0, 0, 0);
733 CALL_FN_W_W(ret, fn, sem);
734 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
735 sem, ret == 0, 0, 0, 0);
736 return ret;
sewardj85642922008-01-14 11:54:56 +0000737}
738
bart00344642008-03-01 15:27:41 +0000739// pthread_rwlock_init
740PTH_FUNC(int,
741 pthreadZurwlockZuinitZa, // pthread_rwlock_init*
742 pthread_rwlock_t* rwlock,
743 const pthread_rwlockattr_t* attr)
744{
bart3772a982008-03-15 08:11:03 +0000745 int ret;
746 int res;
747 OrigFn fn;
748 VALGRIND_GET_ORIG_FN(fn);
749 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_INIT,
750 rwlock, 0, 0, 0, 0);
751 CALL_FN_W_WW(ret, fn, rwlock, attr);
752 return ret;
bart00344642008-03-01 15:27:41 +0000753}
754
755// pthread_rwlock_destroy
756PTH_FUNC(int,
757 pthreadZurwlockZudestroyZa, // pthread_rwlock_destroy*
758 pthread_rwlock_t* rwlock)
759{
bart3772a982008-03-15 08:11:03 +0000760 int ret;
761 int res;
762 OrigFn fn;
763 VALGRIND_GET_ORIG_FN(fn);
764 CALL_FN_W_W(ret, fn, rwlock);
765 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_DESTROY,
766 rwlock, 0, 0, 0, 0);
767 return ret;
bart00344642008-03-01 15:27:41 +0000768}
769
770// pthread_rwlock_rdlock
771PTH_FUNC(int,
772 pthreadZurwlockZurdlockZa, // pthread_rwlock_rdlock*
773 pthread_rwlock_t* rwlock)
774{
bart3772a982008-03-15 08:11:03 +0000775 int ret;
776 int res;
777 OrigFn fn;
778 VALGRIND_GET_ORIG_FN(fn);
779 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
780 rwlock, 0, 0, 0, 0);
781 CALL_FN_W_W(ret, fn, rwlock);
782 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
783 rwlock, ret == 0, 0, 0, 0);
784 return ret;
bart00344642008-03-01 15:27:41 +0000785}
786
787// pthread_rwlock_wrlock
788PTH_FUNC(int,
789 pthreadZurwlockZuwrlockZa, // pthread_rwlock_wrlock*
790 pthread_rwlock_t* rwlock)
791{
bart3772a982008-03-15 08:11:03 +0000792 int ret;
793 int res;
794 OrigFn fn;
795 VALGRIND_GET_ORIG_FN(fn);
796 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
797 rwlock, 0, 0, 0, 0);
798 CALL_FN_W_W(ret, fn, rwlock);
799 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
800 rwlock, ret == 0, 0, 0, 0);
801 return ret;
bart00344642008-03-01 15:27:41 +0000802}
803
804// pthread_rwlock_timedrdlock
805PTH_FUNC(int,
806 pthreadZurwlockZutimedrdlockZa, // pthread_rwlock_timedrdlock*
807 pthread_rwlock_t* rwlock)
808{
bart3772a982008-03-15 08:11:03 +0000809 int ret;
810 int res;
811 OrigFn fn;
812 VALGRIND_GET_ORIG_FN(fn);
813 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
814 rwlock, 0, 0, 0, 0);
815 CALL_FN_W_W(ret, fn, rwlock);
816 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
817 rwlock, ret == 0, 0, 0, 0);
818 return ret;
bart00344642008-03-01 15:27:41 +0000819}
820
821// pthread_rwlock_timedwrlock
822PTH_FUNC(int,
823 pthreadZurwlockZutimedwrlockZa, // pthread_rwlock_timedwrlock*
824 pthread_rwlock_t* rwlock)
825{
bart3772a982008-03-15 08:11:03 +0000826 int ret;
827 int res;
828 OrigFn fn;
829 VALGRIND_GET_ORIG_FN(fn);
830 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
831 rwlock, 0, 0, 0, 0);
832 CALL_FN_W_W(ret, fn, rwlock);
833 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
834 rwlock, ret == 0, 0, 0, 0);
835 return ret;
bart00344642008-03-01 15:27:41 +0000836}
837
838// pthread_rwlock_tryrdlock
839PTH_FUNC(int,
840 pthreadZurwlockZutryrdlockZa, // pthread_rwlock_tryrdlock*
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_trywrlock
856PTH_FUNC(int,
857 pthreadZurwlockZutrywrlockZa, // pthread_rwlock_trywrlock*
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_unlock
873PTH_FUNC(int,
874 pthreadZurwlockZuunlockZa, // pthread_rwlock_unlock*
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_UNLOCK,
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_UNLOCK,
885 rwlock, ret == 0, 0, 0, 0);
886 return ret;
bart00344642008-03-01 15:27:41 +0000887}