blob: 706ec1efc25ded315456cc009213af60fc877524 [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>
50#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>
sewardjaf44c822007-11-25 14:01:38 +000055#include <unistd.h>
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;
bart0d063002008-03-01 07:25:13 +000086static pid_t vg_main_thread_pid;
sewardjaf44c822007-11-25 14:01:38 +000087
88
89// Function definitions.
90
bart5357fcb2008-02-27 15:46:00 +000091static MutexT pthread_to_drd_mutex_type(const int kind)
92{
93 switch (kind)
94 {
95 /* PTHREAD_MUTEX_RECURSIVE_NP */
96 case PTHREAD_MUTEX_RECURSIVE:
97 return mutex_type_recursive_mutex;
98 /* PTHREAD_MUTEX_ERRORCHECK_NP */
99 case PTHREAD_MUTEX_ERRORCHECK:
100 return mutex_type_errorcheck_mutex;
101 /* PTHREAD_MUTEX_TIMED_NP */
102 /* PTHREAD_MUTEX_NORMAL */
103 case PTHREAD_MUTEX_DEFAULT:
104 case PTHREAD_MUTEX_ADAPTIVE_NP:
105 return mutex_type_default_mutex;
bart5357fcb2008-02-27 15:46:00 +0000106 }
bart635cb162008-02-28 08:30:43 +0000107 return mutex_type_invalid_mutex;
bart5357fcb2008-02-27 15:46:00 +0000108}
109
110static MutexT mutex_type(pthread_mutex_t* mutex)
111{
bartc9463c42008-02-28 07:36:04 +0000112#if defined(_PTHREAD_DESCR_DEFINED)
113 // Linuxthreads.
114 const int kind = mutex->__m_kind;
115#elif defined(__SIZEOF_PTHREAD_MUTEX_T)
116 // NPTL.
117 const int kind = mutex->__data.__kind;
118#else
119 // Another POSIX threads implementation. Regression tests will fail.
120 const int kind = PTHREAD_MUTEX_DEFAULT;
121#endif
122 return pthread_to_drd_mutex_type(kind);
bart5357fcb2008-02-27 15:46:00 +0000123}
124
sewardjaf44c822007-11-25 14:01:38 +0000125static void vg_start_suppression(const void* const p, size_t const size)
126{
127 int res;
128 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
bart5e85d262008-03-01 10:49:37 +0000129 p, (char*)p + size, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000130}
131
132static void vg_set_joinable(const pthread_t tid, const int joinable)
133{
134 int res;
135 assert(joinable == 0 || joinable == 1);
sewardjaf44c822007-11-25 14:01:38 +0000136 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_JOINABLE,
137 tid, joinable, 0, 0, 0);
138}
139
140static void* vg_thread_wrapper(void* arg)
141{
142 int res;
bart0d063002008-03-01 07:25:13 +0000143
144 if (getpid() != vg_main_thread_pid)
145 {
bart777f7fe2008-03-02 17:43:18 +0000146 if (getenv("LD_ASSUME_KERNEL"))
147 {
148 fprintf(stderr,
149"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
150"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
151"after having unset the environment variable LD_ASSUME_KERNEL. Giving up.\n"
152 );
153 }
154 else
155 {
156 fprintf(stderr,
157"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
158"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
159"after having upgraded to a newer version of your Linux distribution.\n"
160"Giving up.\n"
161 );
162 }
bart0d063002008-03-01 07:25:13 +0000163 abort();
164 }
165
sewardjaf44c822007-11-25 14:01:38 +0000166 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
167 0, 0, 0, 0, 0);
168
169 {
170 VgPosixThreadArgs* const arg_ptr = (VgPosixThreadArgs*)arg;
171 VgPosixThreadArgs const arg_copy = *arg_ptr;
172 void* result;
173
174#if 0
175 pthread_mutex_lock(arg_ptr->mutex);
176 pthread_cond_signal(arg_ptr->cond);
177 pthread_mutex_unlock(arg_ptr->mutex);
178#else
179 arg_ptr->wrapper_started = 1;
180#endif
181
182 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
183 pthread_self(), 0, 0, 0, 0);
184 vg_set_joinable(pthread_self(),
185 arg_copy.detachstate == PTHREAD_CREATE_JOINABLE);
186 result = (arg_copy.start)(arg_copy.arg);
187 return result;
188 }
189}
190
191static void vg_set_main_thread_state(void)
192{
193 int res;
194
bart0d063002008-03-01 07:25:13 +0000195 vg_main_thread_pid = getpid();
196
sewardjaf44c822007-11-25 14:01:38 +0000197 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
198 0, 0, 0, 0, 0);
199
sewardjaf44c822007-11-25 14:01:38 +0000200 // Make sure that DRD knows about the main thread's POSIX thread ID.
201 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
202 pthread_self(), 0, 0, 0, 0);
203
204}
205
206// pthread_create
sewardj347eeba2008-01-21 14:19:07 +0000207PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
sewardjaf44c822007-11-25 14:01:38 +0000208 pthread_t *thread, const pthread_attr_t *attr,
209 void *(*start) (void *), void *arg)
210{
211 int ret;
212 OrigFn fn;
213 VgPosixThreadArgs vgargs;
214
215 VALGRIND_GET_ORIG_FN(fn);
216
217 if (vg_main_thread_state_is_set == 0)
218 {
219 vg_set_main_thread_state();
220 vg_main_thread_state_is_set = 1;
221 }
222 vg_start_suppression(&vgargs.wrapper_started,
223 sizeof(vgargs.wrapper_started));
224 vgargs.start = start;
225 vgargs.arg = arg;
226 vgargs.wrapper_started = 0;
227 vgargs.detachstate = PTHREAD_CREATE_JOINABLE;
228 if (attr)
229 {
230 if (pthread_attr_getdetachstate(attr, &vgargs.detachstate) != 0)
231 {
232 assert(0);
233 }
sewardjaf44c822007-11-25 14:01:38 +0000234 }
235 assert(vgargs.detachstate == PTHREAD_CREATE_JOINABLE
236 || vgargs.detachstate == PTHREAD_CREATE_DETACHED);
237#if 0
238 pthread_mutex_init(&vgargs.mutex, 0);
239 pthread_cond_init(&vgargs.cond, 0);
240 pthread_mutex_lock(&vgargs.mutex);
241#endif
sewardjaf44c822007-11-25 14:01:38 +0000242 CALL_FN_W_WWWW(ret, fn, thread, attr, vg_thread_wrapper, &vgargs);
sewardjaf44c822007-11-25 14:01:38 +0000243#if 0
244 pthread_cond_wait(&vgargs.cond, &vgargs.mutex);
245 pthread_mutex_unlock(&vgargs.mutex);
246 pthread_cond_destroy(&vgargs.cond);
247 pthread_mutex_destroy(&vgargs.mutex);
248#else
249 // Yes, you see it correctly, busy waiting ... The problem is that
250 // POSIX threads functions cannot be called here -- the functions defined
sewardj85642922008-01-14 11:54:56 +0000251 // in this file (drd_intercepts.c) would be called instead of those in
sewardjaf44c822007-11-25 14:01:38 +0000252 // libpthread.so. This loop is necessary because vgargs is allocated on the
253 // stack, and the created thread reads it.
sewardje0744f02007-12-01 02:09:50 +0000254 if (ret == 0)
sewardjaf44c822007-11-25 14:01:38 +0000255 {
sewardje0744f02007-12-01 02:09:50 +0000256 while (! vgargs.wrapper_started)
257 {
258 sched_yield();
259 }
sewardjaf44c822007-11-25 14:01:38 +0000260 }
261#endif
262 return ret;
263}
264
265// pthread_join
266PTH_FUNC(int, pthreadZujoin, // pthread_join
267 pthread_t pt_joinee, void **thread_return)
268{
269 int ret;
270 int res;
271 OrigFn fn;
272
273 VALGRIND_GET_ORIG_FN(fn);
274 CALL_FN_W_WW(ret, fn, pt_joinee, thread_return);
275 if (ret == 0)
276 {
277 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_JOIN,
278 pt_joinee, 0, 0, 0, 0);
279 }
280 return ret;
281}
282
283// pthread_detach
284PTH_FUNC(int, pthreadZudetach, pthread_t pt_thread)
285{
286 int ret;
287 OrigFn fn;
288 VALGRIND_GET_ORIG_FN(fn);
289 {
290 CALL_FN_W_W(ret, fn, pt_thread);
291 if (ret == 0)
292 {
293 vg_set_joinable(pt_thread, 0);
294 }
295 }
296 return ret;
297}
298
299// pthread_mutex_init
300PTH_FUNC(int, pthreadZumutexZuinit,
301 pthread_mutex_t *mutex,
302 const pthread_mutexattr_t* attr)
303{
304 int ret;
305 int res;
306 OrigFn fn;
bart5357fcb2008-02-27 15:46:00 +0000307 int mt = PTHREAD_MUTEX_DEFAULT;
sewardjaf44c822007-11-25 14:01:38 +0000308 VALGRIND_GET_ORIG_FN(fn);
bart5357fcb2008-02-27 15:46:00 +0000309 if (attr)
310 pthread_mutexattr_gettype(attr, &mt);
sewardjaf44c822007-11-25 14:01:38 +0000311 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
bart5357fcb2008-02-27 15:46:00 +0000312 mutex, sizeof(*mutex),
313 pthread_to_drd_mutex_type(mt), 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000314 CALL_FN_W_WW(ret, fn, mutex, attr);
315 return ret;
316}
317
318// pthread_mutex_destroy
319PTH_FUNC(int, pthreadZumutexZudestroy,
320 pthread_mutex_t *mutex)
321{
322 int ret;
323 int res;
324 OrigFn fn;
325 VALGRIND_GET_ORIG_FN(fn);
326 CALL_FN_W_W(ret, fn, mutex);
327 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
bart5357fcb2008-02-27 15:46:00 +0000328 mutex, mutex_type(mutex), 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000329 return ret;
330}
331
332// pthread_mutex_lock
333PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
334 pthread_mutex_t *mutex)
335{
336 int ret;
337 int res;
338 OrigFn fn;
339 VALGRIND_GET_ORIG_FN(fn);
340 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
bart5357fcb2008-02-27 15:46:00 +0000341 mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000342#if 1
343 // The only purpose of the system call below is to make drd work on AMD64
344 // systems. Without this system call, clients crash (SIGSEGV) in
345 // std::locale::locale().
346 write(1, "", 0);
347#endif
348 CALL_FN_W_W(ret, fn, mutex);
bart3b1ee452008-02-29 19:28:15 +0000349 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
bart00344642008-03-01 15:27:41 +0000350 mutex, ret == 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000351 return ret;
352}
353
354// pthread_mutex_trylock
355PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
356 pthread_mutex_t *mutex)
357{
358 int ret;
359 int res;
360 OrigFn fn;
361 VALGRIND_GET_ORIG_FN(fn);
bart00344642008-03-01 15:27:41 +0000362 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
363 mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000364 CALL_FN_W_W(ret, fn, mutex);
bart3b1ee452008-02-29 19:28:15 +0000365 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
bart00344642008-03-01 15:27:41 +0000366 mutex, ret == 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000367 return ret;
368}
369
sewardj85642922008-01-14 11:54:56 +0000370// pthread_mutex_timedlock
371PTH_FUNC(int, pthreadZumutexZutimedlock, // pthread_mutex_timedlock
372 pthread_mutex_t *mutex,
373 const struct timespec *abs_timeout)
374{
375 int ret;
376 int res;
377 OrigFn fn;
378 VALGRIND_GET_ORIG_FN(fn);
bart00344642008-03-01 15:27:41 +0000379 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
380 mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
sewardj85642922008-01-14 11:54:56 +0000381 CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
bart3b1ee452008-02-29 19:28:15 +0000382 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
bart00344642008-03-01 15:27:41 +0000383 mutex, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000384 return ret;
385}
386
sewardjaf44c822007-11-25 14:01:38 +0000387// pthread_mutex_unlock
388PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
389 pthread_mutex_t *mutex)
390{
391 int ret;
392 int res;
393 OrigFn fn;
394 VALGRIND_GET_ORIG_FN(fn);
395 VALGRIND_DO_CLIENT_REQUEST(res, -1,
396 VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK,
bart5357fcb2008-02-27 15:46:00 +0000397 mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000398 CALL_FN_W_W(ret, fn, mutex);
399 return ret;
400}
401
402// pthread_cond_init
sewardj347eeba2008-01-21 14:19:07 +0000403PTH_FUNC(int, pthreadZucondZuinitZa, // pthread_cond_init*
sewardjaf44c822007-11-25 14:01:38 +0000404 pthread_cond_t* cond,
405 const pthread_condattr_t* attr)
406{
407 int ret;
408 int res;
409 OrigFn fn;
410 VALGRIND_GET_ORIG_FN(fn);
bart72b751c2008-03-01 13:44:24 +0000411 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_INIT,
sewardjaf44c822007-11-25 14:01:38 +0000412 cond, sizeof(*cond), 0, 0, 0);
bart72b751c2008-03-01 13:44:24 +0000413 CALL_FN_W_WW(ret, fn, cond, attr);
sewardjaf44c822007-11-25 14:01:38 +0000414 return ret;
415}
416
417// pthread_cond_destroy
sewardj347eeba2008-01-21 14:19:07 +0000418PTH_FUNC(int, pthreadZucondZudestroyZa, // pthread_cond_destroy*
sewardjaf44c822007-11-25 14:01:38 +0000419 pthread_cond_t* cond)
420{
421 int ret;
422 int res;
423 OrigFn fn;
424 VALGRIND_GET_ORIG_FN(fn);
sewardjaf44c822007-11-25 14:01:38 +0000425 CALL_FN_W_W(ret, fn, cond);
bart72b751c2008-03-01 13:44:24 +0000426 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_DESTROY,
427 cond, 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000428 return ret;
429}
430
431// pthread_cond_wait
sewardj347eeba2008-01-21 14:19:07 +0000432PTH_FUNC(int, pthreadZucondZuwaitZa, // pthread_cond_wait*
sewardjaf44c822007-11-25 14:01:38 +0000433 pthread_cond_t *cond,
434 pthread_mutex_t *mutex)
435{
436 int ret;
437 int res;
438 OrigFn fn;
439 VALGRIND_GET_ORIG_FN(fn);
440 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_WAIT,
bart3b1ee452008-02-29 19:28:15 +0000441 cond, sizeof(*cond), mutex, mutex_type(mutex),
442 0);
sewardjaf44c822007-11-25 14:01:38 +0000443 CALL_FN_W_WW(ret, fn, cond, mutex);
444 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_WAIT,
bart00344642008-03-01 15:27:41 +0000445 cond, mutex, ret == 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000446 return ret;
447}
448
449// pthread_cond_timedwait
sewardj347eeba2008-01-21 14:19:07 +0000450PTH_FUNC(int, pthreadZucondZutimedwaitZa, // pthread_cond_timedwait*
sewardjaf44c822007-11-25 14:01:38 +0000451 pthread_cond_t *cond,
452 pthread_mutex_t *mutex,
453 const struct timespec* abstime)
454{
455 int ret;
456 int res;
457 OrigFn fn;
458 VALGRIND_GET_ORIG_FN(fn);
459 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_WAIT,
bart3b1ee452008-02-29 19:28:15 +0000460 cond, sizeof(*cond), mutex, mutex_type(mutex),
461 0);
sewardjaf44c822007-11-25 14:01:38 +0000462 CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
463 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_WAIT,
bart00344642008-03-01 15:27:41 +0000464 cond, mutex, ret == 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000465 return ret;
466}
467
468// pthread_cond_signal
sewardj347eeba2008-01-21 14:19:07 +0000469PTH_FUNC(int, pthreadZucondZusignalZa, // pthread_cond_signal*
sewardjaf44c822007-11-25 14:01:38 +0000470 pthread_cond_t* cond)
471{
472 int ret;
473 int res;
474 OrigFn fn;
475 VALGRIND_GET_ORIG_FN(fn);
476 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_SIGNAL,
477 cond, 0, 0, 0, 0);
478 CALL_FN_W_W(ret, fn, cond);
479 return ret;
480}
481
482// pthread_cond_broadcast
sewardj347eeba2008-01-21 14:19:07 +0000483PTH_FUNC(int, pthreadZucondZubroadcastZa, // pthread_cond_broadcast*
sewardjaf44c822007-11-25 14:01:38 +0000484 pthread_cond_t* cond)
485{
486 int ret;
487 int res;
488 OrigFn fn;
489 VALGRIND_GET_ORIG_FN(fn);
490 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_BROADCAST,
491 cond, 0, 0, 0, 0);
492 CALL_FN_W_W(ret, fn, cond);
493 return ret;
494}
495
496
497// pthread_spin_init
498PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
499 pthread_spinlock_t *spinlock,
500 int pshared)
501{
502 int ret;
503 int res;
504 OrigFn fn;
505 VALGRIND_GET_ORIG_FN(fn);
506 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000507 spinlock, sizeof(*spinlock),
508 mutex_type_spinlock, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000509 CALL_FN_W_WW(ret, fn, spinlock, pshared);
510 return ret;
511}
512
513// pthread_spin_destroy
514PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
515 pthread_spinlock_t *spinlock)
516{
517 int ret;
518 int res;
519 OrigFn fn;
520 VALGRIND_GET_ORIG_FN(fn);
521 CALL_FN_W_W(ret, fn, spinlock);
522 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
sewardj721ad7b2007-11-30 08:30:29 +0000523 spinlock, mutex_type_spinlock, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000524 return ret;
525}
526
527// pthread_spin_lock
528PTH_FUNC(int, pthreadZuspinZulock, // pthread_spin_lock
529 pthread_spinlock_t *spinlock)
530{
531 int ret;
532 int res;
533 OrigFn fn;
534 VALGRIND_GET_ORIG_FN(fn);
bart00344642008-03-01 15:27:41 +0000535 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
536 spinlock, sizeof(*spinlock), mutex_type_spinlock,
537 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000538 CALL_FN_W_W(ret, fn, spinlock);
bart3b1ee452008-02-29 19:28:15 +0000539 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
bart00344642008-03-01 15:27:41 +0000540 spinlock, ret == 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000541 return ret;
542}
543
544// pthread_spin_trylock
545PTH_FUNC(int, pthreadZuspinZutrylock, // pthread_spin_trylock
546 pthread_spinlock_t *spinlock)
547{
548 int ret;
549 int res;
550 OrigFn fn;
551 VALGRIND_GET_ORIG_FN(fn);
bart00344642008-03-01 15:27:41 +0000552 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
553 spinlock, sizeof(*spinlock), mutex_type_spinlock,
554 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000555 CALL_FN_W_W(ret, fn, spinlock);
bart3b1ee452008-02-29 19:28:15 +0000556 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
bart00344642008-03-01 15:27:41 +0000557 spinlock, ret == 0, 0, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000558 return ret;
559}
560
561// pthread_spin_unlock
562PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock
563 pthread_spinlock_t *spinlock)
564{
565 int ret;
566 int res;
567 OrigFn fn;
568 VALGRIND_GET_ORIG_FN(fn);
569 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SPIN_INIT_OR_UNLOCK,
sewardj721ad7b2007-11-30 08:30:29 +0000570 spinlock, sizeof(*spinlock),
571 mutex_type_spinlock, 0, 0);
sewardjaf44c822007-11-25 14:01:38 +0000572 CALL_FN_W_W(ret, fn, spinlock);
573 return ret;
574}
575
sewardj85642922008-01-14 11:54:56 +0000576// pthread_barrier_init
577PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
578 pthread_barrier_t* barrier,
579 const pthread_barrierattr_t* attr,
580 unsigned count)
581{
582 int ret;
583 int res;
584 OrigFn fn;
585 VALGRIND_GET_ORIG_FN(fn);
586 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__BARRIER_INIT,
587 barrier, sizeof(*barrier),
588 count, 0, 0);
589 CALL_FN_W_WWW(ret, fn, barrier, attr, count);
590 return ret;
591}
592
593// pthread_barrier_destroy
594PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
595 pthread_barrier_t* barrier)
596{
597 int ret;
598 int res;
599 OrigFn fn;
600 VALGRIND_GET_ORIG_FN(fn);
601 CALL_FN_W_W(ret, fn, barrier);
602 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__BARRIER_DESTROY,
603 barrier, 0, 0, 0, 0);
604 return ret;
605}
606
607// pthread_barrier_wait
608PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
609 pthread_barrier_t* barrier)
610{
611 int ret;
612 int res;
613 OrigFn fn;
614 VALGRIND_GET_ORIG_FN(fn);
615 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT,
616 barrier, 0, 0, 0, 0);
617 CALL_FN_W_W(ret, fn, barrier);
618 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
619 barrier,
620 ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
621 0, 0, 0);
622 return ret;
623}
624
625
626// From glibc 2.0 linuxthreads/sysdeps/pthread/cmpxchg/semaphorebits.h
627typedef struct { long int sem_status; } sem_t_glibc_2_0;
628
629// sem_init
bart00344642008-03-01 15:27:41 +0000630PTH_FUNC(int, semZuinitZAGLIBCZu2Zd0, // sem_init@GLIBC_2.0
sewardj85642922008-01-14 11:54:56 +0000631 sem_t_glibc_2_0 *sem,
632 int pshared,
633 unsigned int value)
634{
635 int ret;
636 int res;
637 OrigFn fn;
638 VALGRIND_GET_ORIG_FN(fn);
639 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
640 if (ret == 0)
641 {
642 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_INIT,
643 sem, sizeof(*sem),
644 pshared, value, 0);
645 }
646 return ret;
647}
648
bart00344642008-03-01 15:27:41 +0000649PTH_FUNC(int, semZuinitZa, // sem_init*
sewardj85642922008-01-14 11:54:56 +0000650 sem_t *sem,
651 int pshared,
652 unsigned int value)
653{
654 int ret;
655 int res;
656 OrigFn fn;
657 VALGRIND_GET_ORIG_FN(fn);
658 CALL_FN_W_WWW(ret, fn, sem, pshared, value);
659 if (ret == 0)
660 {
661 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_INIT,
662 sem, sizeof(*sem),
663 pshared, value, 0);
664 }
665 return ret;
666}
667
668// sem_destroy
bart00344642008-03-01 15:27:41 +0000669PTH_FUNC(int, semZudestroyZAGLIBCZu2Zd0, // sem_destroy@GLIBC_2.0
sewardj85642922008-01-14 11:54:56 +0000670 sem_t_glibc_2_0 *sem)
671{
672 int ret;
673 int res;
674 OrigFn fn;
675 VALGRIND_GET_ORIG_FN(fn);
676 CALL_FN_W_W(ret, fn, sem);
677 if (ret == 0)
678 {
679 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_DESTROY,
680 sem, 0, 0, 0, 0);
681 }
682 return ret;
683}
684
bart00344642008-03-01 15:27:41 +0000685PTH_FUNC(int, semZudestroyZa, // sem_destroy*
sewardj85642922008-01-14 11:54:56 +0000686 sem_t *sem)
687{
688 int ret;
689 int res;
690 OrigFn fn;
691 VALGRIND_GET_ORIG_FN(fn);
692 CALL_FN_W_W(ret, fn, sem);
693 if (ret == 0)
694 {
695 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SEM_DESTROY,
696 sem, 0, 0, 0, 0);
697 }
698 return ret;
699}
700
701// sem_wait
bart00344642008-03-01 15:27:41 +0000702PTH_FUNC(int, semZuwaitZAGLIBCZu2Zd0, // sem_wait@GLIBC_2.0
sewardj85642922008-01-14 11:54:56 +0000703 sem_t_glibc_2_0 *sem)
704{
705 int ret;
706 int res;
707 OrigFn fn;
708 VALGRIND_GET_ORIG_FN(fn);
bart28230a32008-02-29 17:27:03 +0000709 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
710 sem, 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000711 CALL_FN_W_W(ret, fn, sem);
bart28230a32008-02-29 17:27:03 +0000712 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
713 sem, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000714 return ret;
715}
716
bart28230a32008-02-29 17:27:03 +0000717// sem_wait
bart00344642008-03-01 15:27:41 +0000718PTH_FUNC(int, semZuwaitZa, // sem_wait*
sewardj85642922008-01-14 11:54:56 +0000719 sem_t *sem)
720{
721 int ret;
722 int res;
723 OrigFn fn;
724 VALGRIND_GET_ORIG_FN(fn);
bart28230a32008-02-29 17:27:03 +0000725 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
726 sem, 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000727 CALL_FN_W_W(ret, fn, sem);
bart28230a32008-02-29 17:27:03 +0000728 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
729 sem, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000730 return ret;
731}
732
733// sem_trywait
bart00344642008-03-01 15:27:41 +0000734PTH_FUNC(int, semZutrywaitZAGLIBCZu2Zd0, // sem_trywait@GLIBC_2.0
sewardj85642922008-01-14 11:54:56 +0000735 sem_t_glibc_2_0 *sem)
736{
737 int ret;
738 int res;
739 OrigFn fn;
740 VALGRIND_GET_ORIG_FN(fn);
bart28230a32008-02-29 17:27:03 +0000741 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
742 sem, 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000743 CALL_FN_W_W(ret, fn, sem);
bart28230a32008-02-29 17:27:03 +0000744 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
745 sem, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000746 return ret;
747}
748
bart00344642008-03-01 15:27:41 +0000749PTH_FUNC(int, semZutrywaitZa, // sem_trywait*
sewardj85642922008-01-14 11:54:56 +0000750 sem_t *sem)
751{
752 int ret;
753 int res;
754 OrigFn fn;
755 VALGRIND_GET_ORIG_FN(fn);
bart28230a32008-02-29 17:27:03 +0000756 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
757 sem, 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000758 CALL_FN_W_W(ret, fn, sem);
bart28230a32008-02-29 17:27:03 +0000759 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
760 sem, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000761 return ret;
762}
763
764// sem_timedwait
bart00344642008-03-01 15:27:41 +0000765PTH_FUNC(int, semZutimedwait, // sem_timedwait
sewardj85642922008-01-14 11:54:56 +0000766 sem_t *sem, const struct timespec *abs_timeout)
767{
768 int ret;
769 int res;
770 OrigFn fn;
771 VALGRIND_GET_ORIG_FN(fn);
bart28230a32008-02-29 17:27:03 +0000772 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT,
773 sem, 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000774 CALL_FN_W_WW(ret, fn, sem, abs_timeout);
bart28230a32008-02-29 17:27:03 +0000775 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT,
776 sem, ret == 0, 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000777 return ret;
778}
779
780// sem_post
bart00344642008-03-01 15:27:41 +0000781PTH_FUNC(int, semZupostZAGLIBCZu2Zd0, // sem_post@GLIBC_2.0
sewardj85642922008-01-14 11:54:56 +0000782 sem_t_glibc_2_0 *sem)
783{
784 int ret;
785 int res;
786 OrigFn fn;
787 VALGRIND_GET_ORIG_FN(fn);
788 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
789 sem, sizeof(*sem), 0, 0, 0);
790 CALL_FN_W_W(ret, fn, sem);
sewardjc0be9252008-02-11 11:00:51 +0000791 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
792 sem, sizeof(*sem), ret == 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000793 return ret;
794}
795
bart00344642008-03-01 15:27:41 +0000796// sem_post
797PTH_FUNC(int, semZupostZa, // sem_post*
sewardj85642922008-01-14 11:54:56 +0000798 sem_t *sem)
799{
800 int ret;
801 int res;
802 OrigFn fn;
803 VALGRIND_GET_ORIG_FN(fn);
804 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST,
805 sem, sizeof(*sem), 0, 0, 0);
806 CALL_FN_W_W(ret, fn, sem);
sewardje3b57aa2008-01-18 07:42:01 +0000807 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST,
808 sem, sizeof(*sem), ret == 0, 0, 0);
sewardj85642922008-01-14 11:54:56 +0000809 return ret;
810}
811
bart00344642008-03-01 15:27:41 +0000812// pthread_rwlock_init
813PTH_FUNC(int,
814 pthreadZurwlockZuinitZa, // pthread_rwlock_init*
815 pthread_rwlock_t* rwlock,
816 const pthread_rwlockattr_t* attr)
817{
818 int ret;
819 int res;
820 OrigFn fn;
821 VALGRIND_GET_ORIG_FN(fn);
822 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_INIT,
823 rwlock, sizeof(*rwlock), 0, 0, 0);
824 CALL_FN_W_WW(ret, fn, rwlock, attr);
825 return ret;
826}
827
828// pthread_rwlock_destroy
829PTH_FUNC(int,
830 pthreadZurwlockZudestroyZa, // pthread_rwlock_destroy*
831 pthread_rwlock_t* rwlock)
832{
833 int ret;
834 int res;
835 OrigFn fn;
836 VALGRIND_GET_ORIG_FN(fn);
837 CALL_FN_W_W(ret, fn, rwlock);
838 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_DESTROY,
839 rwlock, 0, 0, 0, 0);
840 return ret;
841}
842
843// pthread_rwlock_rdlock
844PTH_FUNC(int,
845 pthreadZurwlockZurdlockZa, // pthread_rwlock_rdlock*
846 pthread_rwlock_t* rwlock)
847{
848 int ret;
849 int res;
850 OrigFn fn;
851 VALGRIND_GET_ORIG_FN(fn);
852 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
853 rwlock, sizeof(*rwlock), 0, 0, 0);
854 CALL_FN_W_W(ret, fn, rwlock);
855 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
856 rwlock, ret == 0, 0, 0, 0);
857 return ret;
858}
859
860// pthread_rwlock_wrlock
861PTH_FUNC(int,
862 pthreadZurwlockZuwrlockZa, // pthread_rwlock_wrlock*
863 pthread_rwlock_t* rwlock)
864{
865 int ret;
866 int res;
867 OrigFn fn;
868 VALGRIND_GET_ORIG_FN(fn);
869 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
870 rwlock, sizeof(*rwlock), 0, 0, 0);
871 CALL_FN_W_W(ret, fn, rwlock);
872 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
873 rwlock, ret == 0, 0, 0, 0);
874 return ret;
875}
876
877// pthread_rwlock_timedrdlock
878PTH_FUNC(int,
879 pthreadZurwlockZutimedrdlockZa, // pthread_rwlock_timedrdlock*
880 pthread_rwlock_t* rwlock)
881{
882 int ret;
883 int res;
884 OrigFn fn;
885 VALGRIND_GET_ORIG_FN(fn);
886 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
887 rwlock, sizeof(*rwlock), 0, 0, 0);
888 CALL_FN_W_W(ret, fn, rwlock);
889 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
890 rwlock, ret == 0, 0, 0, 0);
891 return ret;
892}
893
894// pthread_rwlock_timedwrlock
895PTH_FUNC(int,
896 pthreadZurwlockZutimedwrlockZa, // pthread_rwlock_timedwrlock*
897 pthread_rwlock_t* rwlock)
898{
899 int ret;
900 int res;
901 OrigFn fn;
902 VALGRIND_GET_ORIG_FN(fn);
903 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
904 rwlock, sizeof(*rwlock), 0, 0, 0);
905 CALL_FN_W_W(ret, fn, rwlock);
906 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
907 rwlock, ret == 0, 0, 0, 0);
908 return ret;
909}
910
911// pthread_rwlock_tryrdlock
912PTH_FUNC(int,
913 pthreadZurwlockZutryrdlockZa, // pthread_rwlock_tryrdlock*
914 pthread_rwlock_t* rwlock)
915{
916 int ret;
917 int res;
918 OrigFn fn;
919 VALGRIND_GET_ORIG_FN(fn);
920 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK,
921 rwlock, sizeof(*rwlock), 0, 0, 0);
922 CALL_FN_W_W(ret, fn, rwlock);
923 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK,
924 rwlock, ret == 0, 0, 0, 0);
925 return ret;
926}
927
928// pthread_rwlock_trywrlock
929PTH_FUNC(int,
930 pthreadZurwlockZutrywrlockZa, // pthread_rwlock_trywrlock*
931 pthread_rwlock_t* rwlock)
932{
933 int ret;
934 int res;
935 OrigFn fn;
936 VALGRIND_GET_ORIG_FN(fn);
937 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK,
938 rwlock, sizeof(*rwlock), 0, 0, 0);
939 CALL_FN_W_W(ret, fn, rwlock);
940 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK,
941 rwlock, ret == 0, 0, 0, 0);
942 return ret;
943}
944
945// pthread_rwlock_unlock
946PTH_FUNC(int,
947 pthreadZurwlockZuunlockZa, // pthread_rwlock_unlock*
948 pthread_rwlock_t* rwlock)
949{
950 int ret;
951 int res;
952 OrigFn fn;
953 VALGRIND_GET_ORIG_FN(fn);
954 CALL_FN_W_W(ret, fn, rwlock);
bart777f7fe2008-03-02 17:43:18 +0000955 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_UNLOCK,
bart00344642008-03-01 15:27:41 +0000956 rwlock, ret == 0, 0, 0, 0);
957 return ret;
958}
959
sewardj85642922008-01-14 11:54:56 +0000960
sewardjaf44c822007-11-25 14:01:38 +0000961/*
962 * Local variables:
963 * c-basic-offset: 3
964 * End:
965 */