blob: 194d31f241712817e27d71aa8f3570555442908e [file] [log] [blame]
sewardjaf44c822007-11-25 14:01:38 +00001#include "drd_clientreq.h"
2#include "drd_cond.h"
3#include "drd_mutex.h"
4#include "drd_suppression.h" // drd_start_suppression()
5#include "drd_thread.h"
6#include "drd_track.h"
7#include "pthread_object_size.h"
8#include "pub_core_tooliface.h" // VG_TRACK()
9#include "pub_tool_basics.h" // Bool
10#include "pub_tool_libcassert.h"
11#include "pub_tool_libcassert.h" // tl_assert()
12#include "pub_tool_libcprint.h" // VG_(message)()
13#include "pub_tool_machine.h" // VG_(get_SP)()
14#include "pub_tool_threadstate.h"
15#include "pub_tool_tooliface.h" // VG_(needs_...)()
16
17
18static void drd_spin_init_or_unlock(const Addr spinlock, const SizeT size)
19{
20 struct mutex_info* mutex_p = mutex_get(spinlock);
21 if (mutex_p)
22 {
23 mutex_unlock(spinlock);
24 }
25 else
26 {
27 mutex_init(spinlock, size);
28 }
29}
30
31static void drd_pre_cond_wait(const Addr cond, const Addr mutex)
32{
33 mutex_unlock(mutex);
34 cond_pre_wait(cond, mutex);
35}
36
37static void drd_post_cond_wait(const Addr cond, const Addr mutex)
38{
39 cond_post_wait(cond);
40 mutex_lock(mutex, PTHREAD_MUTEX_SIZE);
41}
42
43static void drd_pre_cond_signal(const Addr cond)
44{
45 cond_pre_signal(cond);
46}
47
48static void drd_pre_cond_broadcast(const Addr cond)
49{
50 cond_pre_broadcast(cond);
51}
52
53static Bool drd_handle_client_request(ThreadId tid, UWord* arg, UWord* ret)
54{
55 UWord result = 0;
56
57 switch (arg[0])
58 {
59 case VG_USERREQ__GET_THREAD_SELF:
60 result = tid;
61 break;
62
63 case VG_USERREQ__SET_THREAD_NAME:
64 thread_set_name_fmt(VgThreadIdToDrdThreadId(VG_(get_running_tid)()),
65 (char*)arg[1], arg[2]);
66 break;
67
68 case VG_USERREQ__DRD_START_SUPPRESSION:
69 drd_start_suppression(arg[1], arg[1] + arg[2], "client");
70 break;
71
72 case VG_USERREQ__DRD_FINISH_SUPPRESSION:
73 drd_finish_suppression(arg[1], arg[1] + arg[2]);
74 break;
75
76 case VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK:
77 thread_set_stack_startup(thread_get_running_tid(),
78 VG_(get_SP)(VG_(get_running_tid)()));
79 break;
80
81 case VG_USERREQ__DRD_START_NEW_SEGMENT:
82 thread_new_segment(PtThreadIdToDrdThreadId(arg[1]));
83 break;
84
85 case VG_USERREQ__DRD_START_RECORDING:
86 thread_start_recording(PtThreadIdToDrdThreadId(arg[1]));
87 break;
88
89 case VG_USERREQ__DRD_STOP_RECORDING:
90 thread_stop_recording(PtThreadIdToDrdThreadId(arg[1]));
91 break;
92
93 case VG_USERREQ__SET_PTHREADID:
94 thread_set_pthreadid(thread_get_running_tid(), arg[1]);
95 break;
96
97 case VG_USERREQ__SET_JOINABLE:
98 thread_set_joinable(PtThreadIdToDrdThreadId(arg[1]), (Bool)arg[2]);
99 break;
100
101 case VG_USERREQ__POST_THREAD_JOIN:
102 tl_assert(arg[1]);
103 drd_post_thread_join(thread_get_running_tid(),
104 PtThreadIdToDrdThreadId(arg[1]));
105 break;
106
107 case VG_USERREQ__PRE_MUTEX_INIT:
108 drd_pre_mutex_init(arg[1], arg[2]);
109 break;
110
111 case VG_USERREQ__POST_MUTEX_DESTROY:
112 drd_post_mutex_destroy(arg[1], arg[2]);
113 break;
114
115 case VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK:
116 drd_pre_mutex_lock(thread_get_running_tid(), arg[1], arg[2]);
117 break;
118
119 case VG_USERREQ__POST_PTHREAD_MUTEX_LOCK:
120 drd_post_mutex_lock(thread_get_running_tid(), arg[1], arg[2]);
121 break;
122
123 case VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK:
124 drd_pre_mutex_unlock(thread_get_running_tid(), arg[1]);
125 break;
126
127 case VG_USERREQ__SPIN_INIT_OR_UNLOCK:
128 drd_spin_init_or_unlock(arg[1], arg[2]);
129 break;
130
131 case VG_USERREQ__POST_PTHREAD_COND_INIT:
132 drd_post_cond_init(arg[1], arg[2]);
133 break;
134
135 case VG_USERREQ__PRE_PTHREAD_COND_DESTROY:
136 drd_pre_cond_destroy(arg[1], arg[2]);
137 break;
138
139 case VG_USERREQ__PRE_PTHREAD_COND_WAIT:
140 drd_pre_cond_wait(arg[1], arg[2]);
141 break;
142
143 case VG_USERREQ__POST_PTHREAD_COND_WAIT:
144 drd_post_cond_wait(arg[1], arg[2]);
145 break;
146
147 case VG_USERREQ__PRE_PTHREAD_COND_SIGNAL:
148 drd_pre_cond_signal(arg[1]);
149 break;
150
151 case VG_USERREQ__PRE_PTHREAD_COND_BROADCAST:
152 drd_pre_cond_broadcast(arg[1]);
153 break;
154
155 default:
156 VG_(message)(Vg_DebugMsg, "Unrecognized client request 0x%lx 0x%lx",
157 arg[0], arg[1]);
158 tl_assert(0);
159 return False;
160 }
161
162 *ret = result;
163 return True;
164}
165
166void drd_clientreq_init(void)
167{
168 VG_(needs_client_requests)(drd_handle_client_request);
169}
170
171/*
172 * Local variables:
173 * c-basic-offset: 3
174 * End:
175 */