blob: 49e1f11055729e5482a21ea93c9eb98bc9be8027 [file] [log] [blame]
sewardj85642922008-01-14 11:54:56 +00001/*
bart86562bd2009-02-16 19:43:56 +00002 This file is part of drd, a thread error detector.
sewardj85642922008-01-14 11:54:56 +00003
sewardj03f8d3f2012-08-05 15:46:46 +00004 Copyright (C) 2006-2012 Bart Van Assche <bvanassche@acm.org>.
sewardj85642922008-01-14 11:54:56 +00005
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307, USA.
20
21 The GNU General Public License is contained in the file COPYING.
22*/
23
24
bart09dc13f2009-02-14 15:13:31 +000025#include "drd_barrier.h"
sewardjaf44c822007-11-25 14:01:38 +000026#include "drd_clientreq.h"
27#include "drd_cond.h"
bart6c7c76e2009-05-01 12:23:47 +000028#include "drd_error.h"
bart62cc2322010-03-07 10:54:21 +000029#include "drd_hb.h"
bart83c17802009-03-10 09:26:07 +000030#include "drd_load_store.h"
bart6c7c76e2009-05-01 12:23:47 +000031#include "drd_malloc_wrappers.h"
sewardjaf44c822007-11-25 14:01:38 +000032#include "drd_mutex.h"
bart09dc13f2009-02-14 15:13:31 +000033#include "drd_rwlock.h"
sewardj85642922008-01-14 11:54:56 +000034#include "drd_semaphore.h"
sewardjaf44c822007-11-25 14:01:38 +000035#include "drd_suppression.h" // drd_start_suppression()
36#include "drd_thread.h"
sewardjaf44c822007-11-25 14:01:38 +000037#include "pub_tool_basics.h" // Bool
bartb93846e2008-04-16 18:17:12 +000038#include "pub_tool_debuginfo.h" // VG_(describe_IP)()
sewardjaf44c822007-11-25 14:01:38 +000039#include "pub_tool_libcassert.h"
40#include "pub_tool_libcassert.h" // tl_assert()
41#include "pub_tool_libcprint.h" // VG_(message)()
42#include "pub_tool_machine.h" // VG_(get_SP)()
43#include "pub_tool_threadstate.h"
44#include "pub_tool_tooliface.h" // VG_(needs_...)()
45
46
bart7d5f5232011-03-13 09:08:10 +000047/* Global variables. */
48
49Bool DRD_(g_free_is_write);
50
51
bart09dc13f2009-02-14 15:13:31 +000052/* Local function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000053
bart6c7c76e2009-05-01 12:23:47 +000054static Bool handle_client_request(ThreadId vg_tid, UWord* arg, UWord* ret);
sewardjaf44c822007-11-25 14:01:38 +000055
sewardjaf44c822007-11-25 14:01:38 +000056
bart03ffb2e2009-02-15 10:36:32 +000057/* Function definitions. */
58
bart09dc13f2009-02-14 15:13:31 +000059/**
bart03ffb2e2009-02-15 10:36:32 +000060 * Tell the Valgrind core the address of the DRD function that processes
61 * client requests. Must be called before any client code is run.
bartf1ac71a2008-04-04 16:54:37 +000062 */
bart03ffb2e2009-02-15 10:36:32 +000063void DRD_(clientreq_init)(void)
bartf1ac71a2008-04-04 16:54:37 +000064{
bart6c7c76e2009-05-01 12:23:47 +000065 VG_(needs_client_requests)(handle_client_request);
bartf1ac71a2008-04-04 16:54:37 +000066}
67
bart09dc13f2009-02-14 15:13:31 +000068/**
69 * DRD's handler for Valgrind client requests. The code below handles both
70 * DRD's public and tool-internal client requests.
71 */
sewardj5db15402012-06-07 09:13:21 +000072#if defined(VGP_mips32_linux)
73 /* There is a cse related issue in gcc for MIPS. Optimization level
74 has to be lowered, so cse related optimizations are not
75 included. */
76 __attribute__((optimize("O1")))
77#endif
bart6c7c76e2009-05-01 12:23:47 +000078static Bool handle_client_request(ThreadId vg_tid, UWord* arg, UWord* ret)
sewardjaf44c822007-11-25 14:01:38 +000079{
bartbedfd232009-03-26 19:07:15 +000080 UWord result = 0;
81 const DrdThreadId drd_tid = DRD_(thread_get_running_tid)();
bart0268dfa2008-03-11 20:10:21 +000082
bartbedfd232009-03-26 19:07:15 +000083 tl_assert(vg_tid == VG_(get_running_tid()));
84 tl_assert(DRD_(VgThreadIdToDrdThreadId)(vg_tid) == drd_tid);
sewardjaf44c822007-11-25 14:01:38 +000085
bartbedfd232009-03-26 19:07:15 +000086 switch (arg[0])
87 {
bart6c7c76e2009-05-01 12:23:47 +000088 case VG_USERREQ__MALLOCLIKE_BLOCK:
bart7d5f5232011-03-13 09:08:10 +000089 if (DRD_(g_free_is_write)) {
90 GenericErrInfo GEI = {
91 .tid = DRD_(thread_get_running_tid)(),
92 .addr = 0,
93 };
94 VG_(maybe_record_error)(vg_tid,
95 GenericErr,
96 VG_(get_IP)(vg_tid),
97 "--free-is-write=yes is incompatible with"
98 " custom memory allocator client requests",
99 &GEI);
100 }
bart6c7c76e2009-05-01 12:23:47 +0000101 if (arg[1])
102 DRD_(malloclike_block)(vg_tid, arg[1]/*addr*/, arg[2]/*size*/);
103 break;
104
bart91347382011-03-25 20:07:25 +0000105 case VG_USERREQ__RESIZEINPLACE_BLOCK:
106 if (!DRD_(freelike_block)(vg_tid, arg[1]/*addr*/, False))
107 {
108 GenericErrInfo GEI = {
109 .tid = DRD_(thread_get_running_tid)(),
110 .addr = 0,
111 };
112 VG_(maybe_record_error)(vg_tid,
113 GenericErr,
114 VG_(get_IP)(vg_tid),
115 "Invalid VG_USERREQ__RESIZEINPLACE_BLOCK request",
116 &GEI);
117 }
118 DRD_(malloclike_block)(vg_tid, arg[1]/*addr*/, arg[3]/*newSize*/);
119 break;
120
bart6c7c76e2009-05-01 12:23:47 +0000121 case VG_USERREQ__FREELIKE_BLOCK:
bartfc08a532011-03-12 12:43:39 +0000122 if (arg[1] && ! DRD_(freelike_block)(vg_tid, arg[1]/*addr*/, False))
bart6c7c76e2009-05-01 12:23:47 +0000123 {
bart62cc2322010-03-07 10:54:21 +0000124 GenericErrInfo GEI = {
125 .tid = DRD_(thread_get_running_tid)(),
126 .addr = 0,
127 };
bartb48bde22009-07-31 08:26:17 +0000128 VG_(maybe_record_error)(vg_tid,
129 GenericErr,
130 VG_(get_IP)(vg_tid),
131 "Invalid VG_USERREQ__FREELIKE_BLOCK request",
132 &GEI);
bart6c7c76e2009-05-01 12:23:47 +0000133 }
134 break;
135
bartbedfd232009-03-26 19:07:15 +0000136 case VG_USERREQ__DRD_GET_VALGRIND_THREAD_ID:
137 result = vg_tid;
138 break;
sewardjaf44c822007-11-25 14:01:38 +0000139
bartbedfd232009-03-26 19:07:15 +0000140 case VG_USERREQ__DRD_GET_DRD_THREAD_ID:
141 result = drd_tid;
142 break;
bart5f57be92008-07-01 08:48:56 +0000143
bartd45d9952009-05-31 18:53:54 +0000144 case VG_USERREQ__DRD_SET_THREAD_NAME:
145 DRD_(thread_set_name)(drd_tid, (const char*)arg[1]);
146 break;
147
bartbedfd232009-03-26 19:07:15 +0000148 case VG_USERREQ__DRD_START_SUPPRESSION:
bartd3a300d2010-08-29 16:20:54 +0000149 /*_VG_USERREQ__HG_ARANGE_MAKE_UNTRACKED*/
150 case VG_USERREQ_TOOL_BASE('H','G') + 256 + 39:
bartbedfd232009-03-26 19:07:15 +0000151 DRD_(start_suppression)(arg[1], arg[1] + arg[2], "client");
152 break;
sewardjaf44c822007-11-25 14:01:38 +0000153
bartbedfd232009-03-26 19:07:15 +0000154 case VG_USERREQ__DRD_FINISH_SUPPRESSION:
bartd3a300d2010-08-29 16:20:54 +0000155 /*_VG_USERREQ__HG_ARANGE_MAKE_TRACKED*/
156 case VG_USERREQ_TOOL_BASE('H','G') + 256 + 40:
bartbedfd232009-03-26 19:07:15 +0000157 DRD_(finish_suppression)(arg[1], arg[1] + arg[2]);
158 break;
sewardjaf44c822007-11-25 14:01:38 +0000159
bartd45d9952009-05-31 18:53:54 +0000160 case VG_USERREQ__DRD_ANNOTATE_HAPPENS_BEFORE:
bart62cc2322010-03-07 10:54:21 +0000161 DRD_(hb_happens_before)(drd_tid, arg[1]);
bartd45d9952009-05-31 18:53:54 +0000162 break;
163
164 case VG_USERREQ__DRD_ANNOTATE_HAPPENS_AFTER:
bart62cc2322010-03-07 10:54:21 +0000165 DRD_(hb_happens_after)(drd_tid, arg[1]);
166 break;
167
bart66f196d2009-08-15 10:50:35 +0000168 case VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE:
169 if (arg[1])
bartd45d9952009-05-31 18:53:54 +0000170 {
171 struct mutex_info* const mutex_p = DRD_(mutex_get)(arg[1]);
172 if (mutex_p && mutex_p->mutex_type == mutex_type_spinlock)
173 break;
174 }
bart66f196d2009-08-15 10:50:35 +0000175 DRD_(rwlock_pre_init)(arg[1], user_rwlock);
176 break;
177
178 case VG_USERREQ__DRD_ANNOTATE_RWLOCK_DESTROY:
179 if (arg[1])
bartd45d9952009-05-31 18:53:54 +0000180 {
bart66f196d2009-08-15 10:50:35 +0000181 struct mutex_info* const mutex_p = DRD_(mutex_get)(arg[1]);
182 if (mutex_p && mutex_p->mutex_type == mutex_type_spinlock)
183 break;
bartd45d9952009-05-31 18:53:54 +0000184 }
bart66f196d2009-08-15 10:50:35 +0000185 DRD_(rwlock_post_destroy)(arg[1], user_rwlock);
186 break;
187
188 case VG_USERREQ__DRD_ANNOTATE_RWLOCK_ACQUIRED:
189 if (arg[1])
190 {
191 struct mutex_info* const mutex_p = DRD_(mutex_get)(arg[1]);
192 if (mutex_p && mutex_p->mutex_type == mutex_type_spinlock)
193 break;
194 }
195 tl_assert(arg[2] == !! arg[2]);
196 if (arg[2])
197 {
198 DRD_(rwlock_pre_wrlock)(arg[1], user_rwlock);
199 DRD_(rwlock_post_wrlock)(arg[1], user_rwlock, True);
200 }
201 else
202 {
203 DRD_(rwlock_pre_rdlock)(arg[1], user_rwlock);
204 DRD_(rwlock_post_rdlock)(arg[1], user_rwlock, True);
205 }
206 break;
207
208 case VG_USERREQ__DRD_ANNOTATE_RWLOCK_RELEASED:
209 if (arg[1])
210 {
211 struct mutex_info* const mutex_p = DRD_(mutex_get)(arg[1]);
212 if (mutex_p && mutex_p->mutex_type == mutex_type_spinlock)
213 break;
214 }
215 tl_assert(arg[2] == !! arg[2]);
216 DRD_(rwlock_pre_unlock)(arg[1], user_rwlock);
bartd45d9952009-05-31 18:53:54 +0000217 break;
218
bart850f1992010-05-29 18:43:21 +0000219 case VG_USERREQ__SET_PTHREAD_COND_INITIALIZER:
220 DRD_(pthread_cond_initializer) = (Addr)arg[1];
221 DRD_(pthread_cond_initializer_size) = arg[2];
222 break;
223
bartbedfd232009-03-26 19:07:15 +0000224 case VG_USERREQ__DRD_START_NEW_SEGMENT:
225 DRD_(thread_new_segment)(DRD_(PtThreadIdToDrdThreadId)(arg[1]));
226 break;
sewardjaf44c822007-11-25 14:01:38 +0000227
bartbedfd232009-03-26 19:07:15 +0000228 case VG_USERREQ__DRD_START_TRACE_ADDR:
bart41a378a2012-01-24 18:39:29 +0000229 DRD_(start_tracing_address_range)(arg[1], arg[1] + arg[2], False);
bartbedfd232009-03-26 19:07:15 +0000230 break;
bart005dc972008-03-29 14:42:59 +0000231
bartbedfd232009-03-26 19:07:15 +0000232 case VG_USERREQ__DRD_STOP_TRACE_ADDR:
233 DRD_(stop_tracing_address_range)(arg[1], arg[1] + arg[2]);
234 break;
bart5bd9f2d2008-03-03 20:31:58 +0000235
bartd45d9952009-05-31 18:53:54 +0000236 case VG_USERREQ__DRD_RECORD_LOADS:
237 DRD_(thread_set_record_loads)(drd_tid, arg[1]);
bartbedfd232009-03-26 19:07:15 +0000238 break;
bartbf3a60c2008-04-04 19:10:21 +0000239
bartd45d9952009-05-31 18:53:54 +0000240 case VG_USERREQ__DRD_RECORD_STORES:
241 DRD_(thread_set_record_stores)(drd_tid, arg[1]);
bartbedfd232009-03-26 19:07:15 +0000242 break;
bartbf3a60c2008-04-04 19:10:21 +0000243
bartbedfd232009-03-26 19:07:15 +0000244 case VG_USERREQ__SET_PTHREADID:
245 // pthread_self() returns 0 for programs not linked with libpthread.so.
246 if (arg[1] != INVALID_POSIX_THREADID)
247 DRD_(thread_set_pthreadid)(drd_tid, arg[1]);
248 break;
sewardjaf44c822007-11-25 14:01:38 +0000249
bartbedfd232009-03-26 19:07:15 +0000250 case VG_USERREQ__SET_JOINABLE:
bart5668d4e2011-03-09 17:53:28 +0000251 {
252 const DrdThreadId drd_joinable = DRD_(PtThreadIdToDrdThreadId)(arg[1]);
253 if (drd_joinable != DRD_INVALID_THREADID)
254 DRD_(thread_set_joinable)(drd_joinable, (Bool)arg[2]);
255 else {
256 InvalidThreadIdInfo ITI = { DRD_(thread_get_running_tid)(), arg[1] };
257 VG_(maybe_record_error)(vg_tid,
258 InvalidThreadId,
259 VG_(get_IP)(vg_tid),
260 "pthread_detach(): invalid thread ID",
261 &ITI);
262 }
bartbedfd232009-03-26 19:07:15 +0000263 break;
bart5668d4e2011-03-09 17:53:28 +0000264 }
sewardjaf44c822007-11-25 14:01:38 +0000265
bartdd75cdf2009-07-24 08:20:10 +0000266 case VG_USERREQ__ENTERING_PTHREAD_CREATE:
267 DRD_(thread_entering_pthread_create)(drd_tid);
268 break;
269
270 case VG_USERREQ__LEFT_PTHREAD_CREATE:
271 DRD_(thread_left_pthread_create)(drd_tid);
272 break;
273
bartbedfd232009-03-26 19:07:15 +0000274 case VG_USERREQ__POST_THREAD_JOIN:
bartb48bde22009-07-31 08:26:17 +0000275 {
276 const DrdThreadId thread_to_join = DRD_(PtThreadIdToDrdThreadId)(arg[1]);
277 if (thread_to_join == DRD_INVALID_THREADID)
278 {
279 InvalidThreadIdInfo ITI = { DRD_(thread_get_running_tid)(), arg[1] };
280 VG_(maybe_record_error)(vg_tid,
281 InvalidThreadId,
282 VG_(get_IP)(vg_tid),
283 "pthread_join(): invalid thread ID",
284 &ITI);
285 }
286 else
287 {
288 DRD_(thread_post_join)(drd_tid, thread_to_join);
289 }
bartbedfd232009-03-26 19:07:15 +0000290 break;
bartb48bde22009-07-31 08:26:17 +0000291 }
sewardjaf44c822007-11-25 14:01:38 +0000292
bartbedfd232009-03-26 19:07:15 +0000293 case VG_USERREQ__PRE_THREAD_CANCEL:
bartb48bde22009-07-31 08:26:17 +0000294 {
295 const DrdThreadId thread_to_cancel =DRD_(PtThreadIdToDrdThreadId)(arg[1]);
296 if (thread_to_cancel == DRD_INVALID_THREADID)
297 {
298 InvalidThreadIdInfo ITI = { DRD_(thread_get_running_tid)(), arg[1] };
299 VG_(maybe_record_error)(vg_tid,
300 InvalidThreadId,
301 VG_(get_IP)(vg_tid),
302 "pthread_cancel(): invalid thread ID",
303 &ITI);
304 }
305 else
306 {
307 DRD_(thread_pre_cancel)(thread_to_cancel);
308 }
bartbedfd232009-03-26 19:07:15 +0000309 break;
bartb48bde22009-07-31 08:26:17 +0000310 }
bart0f099cd2008-09-27 12:36:48 +0000311
bartbedfd232009-03-26 19:07:15 +0000312 case VG_USERREQ__POST_THREAD_CANCEL:
bartbedfd232009-03-26 19:07:15 +0000313 break;
bart0f099cd2008-09-27 12:36:48 +0000314
bartbedfd232009-03-26 19:07:15 +0000315 case VG_USERREQ__PRE_MUTEX_INIT:
316 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
317 DRD_(mutex_init)(arg[1], arg[2]);
318 break;
bart0268dfa2008-03-11 20:10:21 +0000319
bartbedfd232009-03-26 19:07:15 +0000320 case VG_USERREQ__POST_MUTEX_INIT:
321 DRD_(thread_leave_synchr)(drd_tid);
322 break;
bart0268dfa2008-03-11 20:10:21 +0000323
bartbedfd232009-03-26 19:07:15 +0000324 case VG_USERREQ__PRE_MUTEX_DESTROY:
325 DRD_(thread_enter_synchr)(drd_tid);
326 break;
sewardjaf44c822007-11-25 14:01:38 +0000327
bartbedfd232009-03-26 19:07:15 +0000328 case VG_USERREQ__POST_MUTEX_DESTROY:
329 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
330 DRD_(mutex_post_destroy)(arg[1]);
331 break;
sewardjaf44c822007-11-25 14:01:38 +0000332
bartbedfd232009-03-26 19:07:15 +0000333 case VG_USERREQ__PRE_MUTEX_LOCK:
334 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
335 DRD_(mutex_pre_lock)(arg[1], arg[2], arg[3]);
336 break;
sewardjaf44c822007-11-25 14:01:38 +0000337
bartbedfd232009-03-26 19:07:15 +0000338 case VG_USERREQ__POST_MUTEX_LOCK:
339 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
340 DRD_(mutex_post_lock)(arg[1], arg[2], False/*post_cond_wait*/);
341 break;
sewardjaf44c822007-11-25 14:01:38 +0000342
bartbedfd232009-03-26 19:07:15 +0000343 case VG_USERREQ__PRE_MUTEX_UNLOCK:
344 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
345 DRD_(mutex_unlock)(arg[1], arg[2]);
346 break;
bart0268dfa2008-03-11 20:10:21 +0000347
bartbedfd232009-03-26 19:07:15 +0000348 case VG_USERREQ__POST_MUTEX_UNLOCK:
349 DRD_(thread_leave_synchr)(drd_tid);
350 break;
sewardjaf44c822007-11-25 14:01:38 +0000351
bartbedfd232009-03-26 19:07:15 +0000352 case VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK:
353 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
354 DRD_(spinlock_init_or_unlock)(arg[1]);
355 break;
bartf4f05812008-07-07 08:10:56 +0000356
bartbedfd232009-03-26 19:07:15 +0000357 case VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK:
358 DRD_(thread_leave_synchr)(drd_tid);
359 break;
sewardjaf44c822007-11-25 14:01:38 +0000360
bartbedfd232009-03-26 19:07:15 +0000361 case VG_USERREQ__PRE_COND_INIT:
362 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
363 DRD_(cond_pre_init)(arg[1]);
364 break;
bart3f4623e2008-07-07 16:53:07 +0000365
bartbedfd232009-03-26 19:07:15 +0000366 case VG_USERREQ__POST_COND_INIT:
367 DRD_(thread_leave_synchr)(drd_tid);
368 break;
bart3f4623e2008-07-07 16:53:07 +0000369
bartbedfd232009-03-26 19:07:15 +0000370 case VG_USERREQ__PRE_COND_DESTROY:
371 DRD_(thread_enter_synchr)(drd_tid);
372 break;
sewardjaf44c822007-11-25 14:01:38 +0000373
bartbedfd232009-03-26 19:07:15 +0000374 case VG_USERREQ__POST_COND_DESTROY:
375 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
376 DRD_(cond_post_destroy)(arg[1]);
377 break;
sewardjaf44c822007-11-25 14:01:38 +0000378
bartbedfd232009-03-26 19:07:15 +0000379 case VG_USERREQ__PRE_COND_WAIT:
380 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
381 {
382 const Addr cond = arg[1];
383 const Addr mutex = arg[2];
384 const MutexT mutex_type = arg[3];
385 DRD_(mutex_unlock)(mutex, mutex_type);
386 DRD_(cond_pre_wait)(cond, mutex);
387 }
388 break;
sewardjaf44c822007-11-25 14:01:38 +0000389
bartbedfd232009-03-26 19:07:15 +0000390 case VG_USERREQ__POST_COND_WAIT:
391 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
392 {
393 const Addr cond = arg[1];
394 const Addr mutex = arg[2];
395 const Bool took_lock = arg[3];
396 DRD_(cond_post_wait)(cond);
397 DRD_(mutex_post_lock)(mutex, took_lock, True);
398 }
399 break;
sewardjaf44c822007-11-25 14:01:38 +0000400
bartbedfd232009-03-26 19:07:15 +0000401 case VG_USERREQ__PRE_COND_SIGNAL:
402 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
403 DRD_(cond_pre_signal)(arg[1]);
404 break;
bart3f4623e2008-07-07 16:53:07 +0000405
bartbedfd232009-03-26 19:07:15 +0000406 case VG_USERREQ__POST_COND_SIGNAL:
407 DRD_(thread_leave_synchr)(drd_tid);
408 break;
sewardjaf44c822007-11-25 14:01:38 +0000409
bartbedfd232009-03-26 19:07:15 +0000410 case VG_USERREQ__PRE_COND_BROADCAST:
411 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
412 DRD_(cond_pre_broadcast)(arg[1]);
413 break;
bart3f4623e2008-07-07 16:53:07 +0000414
bartbedfd232009-03-26 19:07:15 +0000415 case VG_USERREQ__POST_COND_BROADCAST:
416 DRD_(thread_leave_synchr)(drd_tid);
417 break;
sewardjaf44c822007-11-25 14:01:38 +0000418
bartbedfd232009-03-26 19:07:15 +0000419 case VG_USERREQ__PRE_SEM_INIT:
420 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
421 DRD_(semaphore_init)(arg[1], arg[2], arg[3]);
422 break;
sewardj85642922008-01-14 11:54:56 +0000423
bartbedfd232009-03-26 19:07:15 +0000424 case VG_USERREQ__POST_SEM_INIT:
425 DRD_(thread_leave_synchr)(drd_tid);
426 break;
bart0268dfa2008-03-11 20:10:21 +0000427
bartbedfd232009-03-26 19:07:15 +0000428 case VG_USERREQ__PRE_SEM_DESTROY:
429 DRD_(thread_enter_synchr)(drd_tid);
430 break;
bart0268dfa2008-03-11 20:10:21 +0000431
bartbedfd232009-03-26 19:07:15 +0000432 case VG_USERREQ__POST_SEM_DESTROY:
433 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
434 DRD_(semaphore_destroy)(arg[1]);
435 break;
sewardj85642922008-01-14 11:54:56 +0000436
bart25f9f542009-07-23 16:31:39 +0000437 case VG_USERREQ__PRE_SEM_OPEN:
438 DRD_(thread_enter_synchr)(drd_tid);
439 break;
440
441 case VG_USERREQ__POST_SEM_OPEN:
442 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
443 DRD_(semaphore_open)(arg[1], (Char*)arg[2], arg[3], arg[4], arg[5]);
444 break;
445
446 case VG_USERREQ__PRE_SEM_CLOSE:
447 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
448 DRD_(semaphore_close)(arg[1]);
449 break;
450
451 case VG_USERREQ__POST_SEM_CLOSE:
452 DRD_(thread_leave_synchr)(drd_tid);
453 break;
454
bartbedfd232009-03-26 19:07:15 +0000455 case VG_USERREQ__PRE_SEM_WAIT:
456 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
457 DRD_(semaphore_pre_wait)(arg[1]);
458 break;
bart28230a32008-02-29 17:27:03 +0000459
bartbedfd232009-03-26 19:07:15 +0000460 case VG_USERREQ__POST_SEM_WAIT:
461 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
462 DRD_(semaphore_post_wait)(drd_tid, arg[1], arg[2]);
463 break;
sewardj85642922008-01-14 11:54:56 +0000464
bartbedfd232009-03-26 19:07:15 +0000465 case VG_USERREQ__PRE_SEM_POST:
466 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
467 DRD_(semaphore_pre_post)(drd_tid, arg[1]);
468 break;
sewardj85642922008-01-14 11:54:56 +0000469
bartbedfd232009-03-26 19:07:15 +0000470 case VG_USERREQ__POST_SEM_POST:
471 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
472 DRD_(semaphore_post_post)(drd_tid, arg[1], arg[2]);
473 break;
sewardj85642922008-01-14 11:54:56 +0000474
bartbedfd232009-03-26 19:07:15 +0000475 case VG_USERREQ__PRE_BARRIER_INIT:
476 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
477 DRD_(barrier_init)(arg[1], arg[2], arg[3], arg[4]);
478 break;
sewardj85642922008-01-14 11:54:56 +0000479
bartbedfd232009-03-26 19:07:15 +0000480 case VG_USERREQ__POST_BARRIER_INIT:
481 DRD_(thread_leave_synchr)(drd_tid);
482 break;
bart0268dfa2008-03-11 20:10:21 +0000483
bartbedfd232009-03-26 19:07:15 +0000484 case VG_USERREQ__PRE_BARRIER_DESTROY:
485 DRD_(thread_enter_synchr)(drd_tid);
486 break;
bart0268dfa2008-03-11 20:10:21 +0000487
bartbedfd232009-03-26 19:07:15 +0000488 case VG_USERREQ__POST_BARRIER_DESTROY:
489 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
490 DRD_(barrier_destroy)(arg[1], arg[2]);
491 break;
sewardj85642922008-01-14 11:54:56 +0000492
bartbedfd232009-03-26 19:07:15 +0000493 case VG_USERREQ__PRE_BARRIER_WAIT:
494 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
495 DRD_(barrier_pre_wait)(drd_tid, arg[1], arg[2]);
496 break;
sewardj85642922008-01-14 11:54:56 +0000497
bartbedfd232009-03-26 19:07:15 +0000498 case VG_USERREQ__POST_BARRIER_WAIT:
499 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
500 DRD_(barrier_post_wait)(drd_tid, arg[1], arg[2], arg[3], arg[4]);
501 break;
sewardj85642922008-01-14 11:54:56 +0000502
bartbedfd232009-03-26 19:07:15 +0000503 case VG_USERREQ__PRE_RWLOCK_INIT:
bartd45d9952009-05-31 18:53:54 +0000504 DRD_(rwlock_pre_init)(arg[1], pthread_rwlock);
bartbedfd232009-03-26 19:07:15 +0000505 break;
bart00344642008-03-01 15:27:41 +0000506
bartbedfd232009-03-26 19:07:15 +0000507 case VG_USERREQ__POST_RWLOCK_DESTROY:
bartd45d9952009-05-31 18:53:54 +0000508 DRD_(rwlock_post_destroy)(arg[1], pthread_rwlock);
bartbedfd232009-03-26 19:07:15 +0000509 break;
bart00344642008-03-01 15:27:41 +0000510
bartbedfd232009-03-26 19:07:15 +0000511 case VG_USERREQ__PRE_RWLOCK_RDLOCK:
512 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
bartd45d9952009-05-31 18:53:54 +0000513 DRD_(rwlock_pre_rdlock)(arg[1], pthread_rwlock);
bartbedfd232009-03-26 19:07:15 +0000514 break;
bart00344642008-03-01 15:27:41 +0000515
bartbedfd232009-03-26 19:07:15 +0000516 case VG_USERREQ__POST_RWLOCK_RDLOCK:
517 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
bartd45d9952009-05-31 18:53:54 +0000518 DRD_(rwlock_post_rdlock)(arg[1], pthread_rwlock, arg[2]);
bartbedfd232009-03-26 19:07:15 +0000519 break;
bart00344642008-03-01 15:27:41 +0000520
bartbedfd232009-03-26 19:07:15 +0000521 case VG_USERREQ__PRE_RWLOCK_WRLOCK:
522 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
bartd45d9952009-05-31 18:53:54 +0000523 DRD_(rwlock_pre_wrlock)(arg[1], pthread_rwlock);
bartbedfd232009-03-26 19:07:15 +0000524 break;
bart00344642008-03-01 15:27:41 +0000525
bartbedfd232009-03-26 19:07:15 +0000526 case VG_USERREQ__POST_RWLOCK_WRLOCK:
527 if (DRD_(thread_leave_synchr)(drd_tid) == 0)
bartd45d9952009-05-31 18:53:54 +0000528 DRD_(rwlock_post_wrlock)(arg[1], pthread_rwlock, arg[2]);
bartbedfd232009-03-26 19:07:15 +0000529 break;
bart00344642008-03-01 15:27:41 +0000530
bartbedfd232009-03-26 19:07:15 +0000531 case VG_USERREQ__PRE_RWLOCK_UNLOCK:
532 if (DRD_(thread_enter_synchr)(drd_tid) == 0)
bartd45d9952009-05-31 18:53:54 +0000533 DRD_(rwlock_pre_unlock)(arg[1], pthread_rwlock);
bartbedfd232009-03-26 19:07:15 +0000534 break;
bart31b983d2010-02-21 14:52:59 +0000535
bartbedfd232009-03-26 19:07:15 +0000536 case VG_USERREQ__POST_RWLOCK_UNLOCK:
537 DRD_(thread_leave_synchr)(drd_tid);
538 break;
bart00344642008-03-01 15:27:41 +0000539
bartbedfd232009-03-26 19:07:15 +0000540 case VG_USERREQ__DRD_CLEAN_MEMORY:
541 if (arg[2] > 0)
542 DRD_(clean_memory)(arg[1], arg[2]);
543 break;
bart83c17802009-03-10 09:26:07 +0000544
bart141a7ed2010-03-21 17:28:10 +0000545 case VG_USERREQ__HELGRIND_ANNOTATION_UNIMP:
546 {
547 /* Note: it is assumed below that the text arg[1] points to is never
548 * freed, e.g. because it points to static data.
549 */
550 UnimpClReqInfo UICR =
551 { DRD_(thread_get_running_tid)(), (Char*)arg[1] };
552 VG_(maybe_record_error)(vg_tid,
553 UnimpHgClReq,
554 VG_(get_IP)(vg_tid),
555 "",
556 &UICR);
557 }
558 break;
559
bart66f196d2009-08-15 10:50:35 +0000560 case VG_USERREQ__DRD_ANNOTATION_UNIMP:
561 {
562 /* Note: it is assumed below that the text arg[1] points to is never
563 * freed, e.g. because it points to static data.
564 */
565 UnimpClReqInfo UICR =
566 { DRD_(thread_get_running_tid)(), (Char*)arg[1] };
567 VG_(maybe_record_error)(vg_tid,
bart141a7ed2010-03-21 17:28:10 +0000568 UnimpDrdClReq,
bart66f196d2009-08-15 10:50:35 +0000569 VG_(get_IP)(vg_tid),
570 "",
571 &UICR);
572 }
573 break;
574
bartbedfd232009-03-26 19:07:15 +0000575 default:
bart5c0251e2009-05-02 08:06:53 +0000576#if 0
577 VG_(message)(Vg_DebugMsg, "Unrecognized client request 0x%lx 0x%lx",
578 arg[0], arg[1]);
579 tl_assert(0);
580#endif
bartbedfd232009-03-26 19:07:15 +0000581 return False;
582 }
sewardjaf44c822007-11-25 14:01:38 +0000583
bartbedfd232009-03-26 19:07:15 +0000584 *ret = result;
585 return True;
sewardjaf44c822007-11-25 14:01:38 +0000586}