CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

ThreadUtilities.cpp
Go to the documentation of this file.
1 //
2 // ThreadUtilities.cpp -- cross-platform Thread Utilities
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5
6 #include "ThreadUtilities.h"
7 #include "CGestalt.h"
8
9 using namespace csl;
10
11 #ifdef USE_JTHREADS
12
13 // Thread is now concrete
14
15 CThread * CThread::MakeThread() {
16 return new CThread();
17 }
18
19 int CThread::createThread(VoidFcnPtr * func, void * args) {
20 (*func)(args); // call my function
21 return 0;
22 }
23
24 //int CThread::createRealtimeThread(VOIDFCNPTR * func, void * args) {
25 // mFunc = * func;
26 // mArgs = args;
27 // run();
28 // return 0;
29 //}
30
31 void CThread::run() {
32 logMsg("Start thread");
33 (*mFunc)(mArgs); // call my function
34 }
35
36 #else
37
38 // This CThread uses pthreads
39
40 CThread * CThread::MakeThread() {
41 return new ThreadPthread();
42 }
43
44 Synch *Synch::MakeSynch() { return new SynchPthread(); }
45
46 // ~~~~~ SyncPthread Implementation ~~~~~
47
48 // Constructor
49
50 SynchPthread::SynchPthread() {
51 pthread_mutex_init(& mMutex, NULL);
52 pthread_cond_init(& mCond, NULL);
53 }
54
55 SynchPthread::~SynchPthread() {
56 pthread_mutex_destroy(&mMutex);
57 pthread_cond_destroy(&mCond);
58 }
59
60 // The following functions are just wrappers around the pthreads respective commands.
61
62 int SynchPthread::lock() { return pthread_mutex_lock(&mMutex); }
63
64 int SynchPthread::unlock() { return pthread_mutex_unlock(&mMutex); }
65
66 int SynchPthread::condWait() { return pthread_cond_wait(&mCond, &mMutex); }
67
68 int SynchPthread::condSignal() { return pthread_cond_signal(&mCond); }
69
70 // ~~~~~ ThreadPthread Implementation ~~~~~
71
72 // Constructor and destructor for windows and other systems.
73
74 #ifdef CSL_WINDOWS
75
76 ThreadPthread::ThreadPthread() : CThread () /*, mThread(NULL)*/ {
77 pthread_attr_init(&mAttributes);
78 }
79
80 ThreadPthread::~ThreadPthread() {
81 pthread_attr_destroy(&mAttributes);
82 // if (mThread)
83 // pthread_cancel(mThread);
84 }
85
86 #else
87
88 ThreadPthread::ThreadPthread() : CThread(), mThread(NULL) {
89 pthread_attr_init(&mAttributes);
90 }
91
92 ThreadPthread::~ThreadPthread() {
93 pthread_attr_destroy(&mAttributes);
94 if (mThread)
95 pthread_cancel(mThread);
96 }
97
98 #endif
99
100 int ThreadPthread::createThread(VoidFcnPtr * func, void * args) {
101 pthread_attr_setdetachstate(&mAttributes, PTHREAD_CREATE_DETACHED);
102 pthread_attr_setscope(&mAttributes, PTHREAD_SCOPE_SYSTEM);
103 return pthread_create(&mThread, &mAttributes, func, args);
104 }
105
106 #ifdef CSL_MACOSX_OLD_WAY
107
108 // Most of the code in these two functions is taken from Apple PlayAudioFile example
109
110 #include <mach/mach.h> // used for setting policy of thread
111
112 unsigned GetThreadBasePriority (pthread_t inThread) {
113 thread_basic_info_data_t threadInfo;
114 policy_info_data_t thePolicyInfo;
115 unsigned int count;
116
117 // get basic info
118 count = THREAD_BASIC_INFO_COUNT;
119 thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, (integer_t*)&threadInfo, &count);
120 switch (threadInfo.policy) {
121 case POLICY_TIMESHARE:
122 count = POLICY_TIMESHARE_INFO_COUNT;
123 thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_TIMESHARE_INFO, (integer_t*)&(thePolicyInfo.ts), &count);
124 return thePolicyInfo.ts.base_priority;
125 break;
126 case POLICY_FIFO:
127 count = POLICY_FIFO_INFO_COUNT;
128 thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_FIFO_INFO, (integer_t*)&(thePolicyInfo.fifo), &count);
129 if (thePolicyInfo.fifo.depressed) {
130 return thePolicyInfo.fifo.depress_priority;
131 } else {
132 return thePolicyInfo.fifo.base_priority;
133 }
134 break;
135 case POLICY_RR:
136 count = POLICY_RR_INFO_COUNT;
137 thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_RR_INFO, (integer_t*)&(thePolicyInfo.rr), &count);
138 if (thePolicyInfo.rr.depressed)
139 return thePolicyInfo.rr.depress_priority;
140 else
141 return thePolicyInfo.rr.base_priority;
142 break;
143 }
144 return 0;
145 }
146
147 int ThreadPthread::createRealtimeThread(VoidFcnPtr * func, void* args) {
148 // first create a thread
149 int value = createThread(func, args);
150 int result;
151 int threadPriority = 62; // the number in Apple's example code
152
153 // bump up the priority and make it fixed priority
154 // code taken from Apple PlayAudioFile example
155 thread_extended_policy_data_t theFixedPolicy;
156 thread_precedence_policy_data_t thePrecedencePolicy;
157 int relativePriority;
158 // make thread fixed
159 theFixedPolicy.timeshare = false; // set to true for a non-fixed thread
160 result = thread_policy_set (pthread_mach_thread_np(mThread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT);
161 // set priority
162 // precedency policy's "importance" value is relative to spawning thread's priority
163 relativePriority = threadPriority - GetThreadBasePriority (pthread_self());
164 thePrecedencePolicy.importance = relativePriority;
165 result = thread_policy_set (pthread_mach_thread_np(mThread), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT);
166 return value;
167 }
168
169 #else
170
171 //int ThreadPthread::createRealtimeThread(VOIDFCNPTR * func, void* args) {
172 // return createThread(func, args);
173 //}
174
175 #endif
176
177 #endif
178