cannam@62
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
cannam@62
|
2
|
cannam@62
|
3 /*
|
cannam@62
|
4 QM DSP Library
|
cannam@62
|
5
|
cannam@62
|
6 Centre for Digital Music, Queen Mary, University of London.
|
cannam@62
|
7 This file copyright Chris Cannam, used with permission.
|
cannam@62
|
8 */
|
cannam@62
|
9
|
cannam@62
|
10 #ifndef _THREAD_H_
|
cannam@62
|
11 #define _THREAD_H_
|
cannam@62
|
12
|
cannam@62
|
13 #ifdef _WIN32
|
cannam@62
|
14 #include <windows.h>
|
cannam@62
|
15 #else /* !_WIN32 */
|
cannam@62
|
16 #ifdef USE_PTHREADS
|
cannam@62
|
17 #include <pthread.h>
|
cannam@62
|
18 #endif /* USE_PTHREADS */
|
cannam@62
|
19 #endif /* !_WIN32 */
|
cannam@62
|
20
|
cannam@62
|
21 #include <string>
|
cannam@62
|
22
|
cannam@62
|
23 //#define DEBUG_THREAD 1
|
cannam@62
|
24 //#define DEBUG_MUTEX 1
|
cannam@62
|
25 //#define DEBUG_CONDITION 1
|
cannam@62
|
26
|
cannam@62
|
27 class Thread
|
cannam@62
|
28 {
|
cannam@62
|
29 public:
|
cannam@62
|
30 #ifdef _WIN32
|
cannam@62
|
31 typedef HANDLE Id;
|
cannam@62
|
32 #else
|
cannam@62
|
33 #ifdef USE_PTHREADS
|
cannam@62
|
34 typedef pthread_t Id;
|
cannam@62
|
35 #endif
|
cannam@62
|
36 #endif
|
cannam@62
|
37
|
cannam@62
|
38 Thread();
|
cannam@62
|
39 virtual ~Thread();
|
cannam@62
|
40
|
cannam@62
|
41 Id id();
|
cannam@62
|
42
|
cannam@62
|
43 void start();
|
cannam@62
|
44 void wait();
|
cannam@62
|
45
|
cannam@62
|
46 static bool threadingAvailable();
|
cannam@62
|
47
|
cannam@62
|
48 protected:
|
cannam@62
|
49 virtual void run() = 0;
|
cannam@62
|
50
|
cannam@62
|
51 private:
|
cannam@62
|
52 #ifdef _WIN32
|
cannam@62
|
53 HANDLE m_id;
|
cannam@62
|
54 bool m_extant;
|
cannam@62
|
55 static DWORD WINAPI staticRun(LPVOID lpParam);
|
cannam@62
|
56 #else
|
cannam@62
|
57 #ifdef USE_PTHREADS
|
cannam@62
|
58 pthread_t m_id;
|
cannam@62
|
59 bool m_extant;
|
cannam@62
|
60 static void *staticRun(void *);
|
cannam@62
|
61 #endif
|
cannam@62
|
62 #endif
|
cannam@62
|
63 };
|
cannam@62
|
64
|
cannam@62
|
65 class Mutex
|
cannam@62
|
66 {
|
cannam@62
|
67 public:
|
cannam@62
|
68 Mutex();
|
cannam@62
|
69 ~Mutex();
|
cannam@62
|
70
|
cannam@62
|
71 void lock();
|
cannam@62
|
72 void unlock();
|
cannam@62
|
73 bool trylock();
|
cannam@62
|
74
|
cannam@62
|
75 private:
|
cannam@62
|
76 #ifdef _WIN32
|
cannam@62
|
77 HANDLE m_mutex;
|
cannam@62
|
78 #ifndef NO_THREAD_CHECKS
|
cannam@62
|
79 DWORD m_lockedBy;
|
cannam@62
|
80 #endif
|
cannam@62
|
81 #else
|
cannam@62
|
82 #ifdef USE_PTHREADS
|
cannam@62
|
83 pthread_mutex_t m_mutex;
|
cannam@62
|
84 #ifndef NO_THREAD_CHECKS
|
cannam@62
|
85 pthread_t m_lockedBy;
|
cannam@62
|
86 bool m_locked;
|
cannam@62
|
87 #endif
|
cannam@62
|
88 #endif
|
cannam@62
|
89 #endif
|
cannam@62
|
90 };
|
cannam@62
|
91
|
cannam@62
|
92 class MutexLocker
|
cannam@62
|
93 {
|
cannam@62
|
94 public:
|
cannam@62
|
95 MutexLocker(Mutex *);
|
cannam@62
|
96 ~MutexLocker();
|
cannam@62
|
97
|
cannam@62
|
98 private:
|
cannam@62
|
99 Mutex *m_mutex;
|
cannam@62
|
100 };
|
cannam@62
|
101
|
cannam@62
|
102 class Condition
|
cannam@62
|
103 {
|
cannam@62
|
104 public:
|
cannam@62
|
105 Condition(std::string name);
|
cannam@62
|
106 ~Condition();
|
cannam@62
|
107
|
cannam@62
|
108 //!!! NO -- reproducing more conventional lock/wait
|
cannam@62
|
109
|
cannam@62
|
110 // To wait on a condition, either simply call wait(), or call
|
cannam@62
|
111 // lock() and then wait() (perhaps testing some state in between).
|
cannam@62
|
112 // To signal a condition, call signal().
|
cannam@62
|
113
|
cannam@62
|
114 // Although any thread may signal on a given condition, only one
|
cannam@62
|
115 // thread should ever wait on any given condition object --
|
cannam@62
|
116 // otherwise there will be a race conditions in the logic that
|
cannam@62
|
117 // avoids the thread code having to track whether the condition's
|
cannam@62
|
118 // mutex is locked or not. If that is your requirement, this
|
cannam@62
|
119 // Condition wrapper is not for you.
|
cannam@62
|
120 void lock();
|
cannam@62
|
121 void unlock();
|
cannam@62
|
122 void wait(int us = 0);
|
cannam@62
|
123
|
cannam@62
|
124 void signal();
|
cannam@62
|
125
|
cannam@62
|
126 private:
|
cannam@62
|
127
|
cannam@62
|
128 #ifdef _WIN32
|
cannam@62
|
129 HANDLE m_mutex;
|
cannam@62
|
130 HANDLE m_condition;
|
cannam@62
|
131 bool m_locked;
|
cannam@62
|
132 #else
|
cannam@62
|
133 #ifdef USE_PTHREADS
|
cannam@62
|
134 pthread_mutex_t m_mutex;
|
cannam@62
|
135 pthread_cond_t m_condition;
|
cannam@62
|
136 bool m_locked;
|
cannam@62
|
137 #endif
|
cannam@62
|
138 #endif
|
cannam@62
|
139 #ifdef DEBUG_CONDITION
|
cannam@62
|
140 std::string m_name;
|
cannam@62
|
141 #endif
|
cannam@62
|
142 };
|
cannam@62
|
143
|
cannam@62
|
144 #endif
|