c@287
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
c@287
|
2
|
c@287
|
3 /*
|
c@287
|
4 QM DSP Library
|
c@287
|
5
|
c@287
|
6 Centre for Digital Music, Queen Mary, University of London.
|
c@287
|
7 This file copyright Chris Cannam, used with permission.
|
c@287
|
8 */
|
c@287
|
9
|
c@287
|
10 #include "Thread.h"
|
c@287
|
11
|
c@287
|
12 #include <iostream>
|
c@287
|
13 #include <cstdlib>
|
c@287
|
14
|
c@287
|
15 #ifdef USE_PTHREADS
|
c@287
|
16 #include <sys/time.h>
|
c@287
|
17 #include <time.h>
|
c@287
|
18 #endif
|
c@287
|
19
|
c@287
|
20 using std::cerr;
|
c@287
|
21 using std::endl;
|
c@287
|
22 using std::string;
|
c@287
|
23
|
c@287
|
24 #ifdef _WIN32
|
c@287
|
25
|
c@287
|
26 Thread::Thread() :
|
c@287
|
27 m_id(0),
|
c@287
|
28 m_extant(false)
|
c@287
|
29 {
|
c@287
|
30 #ifdef DEBUG_THREAD
|
c@287
|
31 cerr << "THREAD DEBUG: Created thread object " << this << endl;
|
c@287
|
32 #endif
|
c@287
|
33 }
|
c@287
|
34
|
c@287
|
35 Thread::~Thread()
|
c@287
|
36 {
|
c@287
|
37 #ifdef DEBUG_THREAD
|
c@287
|
38 cerr << "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id << endl;
|
c@287
|
39 #endif
|
c@287
|
40 if (m_extant) {
|
c@287
|
41 WaitForSingleObject(m_id, INFINITE);
|
c@287
|
42 }
|
c@287
|
43 #ifdef DEBUG_THREAD
|
c@287
|
44 cerr << "THREAD DEBUG: Destroyed thread object " << this << endl;
|
c@287
|
45 #endif
|
c@287
|
46 }
|
c@287
|
47
|
c@287
|
48 void
|
c@287
|
49 Thread::start()
|
c@287
|
50 {
|
c@287
|
51 m_id = CreateThread(NULL, 0, staticRun, this, 0, 0);
|
c@287
|
52 if (!m_id) {
|
c@287
|
53 cerr << "ERROR: thread creation failed" << endl;
|
c@287
|
54 exit(1);
|
c@287
|
55 } else {
|
c@287
|
56 #ifdef DEBUG_THREAD
|
c@287
|
57 cerr << "THREAD DEBUG: Created thread " << m_id << " for thread object " << this << endl;
|
c@287
|
58 #endif
|
c@287
|
59 m_extant = true;
|
c@287
|
60 }
|
c@287
|
61 }
|
c@287
|
62
|
c@287
|
63 void
|
c@287
|
64 Thread::wait()
|
c@287
|
65 {
|
c@287
|
66 if (m_extant) {
|
c@287
|
67 #ifdef DEBUG_THREAD
|
c@287
|
68 cerr << "THREAD DEBUG: Waiting on thread " << m_id << " for thread object " << this << endl;
|
c@287
|
69 #endif
|
c@287
|
70 WaitForSingleObject(m_id, INFINITE);
|
c@287
|
71 #ifdef DEBUG_THREAD
|
c@287
|
72 cerr << "THREAD DEBUG: Waited on thread " << m_id << " for thread object " << this << endl;
|
c@287
|
73 #endif
|
c@287
|
74 m_extant = false;
|
c@287
|
75 }
|
c@287
|
76 }
|
c@287
|
77
|
c@287
|
78 Thread::Id
|
c@287
|
79 Thread::id()
|
c@287
|
80 {
|
c@287
|
81 return m_id;
|
c@287
|
82 }
|
c@287
|
83
|
c@287
|
84 bool
|
c@287
|
85 Thread::threadingAvailable()
|
c@287
|
86 {
|
c@287
|
87 return true;
|
c@287
|
88 }
|
c@287
|
89
|
c@287
|
90 DWORD
|
c@287
|
91 Thread::staticRun(LPVOID arg)
|
c@287
|
92 {
|
c@287
|
93 Thread *thread = static_cast<Thread *>(arg);
|
c@287
|
94 #ifdef DEBUG_THREAD
|
c@287
|
95 cerr << "THREAD DEBUG: " << (void *)GetCurrentThreadId() << ": Running thread " << thread->m_id << " for thread object " << thread << endl;
|
c@287
|
96 #endif
|
c@287
|
97 thread->run();
|
c@287
|
98 return 0;
|
c@287
|
99 }
|
c@287
|
100
|
c@287
|
101 Mutex::Mutex()
|
c@287
|
102 #ifndef NO_THREAD_CHECKS
|
c@287
|
103 :
|
c@287
|
104 m_lockedBy(-1)
|
c@287
|
105 #endif
|
c@287
|
106 {
|
c@287
|
107 m_mutex = CreateMutex(NULL, FALSE, NULL);
|
c@287
|
108 #ifdef DEBUG_MUTEX
|
c@287
|
109 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised mutex " << &m_mutex << endl;
|
c@287
|
110 #endif
|
c@287
|
111 }
|
c@287
|
112
|
c@287
|
113 Mutex::~Mutex()
|
c@287
|
114 {
|
c@287
|
115 #ifdef DEBUG_MUTEX
|
c@287
|
116 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying mutex " << &m_mutex << endl;
|
c@287
|
117 #endif
|
c@287
|
118 CloseHandle(m_mutex);
|
c@287
|
119 }
|
c@287
|
120
|
c@287
|
121 void
|
c@287
|
122 Mutex::lock()
|
c@287
|
123 {
|
c@287
|
124 #ifndef NO_THREAD_CHECKS
|
c@287
|
125 DWORD tid = GetCurrentThreadId();
|
c@287
|
126 if (m_lockedBy == tid) {
|
c@287
|
127 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
|
c@287
|
128 }
|
c@287
|
129 #endif
|
c@287
|
130 #ifdef DEBUG_MUTEX
|
c@287
|
131 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
|
c@287
|
132 #endif
|
c@287
|
133 WaitForSingleObject(m_mutex, INFINITE);
|
c@287
|
134 #ifndef NO_THREAD_CHECKS
|
c@287
|
135 m_lockedBy = tid;
|
c@287
|
136 #endif
|
c@287
|
137 #ifdef DEBUG_MUTEX
|
c@287
|
138 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
|
c@287
|
139 #endif
|
c@287
|
140 }
|
c@287
|
141
|
c@287
|
142 void
|
c@287
|
143 Mutex::unlock()
|
c@287
|
144 {
|
c@287
|
145 #ifndef NO_THREAD_CHECKS
|
c@287
|
146 DWORD tid = GetCurrentThreadId();
|
c@287
|
147 if (m_lockedBy != tid) {
|
c@287
|
148 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
|
c@287
|
149 return;
|
c@287
|
150 }
|
c@287
|
151 #endif
|
c@287
|
152 #ifdef DEBUG_MUTEX
|
c@287
|
153 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
|
c@287
|
154 #endif
|
c@287
|
155 #ifndef NO_THREAD_CHECKS
|
c@287
|
156 m_lockedBy = -1;
|
c@287
|
157 #endif
|
c@287
|
158 ReleaseMutex(m_mutex);
|
c@287
|
159 }
|
c@287
|
160
|
c@287
|
161 bool
|
c@287
|
162 Mutex::trylock()
|
c@287
|
163 {
|
c@287
|
164 #ifndef NO_THREAD_CHECKS
|
c@287
|
165 DWORD tid = GetCurrentThreadId();
|
c@287
|
166 #endif
|
c@287
|
167 DWORD result = WaitForSingleObject(m_mutex, 0);
|
c@287
|
168 if (result == WAIT_TIMEOUT || result == WAIT_FAILED) {
|
c@287
|
169 #ifdef DEBUG_MUTEX
|
c@287
|
170 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
|
c@287
|
171 #endif
|
c@287
|
172 return false;
|
c@287
|
173 } else {
|
c@287
|
174 #ifndef NO_THREAD_CHECKS
|
c@287
|
175 m_lockedBy = tid;
|
c@287
|
176 #endif
|
c@287
|
177 #ifdef DEBUG_MUTEX
|
c@287
|
178 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
|
c@287
|
179 #endif
|
c@287
|
180 return true;
|
c@287
|
181 }
|
c@287
|
182 }
|
c@287
|
183
|
c@287
|
184 Condition::Condition(string name) :
|
c@287
|
185 m_locked(false)
|
c@287
|
186 #ifdef DEBUG_CONDITION
|
c@287
|
187 , m_name(name)
|
c@287
|
188 #endif
|
c@287
|
189 {
|
c@287
|
190 m_mutex = CreateMutex(NULL, FALSE, NULL);
|
c@287
|
191 m_condition = CreateEvent(NULL, FALSE, FALSE, NULL);
|
c@287
|
192 #ifdef DEBUG_CONDITION
|
c@287
|
193 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised condition " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
194 #endif
|
c@287
|
195 }
|
c@287
|
196
|
c@287
|
197 Condition::~Condition()
|
c@287
|
198 {
|
c@287
|
199 #ifdef DEBUG_CONDITION
|
c@287
|
200 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying condition " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
201 #endif
|
c@287
|
202 if (m_locked) ReleaseMutex(m_mutex);
|
c@287
|
203 CloseHandle(m_condition);
|
c@287
|
204 CloseHandle(m_mutex);
|
c@287
|
205 }
|
c@287
|
206
|
c@287
|
207 void
|
c@287
|
208 Condition::lock()
|
c@287
|
209 {
|
c@287
|
210 #ifdef DEBUG_CONDITION
|
c@287
|
211 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
212 #endif
|
c@287
|
213 WaitForSingleObject(m_mutex, INFINITE);
|
c@287
|
214 m_locked = true;
|
c@287
|
215 #ifdef DEBUG_CONDITION
|
c@287
|
216 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
217 #endif
|
c@287
|
218 }
|
c@287
|
219
|
c@287
|
220 void
|
c@287
|
221 Condition::unlock()
|
c@287
|
222 {
|
c@287
|
223 if (!m_locked) {
|
c@287
|
224 #ifdef DEBUG_CONDITION
|
c@287
|
225 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Not locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
226 #endif
|
c@287
|
227 return;
|
c@287
|
228 }
|
c@287
|
229 #ifdef DEBUG_CONDITION
|
c@287
|
230 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Unlocking " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
231 #endif
|
c@287
|
232 m_locked = false;
|
c@287
|
233 ReleaseMutex(m_mutex);
|
c@287
|
234 }
|
c@287
|
235
|
c@287
|
236 void
|
c@287
|
237 Condition::wait(int us)
|
c@287
|
238 {
|
c@287
|
239 if (us == 0) {
|
c@287
|
240
|
c@287
|
241 #ifdef DEBUG_CONDITION
|
c@287
|
242 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
243 #endif
|
c@287
|
244 SignalObjectAndWait(m_mutex, m_condition, INFINITE, FALSE);
|
c@287
|
245 WaitForSingleObject(m_mutex, INFINITE);
|
c@287
|
246
|
c@287
|
247 } else {
|
c@287
|
248
|
c@287
|
249 DWORD ms = us / 1000;
|
c@287
|
250 if (us > 0 && ms == 0) ms = 1;
|
c@287
|
251
|
c@287
|
252 #ifdef DEBUG_CONDITION
|
c@287
|
253 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Timed waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
254 #endif
|
c@287
|
255 SignalObjectAndWait(m_mutex, m_condition, ms, FALSE);
|
c@287
|
256 WaitForSingleObject(m_mutex, INFINITE);
|
c@287
|
257 }
|
c@287
|
258
|
c@287
|
259 #ifdef DEBUG_CONDITION
|
c@287
|
260 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
261 #endif
|
c@287
|
262 }
|
c@287
|
263
|
c@287
|
264 void
|
c@287
|
265 Condition::signal()
|
c@287
|
266 {
|
c@287
|
267 #ifdef DEBUG_CONDITION
|
c@287
|
268 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
269 #endif
|
c@287
|
270 SetEvent(m_condition);
|
c@287
|
271 }
|
c@287
|
272
|
c@287
|
273 #else /* !_WIN32 */
|
c@287
|
274
|
c@287
|
275 #ifdef USE_PTHREADS
|
c@287
|
276
|
c@287
|
277 Thread::Thread() :
|
c@287
|
278 m_id(0),
|
c@287
|
279 m_extant(false)
|
c@287
|
280 {
|
c@287
|
281 #ifdef DEBUG_THREAD
|
c@287
|
282 cerr << "THREAD DEBUG: Created thread object " << this << endl;
|
c@287
|
283 #endif
|
c@287
|
284 }
|
c@287
|
285
|
c@287
|
286 Thread::~Thread()
|
c@287
|
287 {
|
c@287
|
288 #ifdef DEBUG_THREAD
|
c@287
|
289 cerr << "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id << endl;
|
c@287
|
290 #endif
|
c@287
|
291 if (m_extant) {
|
c@287
|
292 pthread_join(m_id, 0);
|
c@287
|
293 }
|
c@287
|
294 #ifdef DEBUG_THREAD
|
c@287
|
295 cerr << "THREAD DEBUG: Destroyed thread object " << this << endl;
|
c@287
|
296 #endif
|
c@287
|
297 }
|
c@287
|
298
|
c@287
|
299 void
|
c@287
|
300 Thread::start()
|
c@287
|
301 {
|
c@287
|
302 if (pthread_create(&m_id, 0, staticRun, this)) {
|
c@287
|
303 cerr << "ERROR: thread creation failed" << endl;
|
c@287
|
304 exit(1);
|
c@287
|
305 } else {
|
c@287
|
306 #ifdef DEBUG_THREAD
|
c@287
|
307 cerr << "THREAD DEBUG: Created thread " << m_id << " for thread object " << this << endl;
|
c@287
|
308 #endif
|
c@287
|
309 m_extant = true;
|
c@287
|
310 }
|
c@287
|
311 }
|
c@287
|
312
|
c@287
|
313 void
|
c@287
|
314 Thread::wait()
|
c@287
|
315 {
|
c@287
|
316 if (m_extant) {
|
c@287
|
317 #ifdef DEBUG_THREAD
|
c@287
|
318 cerr << "THREAD DEBUG: Waiting on thread " << m_id << " for thread object " << this << endl;
|
c@287
|
319 #endif
|
c@287
|
320 pthread_join(m_id, 0);
|
c@287
|
321 #ifdef DEBUG_THREAD
|
c@287
|
322 cerr << "THREAD DEBUG: Waited on thread " << m_id << " for thread object " << this << endl;
|
c@287
|
323 #endif
|
c@287
|
324 m_extant = false;
|
c@287
|
325 }
|
c@287
|
326 }
|
c@287
|
327
|
c@287
|
328 Thread::Id
|
c@287
|
329 Thread::id()
|
c@287
|
330 {
|
c@287
|
331 return m_id;
|
c@287
|
332 }
|
c@287
|
333
|
c@287
|
334 bool
|
c@287
|
335 Thread::threadingAvailable()
|
c@287
|
336 {
|
c@287
|
337 return true;
|
c@287
|
338 }
|
c@287
|
339
|
c@287
|
340 void *
|
c@287
|
341 Thread::staticRun(void *arg)
|
c@287
|
342 {
|
c@287
|
343 Thread *thread = static_cast<Thread *>(arg);
|
c@287
|
344 #ifdef DEBUG_THREAD
|
c@287
|
345 cerr << "THREAD DEBUG: " << (void *)pthread_self() << ": Running thread " << thread->m_id << " for thread object " << thread << endl;
|
c@287
|
346 #endif
|
c@287
|
347 thread->run();
|
c@287
|
348 return 0;
|
c@287
|
349 }
|
c@287
|
350
|
c@287
|
351 Mutex::Mutex()
|
c@287
|
352 #ifndef NO_THREAD_CHECKS
|
c@287
|
353 :
|
c@287
|
354 m_lockedBy(0),
|
c@287
|
355 m_locked(false)
|
c@287
|
356 #endif
|
c@287
|
357 {
|
c@287
|
358 pthread_mutex_init(&m_mutex, 0);
|
c@287
|
359 #ifdef DEBUG_MUTEX
|
c@287
|
360 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Initialised mutex " << &m_mutex << endl;
|
c@287
|
361 #endif
|
c@287
|
362 }
|
c@287
|
363
|
c@287
|
364 Mutex::~Mutex()
|
c@287
|
365 {
|
c@287
|
366 #ifdef DEBUG_MUTEX
|
c@287
|
367 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Destroying mutex " << &m_mutex << endl;
|
c@287
|
368 #endif
|
c@287
|
369 pthread_mutex_destroy(&m_mutex);
|
c@287
|
370 }
|
c@287
|
371
|
c@287
|
372 void
|
c@287
|
373 Mutex::lock()
|
c@287
|
374 {
|
c@287
|
375 #ifndef NO_THREAD_CHECKS
|
c@287
|
376 pthread_t tid = pthread_self();
|
c@287
|
377 if (m_locked && m_lockedBy == tid) {
|
c@287
|
378 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
|
c@287
|
379 }
|
c@287
|
380 #endif
|
c@287
|
381 #ifdef DEBUG_MUTEX
|
c@287
|
382 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
|
c@287
|
383 #endif
|
c@287
|
384 pthread_mutex_lock(&m_mutex);
|
c@287
|
385 #ifndef NO_THREAD_CHECKS
|
c@287
|
386 m_lockedBy = tid;
|
c@287
|
387 m_locked = true;
|
c@287
|
388 #endif
|
c@287
|
389 #ifdef DEBUG_MUTEX
|
c@287
|
390 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
|
c@287
|
391 #endif
|
c@287
|
392 }
|
c@287
|
393
|
c@287
|
394 void
|
c@287
|
395 Mutex::unlock()
|
c@287
|
396 {
|
c@287
|
397 #ifndef NO_THREAD_CHECKS
|
c@287
|
398 pthread_t tid = pthread_self();
|
c@287
|
399 if (!m_locked) {
|
c@287
|
400 cerr << "ERROR: Mutex " << &m_mutex << " not locked in unlock" << endl;
|
c@287
|
401 return;
|
c@287
|
402 } else if (m_lockedBy != tid) {
|
c@287
|
403 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
|
c@287
|
404 return;
|
c@287
|
405 }
|
c@287
|
406 #endif
|
c@287
|
407 #ifdef DEBUG_MUTEX
|
c@287
|
408 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
|
c@287
|
409 #endif
|
c@287
|
410 #ifndef NO_THREAD_CHECKS
|
c@287
|
411 m_locked = false;
|
c@287
|
412 #endif
|
c@287
|
413 pthread_mutex_unlock(&m_mutex);
|
c@287
|
414 }
|
c@287
|
415
|
c@287
|
416 bool
|
c@287
|
417 Mutex::trylock()
|
c@287
|
418 {
|
c@287
|
419 #ifndef NO_THREAD_CHECKS
|
c@287
|
420 pthread_t tid = pthread_self();
|
c@287
|
421 #endif
|
c@287
|
422 if (pthread_mutex_trylock(&m_mutex)) {
|
c@287
|
423 #ifdef DEBUG_MUTEX
|
c@287
|
424 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
|
c@287
|
425 #endif
|
c@287
|
426 return false;
|
c@287
|
427 } else {
|
c@287
|
428 #ifndef NO_THREAD_CHECKS
|
c@287
|
429 m_lockedBy = tid;
|
c@287
|
430 m_locked = true;
|
c@287
|
431 #endif
|
c@287
|
432 #ifdef DEBUG_MUTEX
|
c@287
|
433 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
|
c@287
|
434 #endif
|
c@287
|
435 return true;
|
c@287
|
436 }
|
c@287
|
437 }
|
c@287
|
438
|
c@287
|
439 Condition::Condition(string name) :
|
c@287
|
440 m_locked(false)
|
c@287
|
441 #ifdef DEBUG_CONDITION
|
c@287
|
442 , m_name(name)
|
c@287
|
443 #endif
|
c@287
|
444 {
|
c@287
|
445 pthread_mutex_init(&m_mutex, 0);
|
c@287
|
446 pthread_cond_init(&m_condition, 0);
|
c@287
|
447 #ifdef DEBUG_CONDITION
|
c@287
|
448 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Initialised condition " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
449 #endif
|
c@287
|
450 }
|
c@287
|
451
|
c@287
|
452 Condition::~Condition()
|
c@287
|
453 {
|
c@287
|
454 #ifdef DEBUG_CONDITION
|
c@287
|
455 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Destroying condition " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
456 #endif
|
c@287
|
457 if (m_locked) pthread_mutex_unlock(&m_mutex);
|
c@287
|
458 pthread_cond_destroy(&m_condition);
|
c@287
|
459 pthread_mutex_destroy(&m_mutex);
|
c@287
|
460 }
|
c@287
|
461
|
c@287
|
462 void
|
c@287
|
463 Condition::lock()
|
c@287
|
464 {
|
c@287
|
465 #ifdef DEBUG_CONDITION
|
c@287
|
466 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
467 #endif
|
c@287
|
468 pthread_mutex_lock(&m_mutex);
|
c@287
|
469 m_locked = true;
|
c@287
|
470 #ifdef DEBUG_CONDITION
|
c@287
|
471 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
472 #endif
|
c@287
|
473 }
|
c@287
|
474
|
c@287
|
475 void
|
c@287
|
476 Condition::unlock()
|
c@287
|
477 {
|
c@287
|
478 if (!m_locked) {
|
c@287
|
479 #ifdef DEBUG_CONDITION
|
c@287
|
480 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Not locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
481 #endif
|
c@287
|
482 return;
|
c@287
|
483 }
|
c@287
|
484 #ifdef DEBUG_CONDITION
|
c@287
|
485 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Unlocking " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
486 #endif
|
c@287
|
487 m_locked = false;
|
c@287
|
488 pthread_mutex_unlock(&m_mutex);
|
c@287
|
489 }
|
c@287
|
490
|
c@287
|
491 void
|
c@287
|
492 Condition::wait(int us)
|
c@287
|
493 {
|
c@287
|
494 if (us == 0) {
|
c@287
|
495
|
c@287
|
496 #ifdef DEBUG_CONDITION
|
c@287
|
497 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
498 #endif
|
c@287
|
499 pthread_cond_wait(&m_condition, &m_mutex);
|
c@287
|
500
|
c@287
|
501 } else {
|
c@287
|
502
|
c@287
|
503 struct timeval now;
|
c@287
|
504 gettimeofday(&now, 0);
|
c@287
|
505
|
c@287
|
506 now.tv_usec += us;
|
c@287
|
507 while (now.tv_usec > 1000000) {
|
c@287
|
508 now.tv_usec -= 1000000;
|
c@287
|
509 ++now.tv_sec;
|
c@287
|
510 }
|
c@287
|
511
|
c@287
|
512 struct timespec timeout;
|
c@287
|
513 timeout.tv_sec = now.tv_sec;
|
c@287
|
514 timeout.tv_nsec = now.tv_usec * 1000;
|
c@287
|
515
|
c@287
|
516 #ifdef DEBUG_CONDITION
|
c@287
|
517 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Timed waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
518 #endif
|
c@287
|
519 pthread_cond_timedwait(&m_condition, &m_mutex, &timeout);
|
c@287
|
520 }
|
c@287
|
521
|
c@287
|
522 #ifdef DEBUG_CONDITION
|
c@287
|
523 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
524 #endif
|
c@294
|
525
|
c@294
|
526 m_locked = true;
|
c@287
|
527 }
|
c@287
|
528
|
c@287
|
529 void
|
c@287
|
530 Condition::signal()
|
c@287
|
531 {
|
c@287
|
532 #ifdef DEBUG_CONDITION
|
c@287
|
533 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
534 #endif
|
c@287
|
535 pthread_cond_signal(&m_condition);
|
c@287
|
536 }
|
c@287
|
537
|
c@287
|
538 #else /* !USE_PTHREADS */
|
c@287
|
539
|
c@287
|
540 Thread::Thread()
|
c@287
|
541 {
|
c@287
|
542 }
|
c@287
|
543
|
c@287
|
544 Thread::~Thread()
|
c@287
|
545 {
|
c@287
|
546 }
|
c@287
|
547
|
c@287
|
548 void
|
c@287
|
549 Thread::start()
|
c@287
|
550 {
|
c@287
|
551 abort();
|
c@287
|
552 }
|
c@287
|
553
|
c@287
|
554 void
|
c@287
|
555 Thread::wait()
|
c@287
|
556 {
|
c@287
|
557 abort();
|
c@287
|
558 }
|
c@287
|
559
|
c@287
|
560 Thread::Id
|
c@287
|
561 Thread::id()
|
c@287
|
562 {
|
c@287
|
563 abort();
|
c@287
|
564 }
|
c@287
|
565
|
c@287
|
566 bool
|
c@287
|
567 Thread::threadingAvailable()
|
c@287
|
568 {
|
c@287
|
569 return false;
|
c@287
|
570 }
|
c@287
|
571
|
c@287
|
572 Mutex::Mutex()
|
c@287
|
573 {
|
c@287
|
574 }
|
c@287
|
575
|
c@287
|
576 Mutex::~Mutex()
|
c@287
|
577 {
|
c@287
|
578 }
|
c@287
|
579
|
c@287
|
580 void
|
c@287
|
581 Mutex::lock()
|
c@287
|
582 {
|
c@287
|
583 abort();
|
c@287
|
584 }
|
c@287
|
585
|
c@287
|
586 void
|
c@287
|
587 Mutex::unlock()
|
c@287
|
588 {
|
c@287
|
589 abort();
|
c@287
|
590 }
|
c@287
|
591
|
c@287
|
592 bool
|
c@287
|
593 Mutex::trylock()
|
c@287
|
594 {
|
c@287
|
595 abort();
|
c@287
|
596 }
|
c@287
|
597
|
c@287
|
598 Condition::Condition(const char *)
|
c@287
|
599 {
|
c@287
|
600 }
|
c@287
|
601
|
c@287
|
602 Condition::~Condition()
|
c@287
|
603 {
|
c@287
|
604 }
|
c@287
|
605
|
c@287
|
606 void
|
c@287
|
607 Condition::lock()
|
c@287
|
608 {
|
c@287
|
609 abort();
|
c@287
|
610 }
|
c@287
|
611
|
c@287
|
612 void
|
c@287
|
613 Condition::wait(int us)
|
c@287
|
614 {
|
c@287
|
615 abort();
|
c@287
|
616 }
|
c@287
|
617
|
c@287
|
618 void
|
c@287
|
619 Condition::signal()
|
c@287
|
620 {
|
c@287
|
621 abort();
|
c@287
|
622 }
|
c@287
|
623
|
c@287
|
624 #endif /* !USE_PTHREADS */
|
c@287
|
625 #endif /* !_WIN32 */
|
c@287
|
626
|
c@287
|
627 MutexLocker::MutexLocker(Mutex *mutex) :
|
c@287
|
628 m_mutex(mutex)
|
c@287
|
629 {
|
c@287
|
630 if (m_mutex) {
|
c@287
|
631 m_mutex->lock();
|
c@287
|
632 }
|
c@287
|
633 }
|
c@287
|
634
|
c@287
|
635 MutexLocker::~MutexLocker()
|
c@287
|
636 {
|
c@287
|
637 if (m_mutex) {
|
c@287
|
638 m_mutex->unlock();
|
c@287
|
639 }
|
c@287
|
640 }
|
c@287
|
641
|