mld_threads.h

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

Generated on Tue May 1 10:45:46 2007 for GNU Radio 3.0.3 by  doxygen 1.5.1