blob: ef654558e5d6387e5b91dd39c04c3e3dcd8c5ffd [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
62#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)
65
66
67// Local data structures.
68
69typedef struct
70{
71 void* (*start)(void*);
72 void* arg;
73 int detachstate;
74#if 0
75 pthread_mutex_t mutex;
76 pthread_cond_t cond;
77#else
78 int wrapper_started;
79#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{
92 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;
bart5357fcb2008-02-27 15:46:00 +0000105 }
bart635cb162008-02-28 08:30:43 +0000106 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)
112 // Linuxthreads.
113 const int kind = mutex->__m_kind;
114#elif defined(__SIZEOF_PTHREAD_MUTEX_T)
115 // NPTL.
116 const int kind = mutex->__data.__kind;
117#else
118 // Another POSIX threads implementation. Regression tests will fail.
119 const int kind = PTHREAD_MUTEX_DEFAULT;
120#endif
121 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{
126 int res;
127 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
bart5e85d262008-03-01 10:49:37 +0000128 p, (char*)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{
133 int res;
134 assert(joinable == 0 || joinable == 1);
sewardjaf44c822007-11-25 14:01:38 +0000135 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_JOINABLE,
136 tid, joinable, 0, 0, 0);
137}
138
139static void* vg_thread_wrapper(void* arg)
140{
141 int res;
bart0d063002008-03-01 07:25:13 +0000142
sewardjaf44c822007-11-25 14:01:38 +0000143 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
144 0, 0, 0, 0, 0);
145
146 {
147 VgPosixThreadArgs* const arg_ptr = (VgPosixThreadArgs*)arg;
148 VgPosixThreadArgs const arg_copy = *arg_ptr;
149 void* result;
150
151#if 0
152 pthread_mutex_lock(arg_ptr->mutex);
153 pthread_cond_signal(arg_ptr->cond);
154 pthread_mutex_unlock(arg_ptr->mutex);
155#else
156 arg_ptr->wrapper_started = 1;
157#endif
158
159 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 }
166}
167
bart4501d5c2008-03-04 18:36:23 +0000168static int detected_linuxthreads(void)
169{
170#if defined(linux)
171#if defined(_CS_GNU_LIBPTHREAD_VERSION)
172 /* Linux with a recent glibc. */
173 char buffer[256];
174 int len;
175 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
176 assert(len <= sizeof(buffer));
177 return len > 0 && buffer[0] == 'l';
178#else
179 /* Linux without _CS_GNU_LIBPTHREAD_VERSION: most likely LinuxThreads. */
180 return 1;
181#endif
182#else
183 /* Another OS than Linux, hence no LinuxThreads. */
184 return 0;
185#endif
186}
187
sewardjaf44c822007-11-25 14:01:38 +0000188static void vg_set_main_thread_state(void)
189{
190 int res;
191
bart4501d5c2008-03-04 18:36:23 +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
sewardjaf44c822007-11-25 14:01:38 +0000214 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
215 0, 0, 0, 0, 0);
216
sewardjaf44c822007-11-25 14:01:38 +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);
220
221}
222
223// pthread_create
sewardj347eeba2008-01-21 14:19:07 +0000224PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
sewardjaf44c822007-11-25 14:01:38 +0000225 pthread_t *thread, const pthread_attr_t *attr,
226 void *(*start) (void *), void *arg)
227{
228 int ret;
229 OrigFn fn;
230 VgPosixThreadArgs vgargs;
231
232 VALGRIND_GET_ORIG_FN(fn);
233
234 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 }
sewardjaf44c822007-11-25 14:01:38 +0000251 }
252 assert(vgargs.detachstate == PTHREAD_CREATE_JOINABLE
253 || vgargs.detachstate == PTHREAD_CREATE_DETACHED);
254#if 0
255 pthread_mutex_init(&vgargs.mutex, 0);
256 pthread_cond_init(&vgargs.cond, 0);
257 pthread_mutex_lock(&vgargs.mutex);
258#endif
sewardjaf44c822007-11-25 14:01:38 +0000259 CALL_FN_W_WWWW(ret, fn, thread, attr, vg_thread_wrapper, &vgargs);
sewardjaf44c822007-11-25 14:01:38 +0000260#if 0
261 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);
265#else
266 // Yes, you see it correctly, busy waiting ... The problem is that
267 // POSIX threads functions cannot be called here -- the functions defined
sewardj85642922008-01-14 11:54:56 +0000268 // in this file (drd_intercepts.c) would be called instead of those in
sewardjaf44c822007-11-25 14:01:38 +0000269 // libpthread.so. This loop is necessary because vgargs is allocated on the
270 // stack, and the created thread reads it.
sewardje0744f02007-12-01 02:09:50 +0000271 if (ret == 0)
sewardjaf44c822007-11-25 14:01:38 +0000272 {
sewardje0744f02007-12-01 02:09:50 +0000273 while (! vgargs.wrapper_started)
274 {
275 sched_yield();
276 }
sewardjaf44c822007-11-25 14:01:38 +0000277 }
278#endif
279 return ret;
280}
281
282// pthread_join
283PTH_FUNC(int, pthreadZujoin, // pthread_join
284 pthread_t pt_joinee, void **thread_return)
285{
286 int ret;
287 int res;
288 OrigFn fn;
289
290 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;
298}
299
300// pthread_detach
301PTH_FUNC(int, pthreadZudetach, pthread_t pt_thread)
302{
303 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;
314}
315
316// pthread_mutex_init
317PTH_FUNC(int, pthreadZumutexZuinit,
318 pthread_mutex_t *mutex,
319 const pthread_mutexattr_t* attr)
320{
321 int ret;
322 int res;
323 OrigFn fn;
bart5357fcb2008-02-27 15:46:00 +0000324 int mt = PTHREAD_MUTEX_DEFAULT;
sewardjaf44c822007-11-25 14:01:38 +0000325 VALGRIND_GET_ORIG_FN(fn);
bart5357fcb2008-02-27 15:46:00 +0000326 if (attr)
327 pthread_mutexattr_gettype(attr, &mt);
sewardjaf44c822007-11-25 14:01:38 +0000328 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
bart5357fcb2008-02-27 15:46:00 +0000329 mutex, sizeof(*mutex),
330 pthread_to_drd_mutex_type(mt), 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000331 CALL_FN_W_WW(ret, fn, mutex, attr);
332 return ret;
333}
334
335// pthread_mutex_destroy
336PTH_FUNC(int, pthreadZumutexZudestroy,
337 pthread_mutex_t *mutex)
338{
339 int ret;
340 int res;
341 OrigFn fn;
342 VALGRIND_GET_ORIG_FN(fn);
343 CALL_FN_W_W(ret, fn, mutex);
344 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
bart5357fcb2008-02-27 15:46:00 +0000345 mutex, mutex_type(mutex), 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000346 return ret;
347}
348
349// pthread_mutex_lock
350PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
351 pthread_mutex_t *mutex)
352{
353 int ret;
354 int res;
355 OrigFn fn;
356 VALGRIND_GET_ORIG_FN(fn);
357 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
bart5357fcb2008-02-27 15:46:00 +0000358 mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000359 CALL_FN_W_W(ret, fn, mutex);
bart3b1ee452008-02-29 19:28:15 +0000360 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
bart00344642008-03-01 15:27:41 +0000361 mutex, ret == 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000362 return ret;
363}
364
365// pthread_mutex_trylock
366PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
367 pthread_mutex_t *mutex)
368{
369 int ret;
370 int res;
371 OrigFn fn;
372 VALGRIND_GET_ORIG_FN(fn);
bart00344642008-03-01 15:27:41 +0000373 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
374 mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000375 CALL_FN_W_W(ret, fn, mutex);
bart3b1ee452008-02-29 19:28:15 +0000376 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
bart00344642008-03-01 15:27:41 +0000377 mutex, ret == 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000378 return ret;
379}
380
sewardj85642922008-01-14 11:54:56 +0000381// pthread_mutex_timedlock
382PTH_FUNC(int, pthreadZumutexZutimedlock, // pthread_mutex_timedlock
383 pthread_mutex_t *mutex,
384 const struct timespec *abs_timeout)
385{
386 int ret;
387 int res;
388 OrigFn fn;
389 VALGRIND_GET_ORIG_FN(fn);
bart00344642008-03-01 15:27:41 +0000390 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
391 mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
sewardj85642922008-01-14 11:54:56 +0000392 CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
bart3b1ee452008-02-29 19:28:15 +0000393 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
bart00344642008-03-01 15:27:41 +0000394 mutex, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000395 return ret;
396}
397
sewardjaf44c822007-11-25 14:01:38 +0000398// pthread_mutex_unlock
399PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
400 pthread_mutex_t *mutex)
401{
402 int ret;
403 int res;
404 OrigFn fn;
405 VALGRIND_GET_ORIG_FN(fn);
406 VALGRIND_DO_CLIENT_REQUEST(res, -1,
407 VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK,
bart5357fcb2008-02-27 15:46:00 +0000408 mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000409 CALL_FN_W_W(ret, fn, mutex);
410 return ret;
411}
412
413// pthread_cond_init
sewardj347eeba2008-01-21 14:19:07 +0000414PTH_FUNC(int, pthreadZucondZuinitZa, // pthread_cond_init*
sewardjaf44c822007-11-25 14:01:38 +0000415 pthread_cond_t* cond,
416 const pthread_condattr_t* attr)
417{
418 int ret;
419 int res;
420 OrigFn fn;
421 VALGRIND_GET_ORIG_FN(fn);
bart72b751c2008-03-01 13:44:24 +0000422 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_INIT,
sewardjaf44c822007-11-25 14:01:38 +0000423 cond, sizeof(*cond), 0, 0, 0);
bart72b751c2008-03-01 13:44:24 +0000424 CALL_FN_W_WW(ret, fn, cond, attr);
sewardjaf44c822007-11-25 14:01:38 +0000425 return ret;
426}
427
428// pthread_cond_destroy
sewardj347eeba2008-01-21 14:19:07 +0000429PTH_FUNC(int, pthreadZucondZudestroyZa, // pthread_cond_destroy*
sewardjaf44c822007-11-25 14:01:38 +0000430 pthread_cond_t* cond)
431{
432 int ret;
433 int res;
434 OrigFn fn;
435 VALGRIND_GET_ORIG_FN(fn);
sewardjaf44c822007-11-25 14:01:38 +0000436 CALL_FN_W_W(ret, fn, cond);
bart72b751c2008-03-01 13:44:24 +0000437 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_DESTROY,
438 cond, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000439 return ret;
440}
441
442// pthread_cond_wait
sewardj347eeba2008-01-21 14:19:07 +0000443PTH_FUNC(int, pthreadZucondZuwaitZa, // pthread_cond_wait*
sewardjaf44c822007-11-25 14:01:38 +0000444 pthread_cond_t *cond,
445 pthread_mutex_t *mutex)
446{
447 int ret;
448 int res;
449 OrigFn fn;
450 VALGRIND_GET_ORIG_FN(fn);
451 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_WAIT,
bart3b1ee452008-02-29 19:28:15 +0000452 cond, sizeof(*cond), mutex, mutex_type(mutex),
453 0);
sewardjaf44c822007-11-25 14:01:38 +0000454 CALL_FN_W_WW(ret, fn, cond, mutex);
455 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_WAIT,
bart00344642008-03-01 15:27:41 +0000456 cond, mutex, ret == 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000457 return ret;
458}
459
460// pthread_cond_timedwait
sewardj347eeba2008-01-21 14:19:07 +0000461PTH_FUNC(int, pthreadZucondZutimedwaitZa, // pthread_cond_timedwait*
sewardjaf44c822007-11-25 14:01:38 +0000462 pthread_cond_t *cond,
463 pthread_mutex_t *mutex,
464 const struct timespec* abstime)
465{
466 int ret;
467 int res;
468 OrigFn fn;
469 VALGRIND_GET_ORIG_FN(fn);
470 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_WAIT,
bart3b1ee452008-02-29 19:28:15 +0000471 cond, sizeof(*cond), mutex, mutex_type(mutex),
472 0);
sewardjaf44c822007-11-25 14:01:38 +0000473 CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
474 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_WAIT,
bart00344642008-03-01 15:27:41 +0000475 cond, mutex, ret == 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000476 return ret;
477}
478
479// pthread_cond_signal
sewardj347eeba2008-01-21 14:19:07 +0000480PTH_FUNC(int, pthreadZucondZusignalZa, // pthread_cond_signal*
sewardjaf44c822007-11-25 14:01:38 +0000481 pthread_cond_t* cond)
482{
483 int ret;
484 int res;
485 OrigFn fn;
486 VALGRIND_GET_ORIG_FN(fn);
487 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_SIGNAL,
488 cond, 0, 0, 0, 0);
489 CALL_FN_W_W(ret, fn, cond);
490 return ret;
491}
492
493// pthread_cond_broadcast
sewardj347eeba2008-01-21 14:19:07 +0000494PTH_FUNC(int, pthreadZucondZubroadcastZa, // pthread_cond_broadcast*
sewardjaf44c822007-11-25 14:01:38 +0000495 pthread_cond_t* cond)
496{
497 int ret;
498 int res;
499 OrigFn fn;
500 VALGRIND_GET_ORIG_FN(fn);
501 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_BROADCAST,
502 cond, 0, 0, 0, 0);
503 CALL_FN_W_W(ret, fn, cond);
504 return ret;
505}
506
507
508// pthread_spin_init
509PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
510 pthread_spinlock_t *spinlock,
511 int pshared)
512{
513 int ret;
514 int res;
515 OrigFn fn;
516 VALGRIND_GET_ORIG_FN(fn);
517 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000518 spinlock, sizeof(*spinlock),
519 mutex_type_spinlock, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000520 CALL_FN_W_WW(ret, fn, spinlock, pshared);
521 return ret;
522}
523
524// pthread_spin_destroy
525PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
526 pthread_spinlock_t *spinlock)
527{
528 int ret;
529 int res;
530 OrigFn fn;
531 VALGRIND_GET_ORIG_FN(fn);
532 CALL_FN_W_W(ret, fn, spinlock);
533 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
sewardj721ad7b2007-11-30 08:30:29 +0000534 spinlock, mutex_type_spinlock, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000535 return ret;
536}
537
538// pthread_spin_lock
539PTH_FUNC(int, pthreadZuspinZulock, // pthread_spin_lock
540 pthread_spinlock_t *spinlock)
541{
542 int ret;
543 int res;
544 OrigFn fn;
545 VALGRIND_GET_ORIG_FN(fn);
bart00344642008-03-01 15:27:41 +0000546 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
547 spinlock, sizeof(*spinlock), mutex_type_spinlock,
548 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000549 CALL_FN_W_W(ret, fn, spinlock);
bart3b1ee452008-02-29 19:28:15 +0000550 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
bart00344642008-03-01 15:27:41 +0000551 spinlock, ret == 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000552 return ret;
553}
554
555// pthread_spin_trylock
556PTH_FUNC(int, pthreadZuspinZutrylock, // pthread_spin_trylock
557 pthread_spinlock_t *spinlock)
558{
559 int ret;
560 int res;
561 OrigFn fn;
562 VALGRIND_GET_ORIG_FN(fn);
bart00344642008-03-01 15:27:41 +0000563 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
564 spinlock, sizeof(*spinlock), mutex_type_spinlock,
565 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000566 CALL_FN_W_W(ret, fn, spinlock);
bart3b1ee452008-02-29 19:28:15 +0000567 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
bart00344642008-03-01 15:27:41 +0000568 spinlock, ret == 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000569 return ret;
570}
571
572// pthread_spin_unlock
573PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock
574 pthread_spinlock_t *spinlock)
575{
576 int ret;
577 int res;
578 OrigFn fn;
579 VALGRIND_GET_ORIG_FN(fn);
580 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000581 spinlock, sizeof(*spinlock),
582 mutex_type_spinlock, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000583 CALL_FN_W_W(ret, fn, spinlock);
584 return ret;
585}
586
sewardj85642922008-01-14 11:54:56 +0000587// pthread_barrier_init
588PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
589 pthread_barrier_t* barrier,
590 const pthread_barrierattr_t* attr,
591 unsigned count)
592{
593 int ret;
594 int res;
595 OrigFn fn;
596 VALGRIND_GET_ORIG_FN(fn);
597 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__BARRIER_INIT,
598 barrier, sizeof(*barrier),
599 count, 0, 0);
600 CALL_FN_W_WWW(ret, fn, barrier, attr, count);
601 return ret;
602}
603
604// pthread_barrier_destroy
605PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
606 pthread_barrier_t* barrier)
607{
608 int ret;
609 int res;
610 OrigFn fn;
611 VALGRIND_GET_ORIG_FN(fn);
612 CALL_FN_W_W(ret, fn, barrier);
613 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__BARRIER_DESTROY,
614 barrier, 0, 0, 0, 0);
615 return ret;
616}
617
618// pthread_barrier_wait
619PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
620 pthread_barrier_t* barrier)
621{
622 int ret;
623 int res;
624 OrigFn fn;
625 VALGRIND_GET_ORIG_FN(fn);
626 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT,
627 barrier, 0, 0, 0, 0);
628 CALL_FN_W_W(ret, fn, barrier);
629 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
630 barrier,
631 ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
632 0, 0, 0);
633 return ret;
634}
635
636
637// From glibc 2.0 linuxthreads/sysdeps/pthread/cmpxchg/semaphorebits.h
638typedef struct { long int sem_status; } sem_t_glibc_2_0;
639
640// sem_init
bart00344642008-03-01 15:27:41 +0000641PTH_FUNC(int, semZuinitZAGLIBCZu2Zd0, // sem_init@GLIBC_2.0
sewardj85642922008-01-14 11:54:56 +0000642 sem_t_glibc_2_0 *sem,
643 int pshared,
644 unsigned int value)
645{
646 int ret;
647 int res;
648 OrigFn fn;
649 VALGRIND_GET_ORIG_FN(fn);
650 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
651 if (ret == 0)
652 {
653 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_INIT,
654 sem, sizeof(*sem),
655 pshared, value, 0);
656 }
657 return ret;
658}
659
bart00344642008-03-01 15:27:41 +0000660PTH_FUNC(int, semZuinitZa, // sem_init*
sewardj85642922008-01-14 11:54:56 +0000661 sem_t *sem,
662 int pshared,
663 unsigned int value)
664{
665 int ret;
666 int res;
667 OrigFn fn;
668 VALGRIND_GET_ORIG_FN(fn);
669 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
670 if (ret == 0)
671 {
672 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_INIT,
673 sem, sizeof(*sem),
674 pshared, value, 0);
675 }
676 return ret;
677}
678
679// sem_destroy
bart00344642008-03-01 15:27:41 +0000680PTH_FUNC(int, semZudestroyZAGLIBCZu2Zd0, // sem_destroy@GLIBC_2.0
sewardj85642922008-01-14 11:54:56 +0000681 sem_t_glibc_2_0 *sem)
682{
683 int ret;
684 int res;
685 OrigFn fn;
686 VALGRIND_GET_ORIG_FN(fn);
687 CALL_FN_W_W(ret, fn, sem);
688 if (ret == 0)
689 {
690 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_DESTROY,
691 sem, 0, 0, 0, 0);
692 }
693 return ret;
694}
695
bart00344642008-03-01 15:27:41 +0000696PTH_FUNC(int, semZudestroyZa, // sem_destroy*
sewardj85642922008-01-14 11:54:56 +0000697 sem_t *sem)
698{
699 int ret;
700 int res;
701 OrigFn fn;
702 VALGRIND_GET_ORIG_FN(fn);
703 CALL_FN_W_W(ret, fn, sem);
704 if (ret == 0)
705 {
706 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_DESTROY,
707 sem, 0, 0, 0, 0);
708 }
709 return ret;
710}
711
712// sem_wait
bart00344642008-03-01 15:27:41 +0000713PTH_FUNC(int, semZuwaitZAGLIBCZu2Zd0, // sem_wait@GLIBC_2.0
sewardj85642922008-01-14 11:54:56 +0000714 sem_t_glibc_2_0 *sem)
715{
716 int ret;
717 int res;
718 OrigFn fn;
719 VALGRIND_GET_ORIG_FN(fn);
bart28230a32008-02-29 17:27:03 +0000720 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
721 sem, 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000722 CALL_FN_W_W(ret, fn, sem);
bart28230a32008-02-29 17:27:03 +0000723 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
724 sem, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000725 return ret;
726}
727
bart28230a32008-02-29 17:27:03 +0000728// sem_wait
bart00344642008-03-01 15:27:41 +0000729PTH_FUNC(int, semZuwaitZa, // sem_wait*
sewardj85642922008-01-14 11:54:56 +0000730 sem_t *sem)
731{
732 int ret;
733 int res;
734 OrigFn fn;
735 VALGRIND_GET_ORIG_FN(fn);
bart28230a32008-02-29 17:27:03 +0000736 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
737 sem, 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000738 CALL_FN_W_W(ret, fn, sem);
bart28230a32008-02-29 17:27:03 +0000739 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
740 sem, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000741 return ret;
742}
743
744// sem_trywait
bart00344642008-03-01 15:27:41 +0000745PTH_FUNC(int, semZutrywaitZAGLIBCZu2Zd0, // sem_trywait@GLIBC_2.0
sewardj85642922008-01-14 11:54:56 +0000746 sem_t_glibc_2_0 *sem)
747{
748 int ret;
749 int res;
750 OrigFn fn;
751 VALGRIND_GET_ORIG_FN(fn);
bart28230a32008-02-29 17:27:03 +0000752 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
753 sem, 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000754 CALL_FN_W_W(ret, fn, sem);
bart28230a32008-02-29 17:27:03 +0000755 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
756 sem, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000757 return ret;
758}
759
bart00344642008-03-01 15:27:41 +0000760PTH_FUNC(int, semZutrywaitZa, // sem_trywait*
sewardj85642922008-01-14 11:54:56 +0000761 sem_t *sem)
762{
763 int ret;
764 int res;
765 OrigFn fn;
766 VALGRIND_GET_ORIG_FN(fn);
bart28230a32008-02-29 17:27:03 +0000767 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
768 sem, 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000769 CALL_FN_W_W(ret, fn, sem);
bart28230a32008-02-29 17:27:03 +0000770 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
771 sem, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000772 return ret;
773}
774
775// sem_timedwait
bart00344642008-03-01 15:27:41 +0000776PTH_FUNC(int, semZutimedwait, // sem_timedwait
sewardj85642922008-01-14 11:54:56 +0000777 sem_t *sem, const struct timespec *abs_timeout)
778{
779 int ret;
780 int res;
781 OrigFn fn;
782 VALGRIND_GET_ORIG_FN(fn);
bart28230a32008-02-29 17:27:03 +0000783 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
784 sem, 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000785 CALL_FN_W_WW(ret, fn, sem, abs_timeout);
bart28230a32008-02-29 17:27:03 +0000786 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
787 sem, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000788 return ret;
789}
790
791// sem_post
bart00344642008-03-01 15:27:41 +0000792PTH_FUNC(int, semZupostZAGLIBCZu2Zd0, // sem_post@GLIBC_2.0
sewardj85642922008-01-14 11:54:56 +0000793 sem_t_glibc_2_0 *sem)
794{
795 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, sizeof(*sem), 0, 0, 0);
801 CALL_FN_W_W(ret, fn, sem);
sewardjc0be9252008-02-11 11:00:51 +0000802 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
803 sem, sizeof(*sem), ret == 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000804 return ret;
805}
806
bart00344642008-03-01 15:27:41 +0000807// sem_post
808PTH_FUNC(int, semZupostZa, // sem_post*
sewardj85642922008-01-14 11:54:56 +0000809 sem_t *sem)
810{
811 int ret;
812 int res;
813 OrigFn fn;
814 VALGRIND_GET_ORIG_FN(fn);
815 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
816 sem, sizeof(*sem), 0, 0, 0);
817 CALL_FN_W_W(ret, fn, sem);
sewardje3b57aa2008-01-18 07:42:01 +0000818 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
819 sem, sizeof(*sem), ret == 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000820 return ret;
821}
822
bart00344642008-03-01 15:27:41 +0000823// pthread_rwlock_init
824PTH_FUNC(int,
825 pthreadZurwlockZuinitZa, // pthread_rwlock_init*
826 pthread_rwlock_t* rwlock,
827 const pthread_rwlockattr_t* attr)
828{
829 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_INIT,
834 rwlock, sizeof(*rwlock), 0, 0, 0);
835 CALL_FN_W_WW(ret, fn, rwlock, attr);
836 return ret;
837}
838
839// pthread_rwlock_destroy
840PTH_FUNC(int,
841 pthreadZurwlockZudestroyZa, // pthread_rwlock_destroy*
842 pthread_rwlock_t* rwlock)
843{
844 int ret;
845 int res;
846 OrigFn fn;
847 VALGRIND_GET_ORIG_FN(fn);
848 CALL_FN_W_W(ret, fn, rwlock);
849 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_DESTROY,
850 rwlock, 0, 0, 0, 0);
851 return ret;
852}
853
854// pthread_rwlock_rdlock
855PTH_FUNC(int,
856 pthreadZurwlockZurdlockZa, // pthread_rwlock_rdlock*
857 pthread_rwlock_t* rwlock)
858{
859 int ret;
860 int res;
861 OrigFn fn;
862 VALGRIND_GET_ORIG_FN(fn);
863 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
864 rwlock, sizeof(*rwlock), 0, 0, 0);
865 CALL_FN_W_W(ret, fn, rwlock);
866 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
867 rwlock, ret == 0, 0, 0, 0);
868 return ret;
869}
870
871// pthread_rwlock_wrlock
872PTH_FUNC(int,
873 pthreadZurwlockZuwrlockZa, // pthread_rwlock_wrlock*
874 pthread_rwlock_t* rwlock)
875{
876 int ret;
877 int res;
878 OrigFn fn;
879 VALGRIND_GET_ORIG_FN(fn);
880 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
881 rwlock, sizeof(*rwlock), 0, 0, 0);
882 CALL_FN_W_W(ret, fn, rwlock);
883 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
884 rwlock, ret == 0, 0, 0, 0);
885 return ret;
886}
887
888// pthread_rwlock_timedrdlock
889PTH_FUNC(int,
890 pthreadZurwlockZutimedrdlockZa, // pthread_rwlock_timedrdlock*
891 pthread_rwlock_t* rwlock)
892{
893 int ret;
894 int res;
895 OrigFn fn;
896 VALGRIND_GET_ORIG_FN(fn);
897 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
898 rwlock, sizeof(*rwlock), 0, 0, 0);
899 CALL_FN_W_W(ret, fn, rwlock);
900 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
901 rwlock, ret == 0, 0, 0, 0);
902 return ret;
903}
904
905// pthread_rwlock_timedwrlock
906PTH_FUNC(int,
907 pthreadZurwlockZutimedwrlockZa, // pthread_rwlock_timedwrlock*
908 pthread_rwlock_t* rwlock)
909{
910 int ret;
911 int res;
912 OrigFn fn;
913 VALGRIND_GET_ORIG_FN(fn);
914 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
915 rwlock, sizeof(*rwlock), 0, 0, 0);
916 CALL_FN_W_W(ret, fn, rwlock);
917 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
918 rwlock, ret == 0, 0, 0, 0);
919 return ret;
920}
921
922// pthread_rwlock_tryrdlock
923PTH_FUNC(int,
924 pthreadZurwlockZutryrdlockZa, // pthread_rwlock_tryrdlock*
925 pthread_rwlock_t* rwlock)
926{
927 int ret;
928 int res;
929 OrigFn fn;
930 VALGRIND_GET_ORIG_FN(fn);
931 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
932 rwlock, sizeof(*rwlock), 0, 0, 0);
933 CALL_FN_W_W(ret, fn, rwlock);
934 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
935 rwlock, ret == 0, 0, 0, 0);
936 return ret;
937}
938
939// pthread_rwlock_trywrlock
940PTH_FUNC(int,
941 pthreadZurwlockZutrywrlockZa, // pthread_rwlock_trywrlock*
942 pthread_rwlock_t* rwlock)
943{
944 int ret;
945 int res;
946 OrigFn fn;
947 VALGRIND_GET_ORIG_FN(fn);
948 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
949 rwlock, sizeof(*rwlock), 0, 0, 0);
950 CALL_FN_W_W(ret, fn, rwlock);
951 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
952 rwlock, ret == 0, 0, 0, 0);
953 return ret;
954}
955
956// pthread_rwlock_unlock
957PTH_FUNC(int,
958 pthreadZurwlockZuunlockZa, // pthread_rwlock_unlock*
959 pthread_rwlock_t* rwlock)
960{
961 int ret;
962 int res;
963 OrigFn fn;
964 VALGRIND_GET_ORIG_FN(fn);
965 CALL_FN_W_W(ret, fn, rwlock);
bart777f7fe2008-03-02 17:43:18 +0000966 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_UNLOCK,
bart00344642008-03-01 15:27:41 +0000967 rwlock, ret == 0, 0, 0, 0);
968 return ret;
969}
970
sewardj85642922008-01-14 11:54:56 +0000971
sewardjaf44c822007-11-25 14:01:38 +0000972/*
973 * Local variables:
974 * c-basic-offset: 3
975 * End:
976 */