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  * 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 2, 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 #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 //  delete d_thread;
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 /* _INCLUDED_MLD_THREADS_H_ */

Generated on Wed Dec 6 01:17:14 2006 for Universal Software Radio Peripheral by  doxygen 1.5.1