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