Universal Software Radio Peripheral
|
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2006 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio. 00006 * 00007 * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame 00008 * 00009 * GNU Radio is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 3, or (at your option) 00012 * any later version. 00013 * 00014 * GNU Radio is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with GNU Radio; see the file COPYING. If not, write to 00021 * the Free Software Foundation, Inc., 51 Franklin Street, 00022 * Boston, MA 02110-1301, USA. 00023 */ 00024 00025 #ifndef _INCLUDED_MLD_THREADS_H_ 00026 #define _INCLUDED_MLD_THREADS_H_ 00027 00028 /* classes which allow for either pthreads or omni_threads */ 00029 00030 #define __macos__ 00031 #ifdef _USE_OMNI_THREADS_ 00032 #include <gnuradio/omnithread.h> 00033 #else 00034 #include <pthread.h> 00035 #endif 00036 00037 #include <stdexcept> 00038 00039 #define __INLINE__ inline 00040 00041 #ifndef DO_DEBUG 00042 #define DO_DEBUG 0 00043 #endif 00044 00045 #if DO_DEBUG 00046 #define DEBUG(X) do{X} while(0); 00047 #else 00048 #define DEBUG(X) do{} while(0); 00049 #endif 00050 00051 class mld_condition_t; 00052 00053 class mld_mutex_t { 00054 #ifdef _USE_OMNI_THREADS_ 00055 typedef omni_mutex l_mutex, *l_mutex_ptr; 00056 #else 00057 typedef pthread_mutex_t l_mutex, *l_mutex_ptr; 00058 #endif 00059 00060 friend class mld_condition_t; 00061 00062 private: 00063 l_mutex_ptr d_mutex; 00064 00065 protected: 00066 inline l_mutex_ptr mutex () { return (d_mutex); }; 00067 00068 public: 00069 __INLINE__ mld_mutex_t () { 00070 #ifdef _USE_OMNI_THREADS_ 00071 d_mutex = new omni_mutex (); 00072 #else 00073 d_mutex = (l_mutex_ptr) new l_mutex; 00074 int l_ret = pthread_mutex_init (d_mutex, NULL); 00075 if (l_ret != 0) { 00076 fprintf (stderr, "Error %d creating mutex.\n", l_ret); 00077 throw std::runtime_error ("mld_mutex_t::mld_mutex_t()\n"); 00078 } 00079 #endif 00080 }; 00081 00082 __INLINE__ ~mld_mutex_t () { 00083 unlock (); 00084 #ifndef _USE_OMNI_THREADS_ 00085 int l_ret = pthread_mutex_destroy (d_mutex); 00086 if (l_ret != 0) { 00087 fprintf (stderr, "mld_mutex_t::~mld_mutex_t(): " 00088 "Error %d destroying mutex.\n", l_ret); 00089 } 00090 #endif 00091 delete d_mutex; 00092 d_mutex = NULL; 00093 }; 00094 00095 __INLINE__ void lock () { 00096 #ifdef _USE_OMNI_THREADS_ 00097 d_mutex->lock (); 00098 #else 00099 int l_ret = pthread_mutex_lock (d_mutex); 00100 if (l_ret != 0) { 00101 fprintf (stderr, "mld_mutex_t::lock(): " 00102 "Error %d locking mutex.\n", l_ret); 00103 } 00104 #endif 00105 }; 00106 00107 __INLINE__ void unlock () { 00108 #ifdef _USE_OMNI_THREADS_ 00109 d_mutex->unlock (); 00110 #else 00111 int l_ret = pthread_mutex_unlock (d_mutex); 00112 if (l_ret != 0) { 00113 fprintf (stderr, "mld_mutex_t::unlock(): " 00114 "Error %d locking mutex.\n", l_ret); 00115 } 00116 #endif 00117 }; 00118 00119 __INLINE__ bool trylock () { 00120 #ifdef _USE_OMNI_THREADS_ 00121 int l_ret = d_mutex->trylock (); 00122 #else 00123 int l_ret = pthread_mutex_unlock (d_mutex); 00124 #endif 00125 return (l_ret == 0 ? true : false); 00126 }; 00127 00128 inline void acquire () { lock(); }; 00129 inline void release () { unlock(); }; 00130 inline void wait () { lock(); }; 00131 inline void post () { unlock(); }; 00132 }; 00133 00134 typedef mld_mutex_t mld_mutex, *mld_mutex_ptr; 00135 00136 class mld_condition_t { 00137 #ifdef _USE_OMNI_THREADS_ 00138 typedef omni_condition l_condition, *l_condition_ptr; 00139 #else 00140 typedef pthread_cond_t l_condition, *l_condition_ptr; 00141 #endif 00142 00143 private: 00144 l_condition_ptr d_condition; 00145 mld_mutex_ptr d_mutex; 00146 bool d_i_own_mutex; 00147 00148 public: 00149 __INLINE__ mld_condition_t (mld_mutex_ptr mutex = NULL) { 00150 if (mutex) { 00151 d_i_own_mutex = false; 00152 d_mutex = mutex; 00153 } else { 00154 d_i_own_mutex = true; 00155 d_mutex = new mld_mutex (); 00156 } 00157 #ifdef _USE_OMNI_THREADS_ 00158 d_condition = new omni_condition (d_mutex->mutex ()); 00159 #else 00160 d_condition = (l_condition_ptr) new l_condition; 00161 int l_ret = pthread_cond_init (d_condition, NULL); 00162 if (l_ret != 0) { 00163 fprintf (stderr, "Error %d creating condition.\n", l_ret); 00164 throw std::runtime_error ("mld_condition_t::mld_condition_t()\n"); 00165 } 00166 #endif 00167 }; 00168 00169 __INLINE__ ~mld_condition_t () { 00170 signal (); 00171 #ifndef _USE_OMNI_THREADS_ 00172 int l_ret = pthread_cond_destroy (d_condition); 00173 if (l_ret != 0) { 00174 fprintf (stderr, "mld_condition_t::mld_condition_t(): " 00175 "Error %d destroying condition.\n", l_ret); 00176 } 00177 #endif 00178 delete d_condition; 00179 d_condition = NULL; 00180 if (d_i_own_mutex) 00181 delete d_mutex; 00182 d_mutex = NULL; 00183 }; 00184 00185 __INLINE__ mld_mutex_ptr mutex () {return (d_mutex);}; 00186 00187 __INLINE__ void signal () { 00188 DEBUG (fprintf (stderr, "a ");); 00189 00190 #ifdef _USE_OMNI_THREADS_ 00191 d_condition->signal (); 00192 #else 00193 int l_ret = pthread_cond_signal (d_condition); 00194 if (l_ret != 0) { 00195 fprintf (stderr, "mld_condition_t::signal(): " 00196 "Error %d.\n", l_ret); 00197 } 00198 #endif 00199 DEBUG (fprintf (stderr, "b ");); 00200 }; 00201 00202 __INLINE__ void wait () { 00203 DEBUG (fprintf (stderr, "c ");); 00204 #ifdef _USE_OMNI_THREADS_ 00205 d_condition->wait (); 00206 #else 00207 int l_ret = pthread_cond_wait (d_condition, d_mutex->mutex ()); 00208 if (l_ret != 0) { 00209 fprintf (stderr, "mld_condition_t::wait(): " 00210 "Error %d.\n", l_ret); 00211 } 00212 #endif 00213 DEBUG (fprintf (stderr, "d ");); 00214 }; 00215 }; 00216 00217 typedef mld_condition_t mld_condition, *mld_condition_ptr; 00218 00219 class mld_thread_t { 00220 #ifdef _USE_OMNI_THREADS_ 00221 typedef omni_thread l_thread, *l_thread_ptr; 00222 #else 00223 typedef pthread_t l_thread, *l_thread_ptr; 00224 #endif 00225 00226 private: 00227 #ifndef _USE_OMNI_THREADS_ 00228 l_thread d_thread; 00229 void (*d_start_routine)(void*); 00230 void *d_arg; 00231 #else 00232 l_thread_ptr d_thread; 00233 #endif 00234 00235 #ifndef _USE_OMNI_THREADS_ 00236 static void* local_start_routine (void *arg) { 00237 mld_thread_t* This = (mld_thread_t*) arg; 00238 (*(This->d_start_routine))(This->d_arg); 00239 return (NULL); 00240 }; 00241 #endif 00242 00243 public: 00244 __INLINE__ mld_thread_t (void (*start_routine)(void *), void *arg) { 00245 #ifdef _USE_OMNI_THREADS_ 00246 d_thread = new omni_thread (start_routine, arg); 00247 d_thread->start (); 00248 #else 00249 d_start_routine = start_routine; 00250 d_arg = arg; 00251 int l_ret = pthread_create (&d_thread, NULL, local_start_routine, this); 00252 if (l_ret != 0) { 00253 fprintf (stderr, "Error %d creating thread.\n", l_ret); 00254 throw std::runtime_error ("mld_thread_t::mld_thread_t()\n"); 00255 } 00256 #endif 00257 }; 00258 00259 __INLINE__ ~mld_thread_t () { 00260 #ifdef _USE_OMNI_THREADS_ 00261 // delete d_thread; 00262 d_thread = NULL; 00263 #else 00264 int l_ret = pthread_detach (d_thread); 00265 if (l_ret != 0) { 00266 fprintf (stderr, "Error %d detaching thread.\n", l_ret); 00267 throw std::runtime_error ("mld_thread_t::~mld_thread_t()\n"); 00268 } 00269 #endif 00270 }; 00271 }; 00272 00273 typedef mld_thread_t mld_thread, *mld_thread_ptr; 00274 00275 #endif /* _INCLUDED_MLD_THREADS_H_ */