1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright Chris Cannam, used with permission.
31 cerr
<< "THREAD DEBUG: Created thread object " << this << endl
;
38 cerr
<< "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id
<< endl
;
41 WaitForSingleObject(m_id
, INFINITE
);
44 cerr
<< "THREAD DEBUG: Destroyed thread object " << this << endl
;
51 m_id
= CreateThread(NULL
, 0, staticRun
, this, 0, 0);
53 cerr
<< "ERROR: thread creation failed" << endl
;
57 cerr
<< "THREAD DEBUG: Created thread " << m_id
<< " for thread object " << this << endl
;
68 cerr
<< "THREAD DEBUG: Waiting on thread " << m_id
<< " for thread object " << this << endl
;
70 WaitForSingleObject(m_id
, INFINITE
);
72 cerr
<< "THREAD DEBUG: Waited on thread " << m_id
<< " for thread object " << this << endl
;
85 Thread::threadingAvailable()
91 Thread::staticRun(LPVOID arg
)
93 Thread
*thread
= static_cast<Thread
*>(arg
);
95 cerr
<< "THREAD DEBUG: " << (void *)GetCurrentThreadId() << ": Running thread " << thread
->m_id
<< " for thread object " << thread
<< endl
;
102 #ifndef NO_THREAD_CHECKS
107 m_mutex
= CreateMutex(NULL
, FALSE
, NULL
);
109 cerr
<< "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised mutex " << &m_mutex
<< endl
;
116 cerr
<< "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying mutex " << &m_mutex
<< endl
;
118 CloseHandle(m_mutex
);
124 #ifndef NO_THREAD_CHECKS
125 DWORD tid
= GetCurrentThreadId();
126 if (m_lockedBy
== tid
) {
127 cerr
<< "ERROR: Deadlock on mutex " << &m_mutex
<< endl
;
131 cerr
<< "MUTEX DEBUG: " << (void *)tid
<< ": Want to lock mutex " << &m_mutex
<< endl
;
133 WaitForSingleObject(m_mutex
, INFINITE
);
134 #ifndef NO_THREAD_CHECKS
138 cerr
<< "MUTEX DEBUG: " << (void *)tid
<< ": Locked mutex " << &m_mutex
<< endl
;
145 #ifndef NO_THREAD_CHECKS
146 DWORD tid
= GetCurrentThreadId();
147 if (m_lockedBy
!= tid
) {
148 cerr
<< "ERROR: Mutex " << &m_mutex
<< " not owned by unlocking thread" << endl
;
153 cerr
<< "MUTEX DEBUG: " << (void *)tid
<< ": Unlocking mutex " << &m_mutex
<< endl
;
155 #ifndef NO_THREAD_CHECKS
158 ReleaseMutex(m_mutex
);
164 #ifndef NO_THREAD_CHECKS
165 DWORD tid
= GetCurrentThreadId();
167 DWORD result
= WaitForSingleObject(m_mutex
, 0);
168 if (result
== WAIT_TIMEOUT
|| result
== WAIT_FAILED
) {
170 cerr
<< "MUTEX DEBUG: " << (void *)tid
<< ": Mutex " << &m_mutex
<< " unavailable" << endl
;
174 #ifndef NO_THREAD_CHECKS
178 cerr
<< "MUTEX DEBUG: " << (void *)tid
<< ": Locked mutex " << &m_mutex
<< " (from trylock)" << endl
;
184 Condition::Condition(string name
) :
186 #ifdef DEBUG_CONDITION
190 m_mutex
= CreateMutex(NULL
, FALSE
, NULL
);
191 m_condition
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
192 #ifdef DEBUG_CONDITION
193 cerr
<< "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised condition " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
197 Condition::~Condition()
199 #ifdef DEBUG_CONDITION
200 cerr
<< "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying condition " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
202 if (m_locked
) ReleaseMutex(m_mutex
);
203 CloseHandle(m_condition
);
204 CloseHandle(m_mutex
);
210 #ifdef DEBUG_CONDITION
211 cerr
<< "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Want to lock " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
213 WaitForSingleObject(m_mutex
, INFINITE
);
215 #ifdef DEBUG_CONDITION
216 cerr
<< "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Locked " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
224 #ifdef DEBUG_CONDITION
225 cerr
<< "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Not locked " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
229 #ifdef DEBUG_CONDITION
230 cerr
<< "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Unlocking " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
233 ReleaseMutex(m_mutex
);
237 Condition::wait(int us
)
241 #ifdef DEBUG_CONDITION
242 cerr
<< "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Waiting on " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
244 SignalObjectAndWait(m_mutex
, m_condition
, INFINITE
, FALSE
);
245 WaitForSingleObject(m_mutex
, INFINITE
);
249 DWORD ms
= us
/ 1000;
250 if (us
> 0 && ms
== 0) ms
= 1;
252 #ifdef DEBUG_CONDITION
253 cerr
<< "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Timed waiting on " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
255 SignalObjectAndWait(m_mutex
, m_condition
, ms
, FALSE
);
256 WaitForSingleObject(m_mutex
, INFINITE
);
259 #ifdef DEBUG_CONDITION
260 cerr
<< "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Wait done on " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
269 #ifdef DEBUG_CONDITION
270 cerr
<< "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Signalling " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
272 SetEvent(m_condition
);
284 cerr
<< "THREAD DEBUG: Created thread object " << this << endl
;
291 cerr
<< "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id
<< endl
;
294 pthread_join(m_id
, 0);
297 cerr
<< "THREAD DEBUG: Destroyed thread object " << this << endl
;
304 if (pthread_create(&m_id
, 0, staticRun
, this)) {
305 cerr
<< "ERROR: thread creation failed" << endl
;
309 cerr
<< "THREAD DEBUG: Created thread " << m_id
<< " for thread object " << this << endl
;
320 cerr
<< "THREAD DEBUG: Waiting on thread " << m_id
<< " for thread object " << this << endl
;
322 pthread_join(m_id
, 0);
324 cerr
<< "THREAD DEBUG: Waited on thread " << m_id
<< " for thread object " << this << endl
;
337 Thread::threadingAvailable()
343 Thread::staticRun(void *arg
)
345 Thread
*thread
= static_cast<Thread
*>(arg
);
347 cerr
<< "THREAD DEBUG: " << (void *)pthread_self() << ": Running thread " << thread
->m_id
<< " for thread object " << thread
<< endl
;
354 #ifndef NO_THREAD_CHECKS
360 pthread_mutex_init(&m_mutex
, 0);
362 cerr
<< "MUTEX DEBUG: " << (void *)pthread_self() << ": Initialised mutex " << &m_mutex
<< endl
;
369 cerr
<< "MUTEX DEBUG: " << (void *)pthread_self() << ": Destroying mutex " << &m_mutex
<< endl
;
371 pthread_mutex_destroy(&m_mutex
);
377 #ifndef NO_THREAD_CHECKS
378 pthread_t tid
= pthread_self();
379 if (m_locked
&& m_lockedBy
== tid
) {
380 cerr
<< "ERROR: Deadlock on mutex " << &m_mutex
<< endl
;
384 cerr
<< "MUTEX DEBUG: " << (void *)tid
<< ": Want to lock mutex " << &m_mutex
<< endl
;
386 pthread_mutex_lock(&m_mutex
);
387 #ifndef NO_THREAD_CHECKS
392 cerr
<< "MUTEX DEBUG: " << (void *)tid
<< ": Locked mutex " << &m_mutex
<< endl
;
399 #ifndef NO_THREAD_CHECKS
400 pthread_t tid
= pthread_self();
402 cerr
<< "ERROR: Mutex " << &m_mutex
<< " not locked in unlock" << endl
;
404 } else if (m_lockedBy
!= tid
) {
405 cerr
<< "ERROR: Mutex " << &m_mutex
<< " not owned by unlocking thread" << endl
;
410 cerr
<< "MUTEX DEBUG: " << (void *)tid
<< ": Unlocking mutex " << &m_mutex
<< endl
;
412 #ifndef NO_THREAD_CHECKS
415 pthread_mutex_unlock(&m_mutex
);
421 #ifndef NO_THREAD_CHECKS
422 pthread_t tid
= pthread_self();
424 if (pthread_mutex_trylock(&m_mutex
)) {
426 cerr
<< "MUTEX DEBUG: " << (void *)tid
<< ": Mutex " << &m_mutex
<< " unavailable" << endl
;
430 #ifndef NO_THREAD_CHECKS
435 cerr
<< "MUTEX DEBUG: " << (void *)tid
<< ": Locked mutex " << &m_mutex
<< " (from trylock)" << endl
;
441 Condition::Condition(string name
) :
443 #ifdef DEBUG_CONDITION
447 pthread_mutex_init(&m_mutex
, 0);
448 pthread_cond_init(&m_condition
, 0);
449 #ifdef DEBUG_CONDITION
450 cerr
<< "CONDITION DEBUG: " << (void *)pthread_self() << ": Initialised condition " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
454 Condition::~Condition()
456 #ifdef DEBUG_CONDITION
457 cerr
<< "CONDITION DEBUG: " << (void *)pthread_self() << ": Destroying condition " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
459 if (m_locked
) pthread_mutex_unlock(&m_mutex
);
460 pthread_cond_destroy(&m_condition
);
461 pthread_mutex_destroy(&m_mutex
);
467 #ifdef DEBUG_CONDITION
468 cerr
<< "CONDITION DEBUG: " << (void *)pthread_self() << ": Want to lock " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
470 pthread_mutex_lock(&m_mutex
);
472 #ifdef DEBUG_CONDITION
473 cerr
<< "CONDITION DEBUG: " << (void *)pthread_self() << ": Locked " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
481 #ifdef DEBUG_CONDITION
482 cerr
<< "CONDITION DEBUG: " << (void *)pthread_self() << ": Not locked " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
486 #ifdef DEBUG_CONDITION
487 cerr
<< "CONDITION DEBUG: " << (void *)pthread_self() << ": Unlocking " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
490 pthread_mutex_unlock(&m_mutex
);
494 Condition::wait(int us
)
498 #ifdef DEBUG_CONDITION
499 cerr
<< "CONDITION DEBUG: " << (void *)pthread_self() << ": Waiting on " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
501 pthread_cond_wait(&m_condition
, &m_mutex
);
506 gettimeofday(&now
, 0);
509 while (now
.tv_usec
> 1000000) {
510 now
.tv_usec
-= 1000000;
514 struct timespec timeout
;
515 timeout
.tv_sec
= now
.tv_sec
;
516 timeout
.tv_nsec
= now
.tv_usec
* 1000;
518 #ifdef DEBUG_CONDITION
519 cerr
<< "CONDITION DEBUG: " << (void *)pthread_self() << ": Timed waiting on " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
521 pthread_cond_timedwait(&m_condition
, &m_mutex
, &timeout
);
524 #ifdef DEBUG_CONDITION
525 cerr
<< "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
534 #ifdef DEBUG_CONDITION
535 cerr
<< "CONDITION DEBUG: " << (void *)pthread_self() << ": Signalling " << &m_condition
<< " \"" << m_name
<< "\"" << endl
;
537 pthread_cond_signal(&m_condition
);
540 #else /* !USE_PTHREADS */
569 Thread::threadingAvailable()
600 Condition::Condition(const char *)
604 Condition::~Condition()
615 Condition::wait(int us
)
626 #endif /* !USE_PTHREADS */
629 MutexLocker::MutexLocker(Mutex
*mutex
) :
637 MutexLocker::~MutexLocker()