CSL  5.2
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 
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 
41  return new ThreadPthread();
42 }
43 
44 Synch *Synch::MakeSynch() { return new SynchPthread(); }
45 
46 // ~~~~~ SyncPthread Implementation ~~~~~
47 
48 // Constructor
49 
51  pthread_mutex_init(& mMutex, NULL);
52  pthread_cond_init(& mCond, NULL);
53 }
54 
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 
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 
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