00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _INCLUDED_MLD_THREADS_H_
00026 #define _INCLUDED_MLD_THREADS_H_
00027
00028
00029
00030 #ifdef _USE_OMNI_THREADS_
00031 #include <gnuradio/omnithread.h>
00032 #else
00033 #include <pthread.h>
00034 #endif
00035
00036 #include <stdexcept>
00037
00038 #define __INLINE__ inline
00039
00040 class mld_condition_t;
00041
00042 class mld_mutex_t {
00043 #ifdef _USE_OMNI_THREADS_
00044 typedef omni_mutex l_mutex, *l_mutex_ptr;
00045 #else
00046 typedef pthread_mutex_t l_mutex, *l_mutex_ptr;
00047 #endif
00048
00049 friend class mld_condition_t;
00050
00051 private:
00052 l_mutex_ptr d_mutex;
00053
00054 protected:
00055 inline l_mutex_ptr mutex () { return (d_mutex); };
00056
00057 public:
00058 __INLINE__ mld_mutex_t () {
00059 #ifdef _USE_OMNI_THREADS_
00060 d_mutex = new omni_mutex ();
00061 #else
00062 d_mutex = (l_mutex_ptr) new l_mutex;
00063 int l_ret = pthread_mutex_init (d_mutex, NULL);
00064 if (l_ret != 0) {
00065 fprintf (stderr, "Error %d creating mutex.\n", l_ret);
00066 throw std::runtime_error ("mld_mutex_t::mld_mutex_t()\n");
00067 }
00068 #endif
00069 };
00070
00071 __INLINE__ ~mld_mutex_t () {
00072 unlock ();
00073 #ifndef _USE_OMNI_THREADS_
00074 int l_ret = pthread_mutex_destroy (d_mutex);
00075 if (l_ret != 0) {
00076 fprintf (stderr, "mld_mutex_t::~mld_mutex_t(): "
00077 "Error %d destroying mutex.\n", l_ret);
00078 }
00079 #endif
00080 delete d_mutex;
00081 d_mutex = NULL;
00082 };
00083
00084 __INLINE__ void lock () {
00085 #ifdef _USE_OMNI_THREADS_
00086 d_mutex->lock ();
00087 #else
00088 int l_ret = pthread_mutex_lock (d_mutex);
00089 if (l_ret != 0) {
00090 fprintf (stderr, "mld_mutex_t::lock(): "
00091 "Error %d locking mutex.\n", l_ret);
00092 }
00093 #endif
00094 };
00095
00096 __INLINE__ void unlock () {
00097 #ifdef _USE_OMNI_THREADS_
00098 d_mutex->unlock ();
00099 #else
00100 int l_ret = pthread_mutex_unlock (d_mutex);
00101 if (l_ret != 0) {
00102 fprintf (stderr, "mld_mutex_t::unlock(): "
00103 "Error %d locking mutex.\n", l_ret);
00104 }
00105 #endif
00106 };
00107
00108 __INLINE__ bool trylock () {
00109 #ifdef _USE_OMNI_THREADS_
00110 int l_ret = d_mutex->trylock ();
00111 #else
00112 int l_ret = pthread_mutex_unlock (d_mutex);
00113 #endif
00114 return (l_ret == 0 ? true : false);
00115 };
00116
00117 inline void acquire () { lock(); };
00118 inline void release () { unlock(); };
00119 inline void wait () { lock(); };
00120 inline void post () { unlock(); };
00121 };
00122
00123 typedef mld_mutex_t mld_mutex, *mld_mutex_ptr;
00124
00125 class mld_condition_t {
00126 #ifdef _USE_OMNI_THREADS_
00127 typedef omni_condition l_condition, *l_condition_ptr;
00128 #else
00129 typedef pthread_cond_t l_condition, *l_condition_ptr;
00130 #endif
00131
00132 private:
00133 l_condition_ptr d_condition;
00134 mld_mutex_ptr d_mutex;
00135 bool d_waiting;
00136
00137 public:
00138 __INLINE__ mld_condition_t () {
00139 d_waiting = false;
00140 d_mutex = new mld_mutex ();
00141 #ifdef _USE_OMNI_THREADS_
00142 d_condition = new omni_condition (d_mutex->mutex ());
00143 #else
00144 d_condition = (l_condition_ptr) new l_condition;
00145 int l_ret = pthread_cond_init (d_condition, NULL);
00146 if (l_ret != 0) {
00147 fprintf (stderr, "Error %d creating condition.\n", l_ret);
00148 throw std::runtime_error ("mld_condition_t::mld_condition_t()\n");
00149 }
00150 #endif
00151 };
00152
00153 __INLINE__ ~mld_condition_t () {
00154 signal ();
00155 #ifndef _USE_OMNI_THREADS_
00156 int l_ret = pthread_cond_destroy (d_condition);
00157 if (l_ret != 0) {
00158 fprintf (stderr, "mld_condition_t::mld_condition_t(): "
00159 "Error %d destroying condition.\n", l_ret);
00160 }
00161 #endif
00162 delete d_condition;
00163 d_condition = NULL;
00164 delete d_mutex;
00165 d_mutex = NULL;
00166 };
00167
00168 __INLINE__ void signal () {
00169 if (d_waiting == true) {
00170 #ifdef _USE_OMNI_THREADS_
00171 d_condition->signal ();
00172 #else
00173 int l_ret = pthread_cond_signal (d_condition);
00174 if (l_ret != 0) {
00175 fprintf (stderr, "mld_condition_t::signal(): "
00176 "Error %d.\n", l_ret);
00177 }
00178 #endif
00179 d_waiting = false;
00180 }
00181 };
00182
00183 __INLINE__ void wait () {
00184 if (d_waiting == false) {
00185 d_waiting = true;
00186 #ifdef _USE_OMNI_THREADS_
00187 d_condition->wait ();
00188 #else
00189 int l_ret = pthread_cond_wait (d_condition, d_mutex->mutex ());
00190 if (l_ret != 0) {
00191 fprintf (stderr, "mld_condition_t::wait(): "
00192 "Error %d.\n", l_ret);
00193 }
00194 #endif
00195 }
00196 };
00197 };
00198
00199 typedef mld_condition_t mld_condition, *mld_condition_ptr;
00200
00201 class mld_thread_t {
00202 #ifdef _USE_OMNI_THREADS_
00203 typedef omni_thread l_thread, *l_thread_ptr;
00204 #else
00205 typedef pthread_t l_thread, *l_thread_ptr;
00206 #endif
00207
00208 private:
00209 #ifndef _USE_OMNI_THREADS_
00210 l_thread d_thread;
00211 void (*d_start_routine)(void*);
00212 void *d_arg;
00213 #else
00214 l_thread_ptr d_thread;
00215 #endif
00216
00217 #ifndef _USE_OMNI_THREADS_
00218 static void* local_start_routine (void *arg) {
00219 mld_thread_t* This = (mld_thread_t*) arg;
00220 (*(This->d_start_routine))(This->d_arg);
00221 return (NULL);
00222 };
00223 #endif
00224
00225 public:
00226 __INLINE__ mld_thread_t (void (*start_routine)(void *), void *arg) {
00227 #ifdef _USE_OMNI_THREADS_
00228 d_thread = new omni_thread (start_routine, arg);
00229 d_thread->start ();
00230 #else
00231 d_start_routine = start_routine;
00232 d_arg = arg;
00233 int l_ret = pthread_create (&d_thread, NULL, local_start_routine, this);
00234 if (l_ret != 0) {
00235 fprintf (stderr, "Error %d creating thread.\n", l_ret);
00236 throw std::runtime_error ("mld_thread_t::mld_thread_t()\n");
00237 }
00238 #endif
00239 };
00240
00241 __INLINE__ ~mld_thread_t () {
00242 #ifdef _USE_OMNI_THREADS_
00243
00244 d_thread = NULL;
00245 #else
00246 int l_ret = pthread_detach (d_thread);
00247 if (l_ret != 0) {
00248 fprintf (stderr, "Error %d detaching thread.\n", l_ret);
00249 throw std::runtime_error ("mld_thread_t::~mld_thread_t()\n");
00250 }
00251 #endif
00252 };
00253 };
00254
00255 typedef mld_thread_t mld_thread, *mld_thread_ptr;
00256
00257 #endif