/[svn]/linuxsampler/trunk/src/common/Thread.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/common/Thread.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1480 by schoenebeck, Sun Oct 14 22:00:17 2007 UTC revision 1481 by senoner, Wed Nov 14 23:42:15 2007 UTC
# Line 31  Line 31 
31    
32  namespace LinuxSampler {  namespace LinuxSampler {
33    
34    #if defined(WIN32)
35    // Callback functions for the WIN32 thread API
36    DWORD WINAPI __win32thread_launcher(LPVOID lpParameter);
37    #else
38  // Callback functions for the POSIX thread API  // Callback functions for the POSIX thread API
39  static void* __pthread_launcher(void* thread);  static void* __pthread_launcher(void* thread);
40  static void  __pthread_destructor(void* thread);  static void  __pthread_destructor(void* thread);
41    #endif
42    
43  Thread::Thread(bool LockMemory, bool RealTime, int PriorityMax, int PriorityDelta) {  Thread::Thread(bool LockMemory, bool RealTime, int PriorityMax, int PriorityDelta) {
44      this->bLockedMemory     = LockMemory;      this->bLockedMemory     = LockMemory;
45      this->isRealTime        = RealTime;      this->isRealTime        = RealTime;
46      this->PriorityDelta     = PriorityDelta;      this->PriorityDelta     = PriorityDelta;
47      this->PriorityMax       = PriorityMax;      this->PriorityMax       = PriorityMax;
48    #if defined(WIN32)
49    #if defined(WIN32_SIGNALSTARTTHREAD_WORKAROUND)
50        win32isRunning = false;
51    #endif
52    #else
53      __thread_destructor_key = 0;      __thread_destructor_key = 0;
54      pthread_attr_init(&__thread_attr);      pthread_attr_init(&__thread_attr);
55    #endif
56  }  }
57    
58  Thread::~Thread() {  Thread::~Thread() {
59      StopThread();      StopThread();
60    #if defined(WIN32)
61    #else
62      pthread_attr_destroy(&__thread_attr);      pthread_attr_destroy(&__thread_attr);
63    #endif
64  }  }
65    
66  /**  /**
# Line 56  Thread::~Thread() { Line 70  Thread::~Thread() {
70   *  Main() method in your subclass.   *  Main() method in your subclass.
71   */   */
72  int Thread::StartThread() {  int Thread::StartThread() {
73    #if defined (WIN32_SIGNALSTARTTHREAD_WORKAROUND)
74        // poll the win32isRunning variable and sleep 1msec inbetween
75        if(!win32isRunning) {
76            SignalStartThread();
77            while(1) {
78                Sleep(1);
79                if(win32isRunning) break;
80            }
81        }
82        return 0;
83    #else
84      RunningCondition.Lock();      RunningCondition.Lock();
85      if (!RunningCondition.GetUnsafe()) {      if (!RunningCondition.GetUnsafe()) {
86          SignalStartThread();          SignalStartThread();
# Line 64  int Thread::StartThread() { Line 89  int Thread::StartThread() {
89      }      }
90      RunningCondition.Unlock();      RunningCondition.Unlock();
91      return 0;      return 0;
92    #endif
93  }  }
94    
95  /**  /**
# Line 75  int Thread::StartThread() { Line 101  int Thread::StartThread() {
101   *  @see StartThread()   *  @see StartThread()
102   */   */
103  int Thread::SignalStartThread() {  int Thread::SignalStartThread() {
104    #if defined(WIN32)
105        LPVOID lpParameter;
106        hThread = CreateThread(
107                   NULL, // no security attributes
108                   MIN_STACK_SIZE,
109                   __win32thread_launcher,
110                   this,
111                   0,
112                   &lpThreadId);
113        if(hThread == NULL) {
114            std::cerr << "Thread creation failed: Error" << GetLastError() << std::endl << std::flush;
115            #if defined(WIN32_SIGNALSTARTTHREAD_WORKAROUND)
116            win32isRunning = false;
117            #else
118            RunningCondition.Set(false);
119            #endif
120            return -1;
121        }
122        return 0;
123    #else
124      // prepare the thread properties      // prepare the thread properties
125      int res = pthread_attr_setinheritsched(&__thread_attr, PTHREAD_EXPLICIT_SCHED);      int res = pthread_attr_setinheritsched(&__thread_attr, PTHREAD_EXPLICIT_SCHED);
126      if (res) {      if (res) {
# Line 126  int Thread::SignalStartThread() { Line 172  int Thread::SignalStartThread() {
172              break;              break;
173      }      }
174      return res;      return res;
175    #endif
176  }  }
177    
178  /**  /**
# Line 133  int Thread::SignalStartThread() { Line 180  int Thread::SignalStartThread() {
180   *  it's execution before it will return.   *  it's execution before it will return.
181   */   */
182  int Thread::StopThread() {  int Thread::StopThread() {
183    #if defined(WIN32_SIGNALSTARTTHREAD_WORKAROUND)
184        SignalStopThread();
185        win32isRunning = false;
186        return 0;
187    #endif
188      RunningCondition.Lock();      RunningCondition.Lock();
189      if (RunningCondition.GetUnsafe()) {      if (RunningCondition.GetUnsafe()) {
190          SignalStopThread();          SignalStopThread();
191          // wait until thread stopped execution          // wait until thread stopped execution
192          RunningCondition.WaitIf(true);          RunningCondition.WaitIf(true);
193            #if defined(WIN32)
194            #else          
195          pthread_detach(__thread_id);          pthread_detach(__thread_id);
196            #endif          
197      }      }
198      RunningCondition.Unlock();      RunningCondition.Unlock();
199      return 0;      return 0;
# Line 153  int Thread::StopThread() { Line 208  int Thread::StopThread() {
208   */   */
209  int Thread::SignalStopThread() {  int Thread::SignalStopThread() {
210      //FIXME: segfaults when thread is not yet running      //FIXME: segfaults when thread is not yet running
211    #if defined(WIN32)
212        BOOL res;
213        res = TerminateThread(hThread, 0); // we set ExitCode to 0
214        //res = WaitForSingleObject( hThread, INFINITE);
215        //myprint(("Thread::SignalStopThread:  WaitForSingleObject( hThread, INFINITE) res=%d\n",res));
216        #if defined(WIN32_SIGNALSTARTTHREAD_WORKAROUND)
217        win32isRunning = false;
218        #else
219        RunningCondition.Set(false);
220        #endif
221    #else  
222      pthread_cancel(__thread_id);      pthread_cancel(__thread_id);
223    #endif  
224      return 0;      return 0;
225  }  }
226    
# Line 161  int Thread::SignalStopThread() { Line 228  int Thread::SignalStopThread() {
228   * Returns @c true in case the thread is currently running.   * Returns @c true in case the thread is currently running.
229   */   */
230  bool Thread::IsRunning() {  bool Thread::IsRunning() {
231        #if defined(WIN32_SIGNALSTARTTHREAD_WORKAROUND)
232        return win32isRunning;
233        #else
234      return RunningCondition.GetUnsafe();      return RunningCondition.GetUnsafe();
235        #endif
236  }  }
237    
238  /**  /**
# Line 172  bool Thread::IsRunning() { Line 243  bool Thread::IsRunning() {
243   *  current priority).   *  current priority).
244   */   */
245  int Thread::SetSchedulingPriority() {  int Thread::SetSchedulingPriority() {
246    #if defined(WIN32)
247        DWORD dwPriorityClass;
248        int nPriority;
249    
250        if(isRealTime) {
251            dwPriorityClass = REALTIME_PRIORITY_CLASS;
252            if (this->PriorityMax == 1) {
253                if(this->PriorityDelta == 0) nPriority = THREAD_PRIORITY_TIME_CRITICAL;
254                else nPriority = 7 + this->PriorityDelta;
255            }
256            else nPriority = THREAD_PRIORITY_NORMAL + this->PriorityDelta;
257        }
258        else {
259            dwPriorityClass = NORMAL_PRIORITY_CLASS;
260            nPriority = THREAD_PRIORITY_NORMAL + this->PriorityDelta;
261        }
262    
263        BOOL res;
264        // FIXME: priority class (realtime) does not work yet, gives error. check why.
265        #if 0
266        res = SetPriorityClass( hThread, dwPriorityClass );
267        if(res == false) {
268            std::cerr << "Thread: WARNING, setPriorityClass " << dwPriorityClass << "failed. Error " << GetLastError() << "\n";
269            return -1;
270        }
271    
272        res = SetThreadPriority( hThread, nPriority );
273        if(res == false) {
274            std::cerr << "Thread: WARNING, setThreadPriority " << nPriority << "failed. Error " << GetLastError() << "\n";
275            return -1;
276        }
277        #endif
278        return 0;
279    #else
280  #if !defined(__APPLE__)  #if !defined(__APPLE__)
281      int policy;      int policy;
282      const char* policyDescription = NULL;      const char* policyDescription = NULL;
# Line 202  int Thread::SetSchedulingPriority() { Line 307  int Thread::SetSchedulingPriority() {
307      }      }
308  #endif  #endif
309      return 0;      return 0;
310    #endif  
311  }  }
312    
313  /**  /**
314   * Locks the memory so it will not be swapped out by the operating system.   * Locks the memory so it will not be swapped out by the operating system.
315   */   */
316  int Thread::LockMemory() {  int Thread::LockMemory() {
317    #if defined(WIN32)
318        return 0;
319    #else
320  #if !defined(__APPLE__)  #if !defined(__APPLE__)
321      if (!bLockedMemory) return 0;      if (!bLockedMemory) return 0;
322      if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) {      if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) {
# Line 217  int Thread::LockMemory() { Line 326  int Thread::LockMemory() {
326      }      }
327  #endif  #endif
328      return 0;      return 0;
329    #endif  
330  }  }
331    
332  /**  /**
# Line 226  int Thread::LockMemory() { Line 336  int Thread::LockMemory() {
336   *  CALL THIS METHOD YOURSELF!   *  CALL THIS METHOD YOURSELF!
337   */   */
338  void Thread::EnableDestructor() {  void Thread::EnableDestructor() {
339    #if defined(WIN32_SIGNALSTARTTHREAD_WORKAROUND)
340        win32isRunning = true;
341        return;    
342    #endif
343      RunningCondition.Lock();      RunningCondition.Lock();
344    #if defined(WIN32)
345    #else  
346      pthread_key_create(&__thread_destructor_key, __pthread_destructor);      pthread_key_create(&__thread_destructor_key, __pthread_destructor);
347      pthread_setspecific(__thread_destructor_key, this);      pthread_setspecific(__thread_destructor_key, this);
348    #endif  
349      RunningCondition.Set(true);      RunningCondition.Set(true);
350      RunningCondition.Unlock();      RunningCondition.Unlock();
351  }  }
# Line 237  void Thread::EnableDestructor() { Line 354  void Thread::EnableDestructor() {
354   *  Will be called by the kernel when the thread stops it's execution.   *  Will be called by the kernel when the thread stops it's execution.
355   */   */
356  int Thread::Destructor() {  int Thread::Destructor() {
357    #if defined(WIN32)
358    #else
359      pthread_key_delete(__thread_destructor_key);      pthread_key_delete(__thread_destructor_key);
360      RunningCondition.Set(false);      RunningCondition.Set(false);
361    #endif  
362      return 0;      return 0;
363  }  }
364    
365    #if defined(WIN32)
366    DWORD WINAPI __win32thread_launcher(LPVOID lpParameter) {
367        Thread* t;
368        t = (Thread*) lpParameter;
369        t->SetSchedulingPriority();
370        t->LockMemory();
371        t->EnableDestructor();
372        t->Main();
373        return 0;
374    }
375    #else
376  /// Callback function for the POSIX thread API  /// Callback function for the POSIX thread API
377  static void* __pthread_launcher(void* thread) {  static void* __pthread_launcher(void* thread) {
378      pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // let the thread be killable under any circumstances      pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // let the thread be killable under any circumstances
# Line 253  static void* __pthread_launcher(void* th Line 384  static void* __pthread_launcher(void* th
384      t->Main();      t->Main();
385      return NULL;      return NULL;
386  }  }
387    #endif
388    
389    #if defined(WIN32)
390    #else
391  /// Callback function for the POSIX thread API  /// Callback function for the POSIX thread API
392  static void __pthread_destructor(void* thread) {  static void __pthread_destructor(void* thread) {
393      Thread* t;      Thread* t;
394      t = (Thread*) thread;      t = (Thread*) thread;
395      t->Destructor();      t->Destructor();
396  }  }
397    #endif
398    
399  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.1480  
changed lines
  Added in v.1481

  ViewVC Help
Powered by ViewVC