blob: ad6746c4a24f1e8253d5cff86a54368f5982515c [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
43// Make sure pthread_spinlock_t is available on glibc 2.3.2 systems.
44#ifndef _GNU_SOURCE
45#define _GNU_SOURCE
46#endif
47
48#include <assert.h>
49#include <inttypes.h> // uintptr_t
sewardj85642922008-01-14 11:54:56 +000050#include <pthread.h>
51#include <semaphore.h>
sewardjaf44c822007-11-25 14:01:38 +000052#include <stdio.h>
53#include <unistd.h>
sewardjaf44c822007-11-25 14:01:38 +000054#include "drd_clientreq.h"
sewardj85642922008-01-14 11:54:56 +000055#include "pub_tool_redir.h"
sewardjaf44c822007-11-25 14:01:38 +000056
57
58// Defines.
59
60#define PTH_FUNC(ret_ty, f, args...) \
61 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args); \
62 ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args)
63
64
65// Local data structures.
66
67typedef struct
68{
69 void* (*start)(void*);
70 void* arg;
71 int detachstate;
72#if 0
73 pthread_mutex_t mutex;
74 pthread_cond_t cond;
75#else
76 int wrapper_started;
77#endif
78} VgPosixThreadArgs;
79
80
81// Local variables.
82
83static int vg_main_thread_state_is_set = 0;
84
85
86// Function definitions.
87
88static void vg_start_suppression(const void* const p, size_t const size)
89{
90 int res;
91 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
92 p, size, 0, 0, 0);
93}
94
95#if 0
96static void vg_finish_suppression(const void* const p, size_t const size)
97{
98 int res;
99 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_FINISH_SUPPRESSION,
100 p, size, 0, 0, 0);
101}
102#endif
103
104static void vg_start_recording(void)
105{
106 int res;
107 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_RECORDING,
108 pthread_self(), 0, 0, 0, 0);
109}
110
111static void vg_stop_recording(void)
112{
113 int res;
114 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_STOP_RECORDING,
115 pthread_self(), 0, 0, 0, 0);
116}
117
118static void vg_set_joinable(const pthread_t tid, const int joinable)
119{
120 int res;
121 assert(joinable == 0 || joinable == 1);
sewardjaf44c822007-11-25 14:01:38 +0000122 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_JOINABLE,
123 tid, joinable, 0, 0, 0);
124}
125
126static void* vg_thread_wrapper(void* arg)
127{
128 int res;
129 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
130 0, 0, 0, 0, 0);
131
132 {
133 VgPosixThreadArgs* const arg_ptr = (VgPosixThreadArgs*)arg;
134 VgPosixThreadArgs const arg_copy = *arg_ptr;
135 void* result;
136
137#if 0
138 pthread_mutex_lock(arg_ptr->mutex);
139 pthread_cond_signal(arg_ptr->cond);
140 pthread_mutex_unlock(arg_ptr->mutex);
141#else
142 arg_ptr->wrapper_started = 1;
143#endif
144
145 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
146 pthread_self(), 0, 0, 0, 0);
147 vg_set_joinable(pthread_self(),
148 arg_copy.detachstate == PTHREAD_CREATE_JOINABLE);
149 result = (arg_copy.start)(arg_copy.arg);
150 return result;
151 }
152}
153
154static void vg_set_main_thread_state(void)
155{
156 int res;
157
158 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
159 0, 0, 0, 0, 0);
160
sewardjaf44c822007-11-25 14:01:38 +0000161 // Make sure that DRD knows about the main thread's POSIX thread ID.
162 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
163 pthread_self(), 0, 0, 0, 0);
164
165}
166
167// pthread_create
168PTH_FUNC(int, pthreadZucreateZAZa, // pthread_create@*
169 pthread_t *thread, const pthread_attr_t *attr,
170 void *(*start) (void *), void *arg)
171{
172 int ret;
173 OrigFn fn;
174 VgPosixThreadArgs vgargs;
175
176 VALGRIND_GET_ORIG_FN(fn);
177
178 if (vg_main_thread_state_is_set == 0)
179 {
180 vg_set_main_thread_state();
181 vg_main_thread_state_is_set = 1;
182 }
183 vg_start_suppression(&vgargs.wrapper_started,
184 sizeof(vgargs.wrapper_started));
185 vgargs.start = start;
186 vgargs.arg = arg;
187 vgargs.wrapper_started = 0;
188 vgargs.detachstate = PTHREAD_CREATE_JOINABLE;
189 if (attr)
190 {
191 if (pthread_attr_getdetachstate(attr, &vgargs.detachstate) != 0)
192 {
193 assert(0);
194 }
sewardjaf44c822007-11-25 14:01:38 +0000195 }
196 assert(vgargs.detachstate == PTHREAD_CREATE_JOINABLE
197 || vgargs.detachstate == PTHREAD_CREATE_DETACHED);
198#if 0
199 pthread_mutex_init(&vgargs.mutex, 0);
200 pthread_cond_init(&vgargs.cond, 0);
201 pthread_mutex_lock(&vgargs.mutex);
202#endif
203 vg_stop_recording();
204 CALL_FN_W_WWWW(ret, fn, thread, attr, vg_thread_wrapper, &vgargs);
205 vg_start_recording();
206#if 0
207 pthread_cond_wait(&vgargs.cond, &vgargs.mutex);
208 pthread_mutex_unlock(&vgargs.mutex);
209 pthread_cond_destroy(&vgargs.cond);
210 pthread_mutex_destroy(&vgargs.mutex);
211#else
212 // Yes, you see it correctly, busy waiting ... The problem is that
213 // POSIX threads functions cannot be called here -- the functions defined
sewardj85642922008-01-14 11:54:56 +0000214 // in this file (drd_intercepts.c) would be called instead of those in
sewardjaf44c822007-11-25 14:01:38 +0000215 // libpthread.so. This loop is necessary because vgargs is allocated on the
216 // stack, and the created thread reads it.
sewardje0744f02007-12-01 02:09:50 +0000217 if (ret == 0)
sewardjaf44c822007-11-25 14:01:38 +0000218 {
sewardje0744f02007-12-01 02:09:50 +0000219 while (! vgargs.wrapper_started)
220 {
221 sched_yield();
222 }
sewardjaf44c822007-11-25 14:01:38 +0000223 }
224#endif
225 return ret;
226}
227
228// pthread_join
229PTH_FUNC(int, pthreadZujoin, // pthread_join
230 pthread_t pt_joinee, void **thread_return)
231{
232 int ret;
233 int res;
234 OrigFn fn;
235
236 VALGRIND_GET_ORIG_FN(fn);
237 CALL_FN_W_WW(ret, fn, pt_joinee, thread_return);
238 if (ret == 0)
239 {
240 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_JOIN,
241 pt_joinee, 0, 0, 0, 0);
242 }
243 return ret;
244}
245
246// pthread_detach
247PTH_FUNC(int, pthreadZudetach, pthread_t pt_thread)
248{
249 int ret;
250 OrigFn fn;
251 VALGRIND_GET_ORIG_FN(fn);
252 {
253 CALL_FN_W_W(ret, fn, pt_thread);
254 if (ret == 0)
255 {
256 vg_set_joinable(pt_thread, 0);
257 }
258 }
259 return ret;
260}
261
262// pthread_mutex_init
263PTH_FUNC(int, pthreadZumutexZuinit,
264 pthread_mutex_t *mutex,
265 const pthread_mutexattr_t* attr)
266{
267 int ret;
268 int res;
269 OrigFn fn;
270 VALGRIND_GET_ORIG_FN(fn);
271 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
sewardj721ad7b2007-11-30 08:30:29 +0000272 mutex, sizeof(*mutex), mutex_type_mutex, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000273 CALL_FN_W_WW(ret, fn, mutex, attr);
274 return ret;
275}
276
277// pthread_mutex_destroy
278PTH_FUNC(int, pthreadZumutexZudestroy,
279 pthread_mutex_t *mutex)
280{
281 int ret;
282 int res;
283 OrigFn fn;
284 VALGRIND_GET_ORIG_FN(fn);
285 CALL_FN_W_W(ret, fn, mutex);
286 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
sewardj721ad7b2007-11-30 08:30:29 +0000287 mutex, mutex_type_mutex, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000288 return ret;
289}
290
291// pthread_mutex_lock
292PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
293 pthread_mutex_t *mutex)
294{
295 int ret;
296 int res;
297 OrigFn fn;
298 VALGRIND_GET_ORIG_FN(fn);
299 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000300 mutex, sizeof(*mutex), mutex_type_mutex, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000301#if 1
302 // The only purpose of the system call below is to make drd work on AMD64
303 // systems. Without this system call, clients crash (SIGSEGV) in
304 // std::locale::locale().
305 write(1, "", 0);
306#endif
307 CALL_FN_W_W(ret, fn, mutex);
308 if (ret == 0)
309 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000310 mutex, sizeof(*mutex), mutex_type_mutex, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000311 return ret;
312}
313
314// pthread_mutex_trylock
315PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
316 pthread_mutex_t *mutex)
317{
318 int ret;
319 int res;
320 OrigFn fn;
321 VALGRIND_GET_ORIG_FN(fn);
322 CALL_FN_W_W(ret, fn, mutex);
323 if (ret == 0)
324 {
325 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000326 mutex, sizeof(*mutex), mutex_type_mutex, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000327 }
328 return ret;
329}
330
sewardj85642922008-01-14 11:54:56 +0000331// pthread_mutex_timedlock
332PTH_FUNC(int, pthreadZumutexZutimedlock, // pthread_mutex_timedlock
333 pthread_mutex_t *mutex,
334 const struct timespec *abs_timeout)
335{
336 int ret;
337 int res;
338 OrigFn fn;
339 VALGRIND_GET_ORIG_FN(fn);
340 CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
341 if (ret == 0)
342 {
343 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
344 mutex, sizeof(*mutex), mutex_type_mutex, 0, 0);
345 }
346 return ret;
347}
348
sewardjaf44c822007-11-25 14:01:38 +0000349// pthread_mutex_unlock
350PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
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, -1,
358 VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000359 mutex, sizeof(*mutex), mutex_type_mutex, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000360 CALL_FN_W_W(ret, fn, mutex);
361 return ret;
362}
363
364// pthread_cond_init
365PTH_FUNC(int, pthreadZucondZuinitZAZa, // pthread_cond_init@*
366 pthread_cond_t* cond,
367 const pthread_condattr_t* attr)
368{
369 int ret;
370 int res;
371 OrigFn fn;
372 VALGRIND_GET_ORIG_FN(fn);
373 CALL_FN_W_WW(ret, fn, cond, attr);
374 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_INIT,
375 cond, sizeof(*cond), 0, 0, 0);
376 return ret;
377}
378
379// pthread_cond_destroy
380PTH_FUNC(int, pthreadZucondZudestroyZAZa, // pthread_cond_destroy@*
381 pthread_cond_t* cond)
382{
383 int ret;
384 int res;
385 OrigFn fn;
386 VALGRIND_GET_ORIG_FN(fn);
387 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_DESTROY,
sewardj721ad7b2007-11-30 08:30:29 +0000388 cond, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000389 CALL_FN_W_W(ret, fn, cond);
390 return ret;
391}
392
393// pthread_cond_wait
394PTH_FUNC(int, pthreadZucondZuwaitZAZa, // pthread_cond_wait@*
395 pthread_cond_t *cond,
396 pthread_mutex_t *mutex)
397{
398 int ret;
399 int res;
400 OrigFn fn;
401 VALGRIND_GET_ORIG_FN(fn);
402 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_WAIT,
sewardj721ad7b2007-11-30 08:30:29 +0000403 cond, sizeof(*cond), mutex, sizeof(*mutex), 0);
sewardjaf44c822007-11-25 14:01:38 +0000404 CALL_FN_W_WW(ret, fn, cond, mutex);
405 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_WAIT,
sewardj721ad7b2007-11-30 08:30:29 +0000406 cond, sizeof(*cond), mutex, sizeof(*mutex), 0);
sewardjaf44c822007-11-25 14:01:38 +0000407 return ret;
408}
409
410// pthread_cond_timedwait
411PTH_FUNC(int, pthreadZucondZutimedwaitZAZa, // pthread_cond_timedwait@*
412 pthread_cond_t *cond,
413 pthread_mutex_t *mutex,
414 const struct timespec* abstime)
415{
416 int ret;
417 int res;
418 OrigFn fn;
419 VALGRIND_GET_ORIG_FN(fn);
420 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_WAIT,
sewardj721ad7b2007-11-30 08:30:29 +0000421 cond, sizeof(*cond), mutex, sizeof(*mutex), 0);
sewardjaf44c822007-11-25 14:01:38 +0000422 CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
423 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_WAIT,
sewardj721ad7b2007-11-30 08:30:29 +0000424 cond, sizeof(*cond), mutex, sizeof(*mutex), 0);
sewardjaf44c822007-11-25 14:01:38 +0000425 return ret;
426}
427
428// pthread_cond_signal
429PTH_FUNC(int, pthreadZucondZusignalZAZa, // pthread_cond_signal@*
430 pthread_cond_t* cond)
431{
432 int ret;
433 int res;
434 OrigFn fn;
435 VALGRIND_GET_ORIG_FN(fn);
436 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_SIGNAL,
437 cond, 0, 0, 0, 0);
438 CALL_FN_W_W(ret, fn, cond);
439 return ret;
440}
441
442// pthread_cond_broadcast
443PTH_FUNC(int, pthreadZucondZubroadcastZAZa, // pthread_cond_broadcast@*
444 pthread_cond_t* cond)
445{
446 int ret;
447 int res;
448 OrigFn fn;
449 VALGRIND_GET_ORIG_FN(fn);
450 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_BROADCAST,
451 cond, 0, 0, 0, 0);
452 CALL_FN_W_W(ret, fn, cond);
453 return ret;
454}
455
456
457// pthread_spin_init
458PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
459 pthread_spinlock_t *spinlock,
460 int pshared)
461{
462 int ret;
463 int res;
464 OrigFn fn;
465 VALGRIND_GET_ORIG_FN(fn);
466 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000467 spinlock, sizeof(*spinlock),
468 mutex_type_spinlock, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000469 CALL_FN_W_WW(ret, fn, spinlock, pshared);
470 return ret;
471}
472
473// pthread_spin_destroy
474PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
475 pthread_spinlock_t *spinlock)
476{
477 int ret;
478 int res;
479 OrigFn fn;
480 VALGRIND_GET_ORIG_FN(fn);
481 CALL_FN_W_W(ret, fn, spinlock);
482 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
sewardj721ad7b2007-11-30 08:30:29 +0000483 spinlock, mutex_type_spinlock, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000484 return ret;
485}
486
487// pthread_spin_lock
488PTH_FUNC(int, pthreadZuspinZulock, // pthread_spin_lock
489 pthread_spinlock_t *spinlock)
490{
491 int ret;
492 int res;
493 OrigFn fn;
494 VALGRIND_GET_ORIG_FN(fn);
495 CALL_FN_W_W(ret, fn, spinlock);
496 if (ret == 0)
497 {
498 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000499 spinlock, sizeof(*spinlock),
500 mutex_type_spinlock, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000501 }
502 return ret;
503}
504
505// pthread_spin_trylock
506PTH_FUNC(int, pthreadZuspinZutrylock, // pthread_spin_trylock
507 pthread_spinlock_t *spinlock)
508{
509 int ret;
510 int res;
511 OrigFn fn;
512 VALGRIND_GET_ORIG_FN(fn);
513 CALL_FN_W_W(ret, fn, spinlock);
514 if (ret == 0)
515 {
516 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000517 spinlock, sizeof(*spinlock),
518 mutex_type_spinlock, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000519 }
520 return ret;
521}
522
523// pthread_spin_unlock
524PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock
525 pthread_spinlock_t *spinlock)
526{
527 int ret;
528 int res;
529 OrigFn fn;
530 VALGRIND_GET_ORIG_FN(fn);
531 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000532 spinlock, sizeof(*spinlock),
533 mutex_type_spinlock, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000534 CALL_FN_W_W(ret, fn, spinlock);
535 return ret;
536}
537
sewardj85642922008-01-14 11:54:56 +0000538// pthread_barrier_init
539PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
540 pthread_barrier_t* barrier,
541 const pthread_barrierattr_t* attr,
542 unsigned count)
543{
544 int ret;
545 int res;
546 OrigFn fn;
547 VALGRIND_GET_ORIG_FN(fn);
548 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__BARRIER_INIT,
549 barrier, sizeof(*barrier),
550 count, 0, 0);
551 CALL_FN_W_WWW(ret, fn, barrier, attr, count);
552 return ret;
553}
554
555// pthread_barrier_destroy
556PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
557 pthread_barrier_t* barrier)
558{
559 int ret;
560 int res;
561 OrigFn fn;
562 VALGRIND_GET_ORIG_FN(fn);
563 CALL_FN_W_W(ret, fn, barrier);
564 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__BARRIER_DESTROY,
565 barrier, 0, 0, 0, 0);
566 return ret;
567}
568
569// pthread_barrier_wait
570PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
571 pthread_barrier_t* barrier)
572{
573 int ret;
574 int res;
575 OrigFn fn;
576 VALGRIND_GET_ORIG_FN(fn);
577 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT,
578 barrier, 0, 0, 0, 0);
579 CALL_FN_W_W(ret, fn, barrier);
580 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
581 barrier,
582 ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
583 0, 0, 0);
584 return ret;
585}
586
587
588// From glibc 2.0 linuxthreads/sysdeps/pthread/cmpxchg/semaphorebits.h
589typedef struct { long int sem_status; } sem_t_glibc_2_0;
590
591// sem_init
592PTH_FUNC(int, sem_initZAGLIBCZu2Zd0, // sem_init@GLIBC_2.0
593 sem_t_glibc_2_0 *sem,
594 int pshared,
595 unsigned int value)
596{
597 int ret;
598 int res;
599 OrigFn fn;
600 VALGRIND_GET_ORIG_FN(fn);
601 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
602 if (ret == 0)
603 {
604 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_INIT,
605 sem, sizeof(*sem),
606 pshared, value, 0);
607 }
608 return ret;
609}
610
611PTH_FUNC(int, sem_initZa, // sem_init*
612 sem_t *sem,
613 int pshared,
614 unsigned int value)
615{
616 int ret;
617 int res;
618 OrigFn fn;
619 VALGRIND_GET_ORIG_FN(fn);
620 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
621 if (ret == 0)
622 {
623 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_INIT,
624 sem, sizeof(*sem),
625 pshared, value, 0);
626 }
627 return ret;
628}
629
630// sem_destroy
631PTH_FUNC(int, sem_destroyZAGLIBCZu2Zd0, // sem_destroy@GLIBC_2.0
632 sem_t_glibc_2_0 *sem)
633{
634 int ret;
635 int res;
636 OrigFn fn;
637 VALGRIND_GET_ORIG_FN(fn);
638 CALL_FN_W_W(ret, fn, sem);
639 if (ret == 0)
640 {
641 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_DESTROY,
642 sem, 0, 0, 0, 0);
643 }
644 return ret;
645}
646
647PTH_FUNC(int, sem_destroyZa, // sem_destroy*
648 sem_t *sem)
649{
650 int ret;
651 int res;
652 OrigFn fn;
653 VALGRIND_GET_ORIG_FN(fn);
654 CALL_FN_W_W(ret, fn, sem);
655 if (ret == 0)
656 {
657 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_DESTROY,
658 sem, 0, 0, 0, 0);
659 }
660 return ret;
661}
662
663// sem_wait
664PTH_FUNC(int, sem_waitZAGLIBCZu2Zd0, // sem_wait@GLIBC_2.0
665 sem_t_glibc_2_0 *sem)
666{
667 int ret;
668 int res;
669 OrigFn fn;
670 VALGRIND_GET_ORIG_FN(fn);
671 CALL_FN_W_W(ret, fn, sem);
672 if (ret == 0)
673 {
674 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
675 sem, sizeof(*sem), 0, 0, 0);
676 }
677 return ret;
678}
679
680PTH_FUNC(int, sem_waitZa, // sem_wait*
681 sem_t *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__POST_SEM_WAIT,
691 sem, sizeof(*sem), 0, 0, 0);
692 }
693 return ret;
694}
695
696// sem_trywait
697PTH_FUNC(int, sem_trywaitZAGLIBCZu2Zd0, // sem_trywait@GLIBC_2.0
698 sem_t_glibc_2_0 *sem)
699{
700 int ret;
701 int res;
702 OrigFn fn;
703 VALGRIND_GET_ORIG_FN(fn);
704 CALL_FN_W_W(ret, fn, sem);
705 if (ret == 0)
706 {
707 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
708 sem, sizeof(*sem), 0, 0, 0);
709 }
710 return ret;
711}
712
713PTH_FUNC(int, sem_trywaitZa, // sem_trywait*
714 sem_t *sem)
715{
716 int ret;
717 int res;
718 OrigFn fn;
719 VALGRIND_GET_ORIG_FN(fn);
720 CALL_FN_W_W(ret, fn, sem);
721 if (ret == 0)
722 {
723 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
724 sem, sizeof(*sem), 0, 0, 0);
725 }
726 return ret;
727}
728
729// sem_timedwait
730PTH_FUNC(int, sem_timedwait, // sem_timedwait
731 sem_t *sem, const struct timespec *abs_timeout)
732{
733 int ret;
734 int res;
735 OrigFn fn;
736 VALGRIND_GET_ORIG_FN(fn);
737 CALL_FN_W_WW(ret, fn, sem, abs_timeout);
738 if (ret == 0)
739 {
740 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
741 sem, sizeof(*sem), 0, 0, 0);
742 }
743 return ret;
744}
745
746// sem_post
747PTH_FUNC(int, sem_postZAGLIBCZu2Zd0, // sem_post@GLIBC_2.0
748 sem_t_glibc_2_0 *sem)
749{
750 int ret;
751 int res;
752 OrigFn fn;
753 VALGRIND_GET_ORIG_FN(fn);
754 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
755 sem, sizeof(*sem), 0, 0, 0);
756 CALL_FN_W_W(ret, fn, sem);
757 assert(ret == 0);
758 if (ret == 0)
759 {
760 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
761 sem, sizeof(*sem), 0, 0, 0);
762 }
763 return ret;
764}
765
766PTH_FUNC(int, sem_postZa, // sem_post*
767 sem_t *sem)
768{
769 int ret;
770 int res;
771 OrigFn fn;
772 VALGRIND_GET_ORIG_FN(fn);
773 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
774 sem, sizeof(*sem), 0, 0, 0);
775 CALL_FN_W_W(ret, fn, sem);
sewardje3b57aa2008-01-18 07:42:01 +0000776 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
777 sem, sizeof(*sem), ret == 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000778 return ret;
779}
780
781/*
782pthread_rwlock_destroy
783pthread_rwlock_init
784pthread_rwlock_rdlock
785pthread_rwlock_timedrdlock
786pthread_rwlock_timedwrlock
787pthread_rwlock_tryrdlock
788pthread_rwlock_trywrlock
789pthread_rwlock_unlock
790pthread_rwlock_wrlock
791pthread_rwlockattr_destroy
792pthread_rwlockattr_getkind_np
793pthread_rwlockattr_getpshared
794pthread_rwlockattr_init
795pthread_rwlockattr_setkind_np
796pthread_rwlockattr_setpshared
797 */
798
sewardjaf44c822007-11-25 14:01:38 +0000799/*
800 * Local variables:
801 * c-basic-offset: 3
802 * End:
803 */