00001
00002 #ifndef _JOT_STD_THREAD_H
00003 #define _JOT_STD_THREAD_H
00004 #include "std/support.H"
00005 #include "thread_mutex.H"
00006
00007
00008
00009
00010 #ifdef USE_PTHREAD
00011 #if defined(sun) && !defined(_REENTRANT)
00012
00013 Need to compile thread stuff with -mt under Solaris
00014 #endif
00015 #include <pthread.h>
00016
00017 class Thread {
00018 public:
00019 Thread() { _running = false; }
00020 virtual ~Thread() { if (_running) pthread_cancel(_thread); }
00021
00022 void start() {
00023 pthread_attr_t attr;
00024 int retval;
00025 if ((retval = pthread_attr_init(&attr)) != 0)
00026 {
00027 err_msg("Thread:start - pthread_attr_init returned %d: %s", retval,strerror(errno));
00028 exit(1);
00029 }
00030 if ((retval=pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) != 0)
00031 {
00032
00033 err_msg("Thread:start - pthread_attr_setscope: %s", strerror(retval));
00034 exit(1);
00035 }
00036 _running = !pthread_create(&_thread, &attr, kickstart, (void *)this);
00037 pthread_attr_destroy(&attr);
00038 }
00039 protected:
00040 virtual void threadProc() = 0;
00041
00042 private:
00043 bool _running;
00044 pthread_t _thread;
00045 static void *kickstart(void *me) { ((Thread *)me)->threadProc();
00046 return 0; }
00047 };
00048
00049
00050 class ThreadSync {
00051 private:
00052 pthread_mutex_t mut_;
00053 pthread_cond_t queue_;
00054 int count_;
00055 const int number_;
00056 int generation_;
00057
00058 public:
00059 ThreadSync(int number): number_(number) {
00060 pthread_mutex_init(&mut_, 0);
00061 pthread_cond_init(&queue_, 0);
00062 count_ = 0;
00063 generation_ = 0;
00064 }
00065
00066 ~ThreadSync() {
00067 pthread_mutex_destroy(&mut_);
00068 pthread_cond_destroy(&queue_);
00069 }
00070
00071 #ifndef sgi
00072 void wait() {
00073 pthread_mutex_lock(&mut_);
00074 if (++count_ < number_) {
00075 int my_generation = generation_;
00076 while(my_generation == generation_)
00077 pthread_cond_wait(&queue_, &mut_);
00078 } else {
00079 count_ = 0;
00080 generation_++;
00081 pthread_cond_broadcast(&queue_);
00082 }
00083 pthread_mutex_unlock(&mut_);
00084 }
00085 #else
00086 void wait() {
00087 pthread_mutex_lock(&mut_);
00088 if (++count_ < number_) {
00089 assert((count_ < number_) && (count_ > 0));
00090 int my_generation = generation_;
00091 pthread_mutex_unlock(&mut_);
00092 while(my_generation == generation_)
00093 ;
00094 } else {
00095 count_ = 0;
00096 generation_++;
00097 pthread_mutex_unlock(&mut_);
00098 }
00099 }
00100 #endif
00101 };
00102
00103 class ThreadData {
00104 public:
00105 ThreadData() : _key(0) { }
00106
00107 void create() {
00108 if (pthread_key_create(&_key, 0)) {
00109 cerr << "ThreadData::create - Could not create key" << endl;
00110 }
00111 }
00112
00113 void set(void *val) { pthread_setspecific(_key, val);}
00114 void *get() { return pthread_getspecific(_key);}
00115 protected:
00116 pthread_key_t _key;
00117 };
00118 #endif
00119 #endif