Thread.h

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 
00018 #ifndef _OASYS_THREAD_H_
00019 #define _OASYS_THREAD_H_
00020 
00021 #include "config.h"
00022 
00023 #include <sys/types.h>
00024 
00025 #ifdef __win32__
00026 
00027 #include <Windows.h>
00028 
00029 #else
00030 
00031 #include <pthread.h>
00032 #include <signal.h>
00033 
00034 #ifdef HAVE_SCHED_YIELD
00035 #include <sched.h>
00036 #endif
00037 
00038 #endif // __win32__
00039 
00040 #include <vector>
00041 
00042 #include "../debug/DebugUtils.h"
00043 
00044 namespace oasys {
00045 
00046 #ifdef __win32__
00047 typedef DWORD     ThreadId_t;
00048 #else
00049 typedef pthread_t ThreadId_t;
00050 #endif
00051 
00052 class SpinLock;
00053 
00059 class Thread {
00060 public:
00064     enum thread_flags_t { 
00067         CREATE_JOINABLE = 1 << 0,
00069         DELETE_ON_EXIT  = 1 << 1,
00071         INTERRUPTABLE   = 1 << 2,
00073         STARTED         = 1 << 3,
00075         SHOULD_STOP     = 1 << 4,
00077         STOPPED         = 1 << 5,
00078     };
00079 
00080 #ifndef __win32__
00081 
00085     enum thread_signal_t {
00086         INTERRUPT_SIG = SIGURG
00087     };
00088 #endif
00089 
00093     static const int max_live_threads_ = 256;
00094 
00099     static Thread* all_threads_[Thread::max_live_threads_];
00100 
00105     static SpinLock* all_threads_lock_;
00106 
00114     static void activate_start_barrier();
00115     
00120     static void release_start_barrier();
00121     
00125     static bool start_barrier_enabled() { 
00126         return start_barrier_enabled_;
00127     }
00128 
00134     static void yield();
00135 
00145     static void spin_yield();
00146 
00153     static ThreadId_t current();
00154 
00158     static bool id_equal(ThreadId_t a, ThreadId_t b);
00159 
00163     Thread(const char* name, int flags = 0);
00164 
00168     virtual ~Thread();
00169     
00174     void start();
00175 
00179     void join();
00180 
00184     void kill(int sig);
00185 
00193     void interrupt();
00194 
00204     void set_interruptable(bool interruptable);
00205     
00213     void set_should_stop() { flags_ |= SHOULD_STOP; }
00214 
00218     bool should_stop() { return ((flags_ & SHOULD_STOP) != 0); }
00219     
00223     bool is_stopped() { return ((flags_ & STOPPED) != 0); }
00224 
00228     bool started() { return ((flags_ & STARTED) != 0); }
00229 
00233     void set_flag(thread_flags_t flag) { flags_ |= flag; }
00234 
00238     void clear_flag(thread_flags_t flag) { flags_ &= ~flag; }
00239     
00244     ThreadId_t thread_id() { return thread_id_; }
00245     
00246 protected:
00247 #ifdef __win32__
00249     static __declspec(thread) Thread* current_thread_;
00250     HANDLE join_event_;
00251 #endif // __win32__
00252 
00253 #ifndef __win32__
00254     static bool     signals_inited_;
00255     static sigset_t interrupt_sigset_;
00256 #endif    
00257 
00258     static bool                 start_barrier_enabled_;
00259     static std::vector<Thread*> threads_in_barrier_;
00260 
00261     ThreadId_t thread_id_;
00262     int        flags_;
00263     char       name_[64];
00264 
00268 #ifdef __win32__
00269     static DWORD WINAPI pre_thread_run(void* t);
00270 #else
00271     static void* pre_thread_run(void* t);
00272 #endif
00273 
00277     static void interrupt_signal(int sig);
00278 
00283     void thread_run(const char* thread_name, ThreadId_t thread_id);
00284 
00289     virtual void run() = 0;
00290 };
00291 
00292 //---------------------------------------------------------------------------
00293 inline ThreadId_t
00294 Thread::current()
00295 {
00296 #ifdef __win32__
00297     return current_thread_->thread_id_;
00298 #else
00299     return pthread_self();
00300 #endif
00301 }
00302 
00303 //---------------------------------------------------------------------------
00304 inline void
00305 Thread::yield()
00306 {
00307 #ifndef __win32__
00308 #ifdef HAVE_THREAD_ID_YIELD
00309     thread_id_yield();
00310 #elif  HAVE_SCHED_YIELD
00311     sched_yield();
00312 #else
00313 #error MUST EITHER HAVE THREAD_ID_YIELD OR SCHED_YIELD
00314 #endif
00315 #endif // __win32__
00316 }
00317 
00318 //---------------------------------------------------------------------------
00319 inline void
00320 Thread::spin_yield()
00321 {
00322     // XXX/bowei: 
00323     // 1-p call yield()
00324     // o.w. spin
00325     Thread::yield();
00326 }
00327 
00328 } // namespace oasys
00329 
00330 #endif /* _OASYS_THREAD_H_ */

Generated on Sat Sep 8 08:36:18 2007 for DTN Reference Implementation by  doxygen 1.5.3