1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
5 An audio time-stretching and pitch-shifting library.
6 Copyright 2007-2008 Chris Cannam.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version. See the file
12 COPYING included with this distribution for more information.
39 cerr << "THREAD DEBUG: Created thread object " << this << endl;
46 cerr << "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id << endl;
49 WaitForSingleObject(m_id, INFINITE);
52 cerr << "THREAD DEBUG: Destroyed thread object " << this << endl;
59 m_id = CreateThread(NULL, 0, staticRun, this, 0, 0);
61 cerr << "ERROR: thread creation failed" << endl;
65 cerr << "THREAD DEBUG: Created thread " << m_id << " for thread object " << this << endl;
76 cerr << "THREAD DEBUG: Waiting on thread " << m_id << " for thread object " << this << endl;
78 WaitForSingleObject(m_id, INFINITE);
80 cerr << "THREAD DEBUG: Waited on thread " << m_id << " for thread object " << this << endl;
93 Thread::threadingAvailable()
99 Thread::staticRun(LPVOID arg)
101 Thread *thread = static_cast<Thread *>(arg);
103 cerr << "THREAD DEBUG: " << (void *)GetCurrentThreadId() << ": Running thread " << thread->m_id << " for thread object " << thread << endl;
110 #ifndef NO_THREAD_CHECKS
115 m_mutex = CreateMutex(NULL, FALSE, NULL);
117 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised mutex " << &m_mutex << endl;
124 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying mutex " << &m_mutex << endl;
126 CloseHandle(m_mutex);
132 #ifndef NO_THREAD_CHECKS
133 DWORD tid = GetCurrentThreadId();
134 if (m_lockedBy == tid) {
135 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
139 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
141 WaitForSingleObject(m_mutex, INFINITE);
142 #ifndef NO_THREAD_CHECKS
146 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
153 #ifndef NO_THREAD_CHECKS
154 DWORD tid = GetCurrentThreadId();
155 if (m_lockedBy != tid) {
156 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
161 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
163 #ifndef NO_THREAD_CHECKS
166 ReleaseMutex(m_mutex);
172 #ifndef NO_THREAD_CHECKS
173 DWORD tid = GetCurrentThreadId();
175 DWORD result = WaitForSingleObject(m_mutex, 0);
176 if (result == WAIT_TIMEOUT || result == WAIT_FAILED) {
178 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
182 #ifndef NO_THREAD_CHECKS
186 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
192 Condition::Condition(string name) :
194 #ifdef DEBUG_CONDITION
198 m_mutex = CreateMutex(NULL, FALSE, NULL);
199 m_condition = CreateEvent(NULL, FALSE, FALSE, NULL);
200 #ifdef DEBUG_CONDITION
201 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised condition " << &m_condition << " \"" << m_name << "\"" << endl;
205 Condition::~Condition()
207 #ifdef DEBUG_CONDITION
208 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying condition " << &m_condition << " \"" << m_name << "\"" << endl;
210 if (m_locked) ReleaseMutex(m_mutex);
211 CloseHandle(m_condition);
212 CloseHandle(m_mutex);
219 #ifdef DEBUG_CONDITION
220 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Already locked " << &m_condition << " \"" << m_name << "\"" << endl;
224 #ifdef DEBUG_CONDITION
225 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
227 WaitForSingleObject(m_mutex, INFINITE);
229 #ifdef DEBUG_CONDITION
230 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Locked " << &m_condition << " \"" << m_name << "\"" << endl;
238 #ifdef DEBUG_CONDITION
239 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Not locked " << &m_condition << " \"" << m_name << "\"" << endl;
243 #ifdef DEBUG_CONDITION
244 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Unlocking " << &m_condition << " \"" << m_name << "\"" << endl;
247 ReleaseMutex(m_mutex);
251 Condition::wait(int us)
253 if (!m_locked) lock();
257 #ifdef DEBUG_CONDITION
258 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
260 SignalObjectAndWait(m_mutex, m_condition, INFINITE, FALSE);
261 WaitForSingleObject(m_mutex, INFINITE);
265 DWORD ms = us / 1000;
266 if (us > 0 && ms == 0) ms = 1;
268 #ifdef DEBUG_CONDITION
269 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Timed waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
271 SignalObjectAndWait(m_mutex, m_condition, ms, FALSE);
272 WaitForSingleObject(m_mutex, INFINITE);
275 ReleaseMutex(m_mutex);
277 #ifdef DEBUG_CONDITION
278 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
286 #ifdef DEBUG_CONDITION
287 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
289 SetEvent(m_condition);
300 cerr << "THREAD DEBUG: Created thread object " << this << endl;
307 cerr << "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id << endl;
310 pthread_join(m_id, 0);
313 cerr << "THREAD DEBUG: Destroyed thread object " << this << endl;
320 if (pthread_create(&m_id, 0, staticRun, this)) {
321 cerr << "ERROR: thread creation failed" << endl;
325 cerr << "THREAD DEBUG: Created thread " << m_id << " for thread object " << this << endl;
336 cerr << "THREAD DEBUG: Waiting on thread " << m_id << " for thread object " << this << endl;
338 pthread_join(m_id, 0);
340 cerr << "THREAD DEBUG: Waited on thread " << m_id << " for thread object " << this << endl;
353 Thread::threadingAvailable()
359 Thread::staticRun(void *arg)
361 Thread *thread = static_cast<Thread *>(arg);
363 cerr << "THREAD DEBUG: " << (void *)pthread_self() << ": Running thread " << thread->m_id << " for thread object " << thread << endl;
370 #ifndef NO_THREAD_CHECKS
376 pthread_mutex_init(&m_mutex, 0);
378 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Initialised mutex " << &m_mutex << endl;
385 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Destroying mutex " << &m_mutex << endl;
387 pthread_mutex_destroy(&m_mutex);
393 #ifndef NO_THREAD_CHECKS
394 pthread_t tid = pthread_self();
395 if (m_locked && m_lockedBy == tid) {
396 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
400 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
402 pthread_mutex_lock(&m_mutex);
403 #ifndef NO_THREAD_CHECKS
408 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
415 #ifndef NO_THREAD_CHECKS
416 pthread_t tid = pthread_self();
418 cerr << "ERROR: Mutex " << &m_mutex << " not locked in unlock" << endl;
420 } else if (m_lockedBy != tid) {
421 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
426 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
428 #ifndef NO_THREAD_CHECKS
431 pthread_mutex_unlock(&m_mutex);
437 #ifndef NO_THREAD_CHECKS
438 pthread_t tid = pthread_self();
440 if (pthread_mutex_trylock(&m_mutex)) {
442 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
446 #ifndef NO_THREAD_CHECKS
451 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
457 Condition::Condition(string /*name*/) :
459 #ifdef DEBUG_CONDITION
463 pthread_mutex_init(&m_mutex, 0);
464 pthread_cond_init(&m_condition, 0);
465 #ifdef DEBUG_CONDITION
466 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Initialised condition " << &m_condition << " \"" << m_name << "\"" << endl;
470 Condition::~Condition()
472 #ifdef DEBUG_CONDITION
473 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Destroying condition " << &m_condition << " \"" << m_name << "\"" << endl;
475 if (m_locked) pthread_mutex_unlock(&m_mutex);
476 pthread_cond_destroy(&m_condition);
477 pthread_mutex_destroy(&m_mutex);
484 #ifdef DEBUG_CONDITION
485 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Already locked " << &m_condition << " \"" << m_name << "\"" << endl;
489 #ifdef DEBUG_CONDITION
490 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
492 pthread_mutex_lock(&m_mutex);
494 #ifdef DEBUG_CONDITION
495 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Locked " << &m_condition << " \"" << m_name << "\"" << endl;
503 #ifdef DEBUG_CONDITION
504 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Not locked " << &m_condition << " \"" << m_name << "\"" << endl;
508 #ifdef DEBUG_CONDITION
509 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Unlocking " << &m_condition << " \"" << m_name << "\"" << endl;
512 pthread_mutex_unlock(&m_mutex);
516 Condition::wait(int us)
518 if (!m_locked) lock();
522 #ifdef DEBUG_CONDITION
523 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
525 pthread_cond_wait(&m_condition, &m_mutex);
530 gettimeofday(&now, 0);
533 while (now.tv_usec > 1000000) {
534 now.tv_usec -= 1000000;
538 struct timespec timeout;
539 timeout.tv_sec = now.tv_sec;
540 timeout.tv_nsec = now.tv_usec * 1000;
542 #ifdef DEBUG_CONDITION
543 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Timed waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
545 pthread_cond_timedwait(&m_condition, &m_mutex, &timeout);
548 pthread_mutex_unlock(&m_mutex);
550 #ifdef DEBUG_CONDITION
551 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
559 #ifdef DEBUG_CONDITION
560 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
562 pthread_cond_signal(&m_condition);
567 MutexLocker::MutexLocker(Mutex *mutex) :
575 MutexLocker::~MutexLocker()