diff options
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | config/grc_gr_audio_osx.m4 | 5 | ||||
-rw-r--r-- | config/grc_usrp.m4 | 16 | ||||
-rw-r--r-- | configure.ac | 14 | ||||
-rw-r--r-- | gr-audio-osx/src/Makefile.am | 8 | ||||
-rw-r--r-- | gr-audio-osx/src/audio_osx_sink.cc | 35 | ||||
-rw-r--r-- | gr-audio-osx/src/audio_osx_sink.h | 6 | ||||
-rw-r--r-- | gr-audio-osx/src/audio_osx_source.cc | 49 | ||||
-rw-r--r-- | gr-audio-osx/src/audio_osx_source.h | 6 | ||||
-rw-r--r-- | gr-audio-osx/src/circular_buffer.h | 69 | ||||
-rw-r--r-- | gr-audio-osx/src/mld_threads.h | 272 | ||||
-rw-r--r-- | usrp/host/lib/Makefile.am | 9 | ||||
-rw-r--r-- | usrp/host/lib/circular_buffer.h | 69 | ||||
-rw-r--r-- | usrp/host/lib/circular_linked_list.h | 34 | ||||
-rw-r--r-- | usrp/host/lib/fusb_darwin.cc | 97 | ||||
-rw-r--r-- | usrp/host/lib/fusb_darwin.h | 13 | ||||
-rw-r--r-- | usrp/host/lib/mld_threads.h | 275 | ||||
-rw-r--r-- | usrp/usrp.pc.in | 2 |
18 files changed, 198 insertions, 783 deletions
@@ -177,7 +177,7 @@ http://sourceforge.net/project/showfiles.php?group_id=1369&package_id=175103 We use Smart Pointers, the thread library and a bunch of other boost stuff. If your system doesn't have boost 1.35 or later, see README.building-boost -for additional info. +for additional info. (Note: Mac OSX systems require 1.37 or later.) (7) cppunit 1.9.14 or later. http://cppunit.sourceforge.net diff --git a/config/grc_gr_audio_osx.m4 b/config/grc_gr_audio_osx.m4 index 95fbc17d5..df8634ff6 100644 --- a/config/grc_gr_audio_osx.m4 +++ b/config/grc_gr_audio_osx.m4 @@ -1,4 +1,4 @@ -dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc. +dnl Copyright 2001,2002,2003,2004,2005,2006,2008,2010 Free Software Foundation, Inc. dnl dnl This file is part of GNU Radio dnl @@ -20,8 +20,7 @@ dnl Boston, MA 02110-1301, USA. AC_DEFUN([GRC_GR_AUDIO_OSX],[ GRC_ENABLE(gr-audio-osx) - dnl Don't do gr-audio-osx if omnithread or gnuradio-core skipped - GRC_CHECK_DEPENDENCY(gr-audio-osx, omnithread) + dnl Don't do gr-audio-osx if gnuradio-core skipped GRC_CHECK_DEPENDENCY(gr-audio-osx, gnuradio-core) dnl If execution gets to here, $passed will be: diff --git a/config/grc_usrp.m4 b/config/grc_usrp.m4 index 286641928..999b9c5c3 100644 --- a/config/grc_usrp.m4 +++ b/config/grc_usrp.m4 @@ -22,8 +22,8 @@ AC_DEFUN([GRC_USRP],[ GRC_WITH(usrp) - dnl Don't do usrp if omnithread skipped - GRC_CHECK_DEPENDENCY(usrp, omnithread) + dnl Don't do usrp if gruel is skipped + GRC_CHECK_DEPENDENCY(usrp, gruel) dnl Make sure the fast usb technique is set, OS dependent. dnl This is always performed, since it puts out CLI flags. @@ -59,18 +59,6 @@ AC_DEFUN([GRC_USRP],[ usrp_LA="\${abs_top_builddir}/usrp/host/lib/libusrp.la" fi - dnl There pkg-config file for usrp requires omnithread for Darwin only. Create a variable - dnl for just the usrp.pc.in case. - case "$host_os" in - darwin*) - usrp_darwin_omnithread_pc_requires="gnuradio-omnithread" - ;; - *) dnl (blanks) - usrp_darwin_omnithread_pc_requires="" - ;; - esac - AC_SUBST(usrp_darwin_omnithread_pc_requires) - AC_CONFIG_FILES([ \ usrp/Makefile \ usrp/usrp.pc \ diff --git a/configure.ac b/configure.ac index 3ba5bb387..3abdfbfcf 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -dnl Copyright 2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. +dnl Copyright 2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. dnl dnl This file is part of GNU Radio dnl @@ -264,7 +264,17 @@ dnl We require the boost headers, thread lib and date_time lib. dnl AX_BOOST_BASE finds the headers and the lib dir (-L<foo>) dnl dnl calls AC_SUBST(BOOST_CPPFLAGS), AC_SUBST(BOOST_LDFLAGS) and defines HAVE_BOOST -AX_BOOST_BASE([1.35]) +dnl +dnl Current Boost version requirement is >=1.35 for all platforms except Darwin, +dnl which requires >=1.37 for code in usrp host library. +case "$host_os" in + darwin*) + AX_BOOST_BASE([1.37]) + ;; + *) + AX_BOOST_BASE([1.35]) + ;; +esac dnl calls AC_SUBST(BOOST_THREAD_LIB), AC_SUBST(BOOST_CXXFLAGS) and defines HAVE_BOOST_THREAD AX_BOOST_THREAD diff --git a/gr-audio-osx/src/Makefile.am b/gr-audio-osx/src/Makefile.am index 6099dc20b..5bf28b8e7 100644 --- a/gr-audio-osx/src/Makefile.am +++ b/gr-audio-osx/src/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2006,2008,2009 Free Software Foundation, Inc. +# Copyright 2006,2008,2009,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio. # @@ -32,8 +32,7 @@ grinclude_HEADERS = \ noinst_HEADERS = \ audio_osx.h \ - circular_buffer.h \ - mld_threads.h + circular_buffer.h noinst_PYTHON = \ qa_osx.py \ @@ -46,8 +45,7 @@ libgnuradio_audio_osx_la_SOURCES = \ audio_osx_source.cc libgnuradio_audio_osx_la_LIBADD = \ - $(GNURADIO_CORE_LA) \ - $(OMNITHREAD_LA) + $(GNURADIO_CORE_LA) libgnuradio_audio_osx_la_LDFLAGS = \ -framework AudioUnit \ diff --git a/gr-audio-osx/src/audio_osx_sink.cc b/gr-audio-osx/src/audio_osx_sink.cc index e91716c0a..20fd895b9 100644 --- a/gr-audio-osx/src/audio_osx_sink.cc +++ b/gr-audio-osx/src/audio_osx_sink.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2006,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -24,8 +24,6 @@ #include "config.h" #endif -#define _USE_OMNI_THREADS_ - #include <audio_osx_sink.h> #include <gr_io_signature.h> #include <stdexcept> @@ -172,11 +170,15 @@ audio_osx_sink::audio_osx_sink (int sample_rate, // create the stuff to regulate I/O - d_cond_data = new mld_condition (); + d_cond_data = new gruel::condition_variable (); if (d_cond_data == NULL) - CheckErrorAndThrow (errno, "new mld_condition (data)", - "audio_osx_source::audio_osx_source"); - d_internal = d_cond_data->mutex (); + CheckErrorAndThrow (errno, "new condition (data)", + "audio_osx_sink::audio_osx_sink"); + + d_internal = new gruel::mutex (); + if (d_internal == NULL) + CheckErrorAndThrow (errno, "new mutex (internal)", + "audio_osx_sink::audio_osx_sink"); // initialize the AU for output @@ -253,6 +255,9 @@ audio_osx_sink::~audio_osx_sink () // close and delete control stuff delete d_cond_data; + d_cond_data = 0; + delete d_internal; + d_internal = 0; } audio_osx_sink_sptr @@ -274,7 +279,7 @@ audio_osx_sink::work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); /* take the input data, copy it, and push it to the bottom of the queue mono input are pushed onto queue[0]; @@ -307,8 +312,8 @@ audio_osx_sink::work (int noutput_items, while (d_queueSampleCount > l_max_count) { // release control so-as to allow data to be retrieved; // block until there is data to return - d_cond_data->wait (); -// the condition's signal() was called; acquire control + d_cond_data->wait (l); +// the condition's 'notify' was called; acquire control // to keep thread safe } } @@ -353,9 +358,6 @@ audio_osx_sink::work (int noutput_items, << d_queueSampleCount << ", mSC = " << d_max_sample_count << std::endl; #endif -// release control to allow for other processing parts to run - d_internal->unlock (); - return (noutput_items); } @@ -370,7 +372,7 @@ OSStatus audio_osx_sink::AUOutputCallback audio_osx_sink* This = (audio_osx_sink*) inRefCon; OSStatus err = noErr; - This->d_internal->lock (); + gruel::scoped_lock l (*This->d_internal); #if _OSX_AU_DEBUG_ std::cerr << "cb_in: SC = " << This->d_queueSampleCount @@ -403,10 +405,7 @@ OSStatus audio_osx_sink::AUOutputCallback #endif // signal that data is available - This->d_cond_data->signal (); - -// release control to allow for other processing parts to run - This->d_internal->unlock (); + This->d_cond_data->notify_one (); return (err); } diff --git a/gr-audio-osx/src/audio_osx_sink.h b/gr-audio-osx/src/audio_osx_sink.h index ceb291d0f..a1a56502c 100644 --- a/gr-audio-osx/src/audio_osx_sink.h +++ b/gr-audio-osx/src/audio_osx_sink.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2006,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -59,8 +59,8 @@ class audio_osx_sink : public gr_sync_block { UInt32 d_n_channels; UInt32 d_queueSampleCount, d_max_sample_count; bool d_do_block; - mld_mutex_ptr d_internal; - mld_condition_ptr d_cond_data; + gruel::mutex* d_internal; + gruel::condition_variable* d_cond_data; circular_buffer<float>** d_buffers; // AudioUnits and Such diff --git a/gr-audio-osx/src/audio_osx_source.cc b/gr-audio-osx/src/audio_osx_source.cc index 61838745b..538cfd8f6 100644 --- a/gr-audio-osx/src/audio_osx_source.cc +++ b/gr-audio-osx/src/audio_osx_source.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2006,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -24,8 +24,6 @@ #include "config.h" #endif -#define _USE_OMNI_THREADS_ - #include <audio_osx_source.h> #include <gr_io_signature.h> #include <stdexcept> @@ -446,11 +444,15 @@ audio_osx_source::audio_osx_source (int sample_rate, // create the stuff to regulate I/O - d_cond_data = new mld_condition (); + d_cond_data = new gruel::condition_variable (); if (d_cond_data == NULL) - CheckErrorAndThrow (errno, "new mld_condition (data)", + CheckErrorAndThrow (errno, "new condition (data)", + "audio_osx_source::audio_osx_source"); + + d_internal = new gruel::mutex (); + if (d_internal == NULL) + CheckErrorAndThrow (errno, "new mutex (internal)", "audio_osx_source::audio_osx_source"); - d_internal = d_cond_data->mutex (); // initialize the AU for input @@ -600,6 +602,9 @@ audio_osx_source::~audio_osx_source () // close and delete the control stuff delete d_cond_data; + d_cond_data = 0; + delete d_internal; + d_internal = 0; } audio_osx_source_sptr @@ -654,7 +659,7 @@ audio_osx_source::work gr_vector_void_star &output_items) { // acquire control to do processing here only - d_internal->lock (); + gruel::scoped_lock l (*d_internal); #if _OSX_AU_DEBUG_ std::cerr << "work1: SC = " << d_queueSampleCount @@ -677,14 +682,12 @@ audio_osx_source::work while (d_queueSampleCount == 0) { // release control so-as to allow data to be retrieved; // block until there is data to return - d_cond_data->wait (); - // the condition's signal() was called; acquire control to + d_cond_data->wait (l); + // the condition's 'notify' was called; acquire control to // keep thread safe } } else { // no data & not blocking; return nothing - // release control so-as to allow data to be retrieved - d_internal->unlock (); return (0); } } @@ -718,15 +721,8 @@ audio_osx_source::work #if _OSX_AU_DEBUG_ std::cerr << "work2: SC = " << d_queueSampleCount - << ", act#OI = " << actual_noutput_items << std::endl; -#endif - - // release control to allow for other processing parts to run - - d_internal->unlock (); - -#if _OSX_AU_DEBUG_ - std::cerr << "work3: Returning." << std::endl; + << ", act#OI = " << actual_noutput_items << std::endl + << "Returning." << std::endl; #endif return (actual_noutput_items); @@ -782,7 +778,7 @@ audio_osx_source::AUInputCallback (void* inRefCon, OSStatus err = noErr; audio_osx_source* This = static_cast<audio_osx_source*>(inRefCon); - This->d_internal->lock (); + gruel::scoped_lock l (*This->d_internal); #if _OSX_AU_DEBUG_ std::cerr << "cb0: in#F = " << inNumberFrames @@ -911,17 +907,10 @@ audio_osx_source::AUInputCallback (void* inRefCon, #endif // signal that data is available, if appropraite - This->d_cond_data->signal (); - -#if _OSX_AU_DEBUG_ - std::cerr << "cb5: releasing internal mutex." << std::endl; -#endif - -// release control to allow for other processing parts to run - This->d_internal->unlock (); + This->d_cond_data->notify_one (); #if _OSX_AU_DEBUG_ - std::cerr << "cb6: returning." << std::endl; + std::cerr << "cb5: returning." << std::endl; #endif return (err); diff --git a/gr-audio-osx/src/audio_osx_source.h b/gr-audio-osx/src/audio_osx_source.h index 780f7ec6b..e8df47b16 100644 --- a/gr-audio-osx/src/audio_osx_source.h +++ b/gr-audio-osx/src/audio_osx_source.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2006,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -66,8 +66,8 @@ class audio_osx_source : public gr_sync_block { UInt32 d_n_AvailableInputFrames, d_n_ActualInputFrames; UInt32 d_n_user_channels, d_n_max_channels, d_n_deviceChannels; bool d_do_block, d_passThrough, d_waiting_for_data; - mld_mutex_ptr d_internal; - mld_condition_ptr d_cond_data; + gruel::mutex* d_internal; + gruel::condition_variable* d_cond_data; circular_buffer<float>** d_buffers; // AudioUnits and Such diff --git a/gr-audio-osx/src/circular_buffer.h b/gr-audio-osx/src/circular_buffer.h index 6d491fb6f..48758bf87 100644 --- a/gr-audio-osx/src/circular_buffer.h +++ b/gr-audio-osx/src/circular_buffer.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. + * Copyright 2006,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -23,7 +23,7 @@ #ifndef _CIRCULAR_BUFFER_H_ #define _CIRCULAR_BUFFER_H_ -#include "mld_threads.h" +#include <gruel/thread.h> #include <iostream> #include <stdexcept> @@ -37,7 +37,8 @@ #define DEBUG(X) do{} while(0); #endif -template <class T> class circular_buffer +template <class T> +class circular_buffer { private: // the buffer to use @@ -48,8 +49,9 @@ private: size_t d_n_avail_write_I, d_n_avail_read_I; // stuff to control access to class internals - mld_mutex_ptr d_internal; - mld_condition_ptr d_readBlock, d_writeBlock; + gruel::mutex* d_internal; + gruel::condition_variable* d_readBlock; + gruel::condition_variable* d_writeBlock; // booleans to decide how to control reading, writing, and aborting bool d_doWriteBlock, d_doFullRead, d_doAbort; @@ -94,16 +96,14 @@ public: }; inline size_t n_avail_write_items () { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); size_t retVal = d_n_avail_write_I; - d_internal->unlock (); return (retVal); }; inline size_t n_avail_read_items () { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); size_t retVal = d_n_avail_read_I; - d_internal->unlock (); return (retVal); }; @@ -120,13 +120,13 @@ public: // create a mutex to handle contention of shared resources; // any routine needed access to shared resources uses lock() // before doing anything, then unlock() when finished. - d_internal = new mld_mutex (); + d_internal = new gruel::mutex (); // link the internal mutex to the read and write conditions; // when wait() is called, the internal mutex will automatically - // be unlock()'ed. Upon return (from a signal() to the condition), + // be unlock()'ed. Upon return (from a notify_one() to the condition), // the internal mutex will be lock()'ed. - d_readBlock = new mld_condition (d_internal); - d_writeBlock = new mld_condition (d_internal); + d_readBlock = new gruel::condition_variable (); + d_writeBlock = new gruel::condition_variable (); }; /* @@ -167,9 +167,8 @@ public: if (!buf) throw std::runtime_error ("circular_buffer::enqueue(): " "input buffer is NULL.\n"); - d_internal->lock (); + gruel::scoped_lock l (*d_internal); if (d_doAbort) { - d_internal->unlock (); return (2); } // set the return value to 1: success; change if needed @@ -178,11 +177,11 @@ public: if (d_doWriteBlock) { while (bufLen_I > d_n_avail_write_I) { DEBUG (std::cerr << "enqueue: #len > #a, waiting." << std::endl); - // wait will automatically unlock() the internal mutex - d_writeBlock->wait (); - // and lock() it here. + // wait; will automatically unlock() the internal mutex via + // the scoped lock + d_writeBlock->wait (l); + // and auto re-lock() it here. if (d_doAbort) { - d_internal->unlock (); DEBUG (std::cerr << "enqueue: #len > #a, aborting." << std::endl); return (2); } @@ -208,8 +207,7 @@ public: d_writeNdx_I += n_now_I; d_n_avail_read_I += bufLen_I; d_n_avail_write_I -= bufLen_I; - d_readBlock->signal (); - d_internal->unlock (); + d_readBlock->notify_one (); return (retval); }; @@ -255,19 +253,18 @@ public: throw std::runtime_error ("circular_buffer::dequeue()"); } - d_internal->lock (); + gruel::scoped_lock l (*d_internal); if (d_doAbort) { - d_internal->unlock (); return (2); } if (d_doFullRead) { while (d_n_avail_read_I < l_bufLen_I) { DEBUG (std::cerr << "dequeue: #a < #len, waiting." << std::endl); - // wait will automatically unlock() the internal mutex - d_readBlock->wait (); - // and lock() it here. + // wait; will automatically unlock() the internal mutex via + // the scoped lock + d_readBlock->wait (l); + // and re-lock() it here. if (d_doAbort) { - d_internal->unlock (); DEBUG (std::cerr << "dequeue: #a < #len, aborting." << std::endl); return (2); } @@ -276,11 +273,11 @@ public: } else { while (d_n_avail_read_I == 0) { DEBUG (std::cerr << "dequeue: #a == 0, waiting." << std::endl); - // wait will automatically unlock() the internal mutex - d_readBlock->wait (); - // and lock() it here. + // wait; will automatically unlock() the internal mutex via + // the scoped lock + d_readBlock->wait (l); + // and re-lock() it here. if (d_doAbort) { - d_internal->unlock (); DEBUG (std::cerr << "dequeue: #a == 0, aborting." << std::endl); return (2); } @@ -303,17 +300,15 @@ public: *bufLen_I = l_bufLen_I; d_n_avail_read_I -= l_bufLen_I; d_n_avail_write_I += l_bufLen_I; - d_writeBlock->signal (); - d_internal->unlock (); + d_writeBlock->notify_one (); return (1); }; void abort () { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); d_doAbort = true; - d_writeBlock->signal (); - d_readBlock->signal (); - d_internal->unlock (); + d_writeBlock->notify_one (); + d_readBlock->notify_one (); }; }; diff --git a/gr-audio-osx/src/mld_threads.h b/gr-audio-osx/src/mld_threads.h deleted file mode 100644 index d2fb4ea7c..000000000 --- a/gr-audio-osx/src/mld_threads.h +++ /dev/null @@ -1,272 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _INCLUDED_MLD_THREADS_H_ -#define _INCLUDED_MLD_THREADS_H_ - -/* classes which allow for either pthreads or omni_threads */ - -#define __macos__ -#ifdef _USE_OMNI_THREADS_ -#include <gnuradio/omnithread.h> -#else -#include <pthread.h> -#endif - -#include <stdexcept> - -#define __INLINE__ inline -#define DO_DEBUG 0 - -#if DO_DEBUG -#define DEBUG(X) do{X} while(0); -#else -#define DEBUG(X) do{} while(0); -#endif - -class mld_condition_t; - -class mld_mutex_t { -#ifdef _USE_OMNI_THREADS_ - typedef omni_mutex l_mutex, *l_mutex_ptr; -#else - typedef pthread_mutex_t l_mutex, *l_mutex_ptr; -#endif - - friend class mld_condition_t; - -private: - l_mutex_ptr d_mutex; - -protected: - inline l_mutex_ptr mutex () { return (d_mutex); }; - -public: - __INLINE__ mld_mutex_t () { -#ifdef _USE_OMNI_THREADS_ - d_mutex = new omni_mutex (); -#else - d_mutex = (l_mutex_ptr) new l_mutex; - int l_ret = pthread_mutex_init (d_mutex, NULL); - if (l_ret != 0) { - fprintf (stderr, "Error %d creating mutex.\n", l_ret); - throw std::runtime_error ("mld_mutex_t::mld_mutex_t()\n"); - } -#endif - }; - - __INLINE__ ~mld_mutex_t () { - unlock (); -#ifndef _USE_OMNI_THREADS_ - int l_ret = pthread_mutex_destroy (d_mutex); - if (l_ret != 0) { - fprintf (stderr, "mld_mutex_t::~mld_mutex_t(): " - "Error %d destroying mutex.\n", l_ret); - } -#endif - delete d_mutex; - d_mutex = NULL; - }; - - __INLINE__ void lock () { -#ifdef _USE_OMNI_THREADS_ - d_mutex->lock (); -#else - int l_ret = pthread_mutex_lock (d_mutex); - if (l_ret != 0) { - fprintf (stderr, "mld_mutex_t::lock(): " - "Error %d locking mutex.\n", l_ret); - } -#endif - }; - - __INLINE__ void unlock () { -#ifdef _USE_OMNI_THREADS_ - d_mutex->unlock (); -#else - int l_ret = pthread_mutex_unlock (d_mutex); - if (l_ret != 0) { - fprintf (stderr, "mld_mutex_t::unlock(): " - "Error %d locking mutex.\n", l_ret); - } -#endif - }; - - __INLINE__ bool trylock () { -#ifdef _USE_OMNI_THREADS_ - int l_ret = d_mutex->trylock (); -#else - int l_ret = pthread_mutex_unlock (d_mutex); -#endif - return (l_ret == 0 ? true : false); - }; - - inline void acquire () { lock(); }; - inline void release () { unlock(); }; - inline void wait () { lock(); }; - inline void post () { unlock(); }; -}; - -typedef mld_mutex_t mld_mutex, *mld_mutex_ptr; - -class mld_condition_t { -#ifdef _USE_OMNI_THREADS_ - typedef omni_condition l_condition, *l_condition_ptr; -#else - typedef pthread_cond_t l_condition, *l_condition_ptr; -#endif - -private: - l_condition_ptr d_condition; - mld_mutex_ptr d_mutex; - bool d_i_own_mutex; - -public: - __INLINE__ mld_condition_t (mld_mutex_ptr mutex = NULL) { - if (mutex) { - d_i_own_mutex = false; - d_mutex = mutex; - } else { - d_i_own_mutex = true; - d_mutex = new mld_mutex (); - } -#ifdef _USE_OMNI_THREADS_ - d_condition = new omni_condition (d_mutex->mutex ()); -#else - d_condition = (l_condition_ptr) new l_condition; - int l_ret = pthread_cond_init (d_condition, NULL); - if (l_ret != 0) { - fprintf (stderr, "Error %d creating condition.\n", l_ret); - throw std::runtime_error ("mld_condition_t::mld_condition_t()\n"); - } -#endif - }; - - __INLINE__ ~mld_condition_t () { - signal (); -#ifndef _USE_OMNI_THREADS_ - int l_ret = pthread_cond_destroy (d_condition); - if (l_ret != 0) { - fprintf (stderr, "mld_condition_t::mld_condition_t(): " - "Error %d destroying condition.\n", l_ret); - } -#endif - delete d_condition; - d_condition = NULL; - if (d_i_own_mutex) - delete d_mutex; - d_mutex = NULL; - }; - - __INLINE__ mld_mutex_ptr mutex () {return (d_mutex);}; - - __INLINE__ void signal () { - DEBUG (fprintf (stderr, "a ")); - -#ifdef _USE_OMNI_THREADS_ - d_condition->signal (); -#else - int l_ret = pthread_cond_signal (d_condition); - if (l_ret != 0) { - fprintf (stderr, "mld_condition_t::signal(): " - "Error %d.\n", l_ret); - } -#endif - DEBUG (fprintf (stderr, "b ")); - }; - - __INLINE__ void wait () { - DEBUG (fprintf (stderr, "c ")); -#ifdef _USE_OMNI_THREADS_ - d_condition->wait (); -#else - int l_ret = pthread_cond_wait (d_condition, d_mutex->mutex ()); - if (l_ret != 0) { - fprintf (stderr, "mld_condition_t::wait(): " - "Error %d.\n", l_ret); - } -#endif - DEBUG (printf (stderr, "d ")); - }; -}; - -typedef mld_condition_t mld_condition, *mld_condition_ptr; - -class mld_thread_t { -#ifdef _USE_OMNI_THREADS_ - typedef omni_thread l_thread, *l_thread_ptr; -#else - typedef pthread_t l_thread, *l_thread_ptr; -#endif - -private: -#ifndef _USE_OMNI_THREADS_ - l_thread d_thread; - void (*d_start_routine)(void*); - void *d_arg; -#else - l_thread_ptr d_thread; -#endif - -#ifndef _USE_OMNI_THREADS_ - static void* local_start_routine (void *arg) { - mld_thread_t* This = (mld_thread_t*) arg; - (*(This->d_start_routine))(This->d_arg); - return (NULL); - }; -#endif - -public: - __INLINE__ mld_thread_t (void (*start_routine)(void *), void *arg) { -#ifdef _USE_OMNI_THREADS_ - d_thread = new omni_thread (start_routine, arg); - d_thread->start (); -#else - d_start_routine = start_routine; - d_arg = arg; - int l_ret = pthread_create (&d_thread, NULL, local_start_routine, this); - if (l_ret != 0) { - fprintf (stderr, "Error %d creating thread.\n", l_ret); - throw std::runtime_error ("mld_thread_t::mld_thread_t()\n"); - } -#endif - }; - - __INLINE__ ~mld_thread_t () { -#ifdef _USE_OMNI_THREADS_ -// delete d_thread; - d_thread = NULL; -#else - int l_ret = pthread_detach (d_thread); - if (l_ret != 0) { - fprintf (stderr, "Error %d detaching thread.\n", l_ret); - throw std::runtime_error ("mld_thread_t::~mld_thread_t()\n"); - } -#endif - }; -}; - -typedef mld_thread_t mld_thread, *mld_thread_ptr; - -#endif /* _INCLUDED_MLD_THREADS_H_ */ diff --git a/usrp/host/lib/Makefile.am b/usrp/host/lib/Makefile.am index e80f27112..5848412c9 100644 --- a/usrp/host/lib/Makefile.am +++ b/usrp/host/lib/Makefile.am @@ -1,7 +1,7 @@ # # USRP - Universal Software Radio Peripheral # -# Copyright (C) 2003,2004,2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2003,2004,2006,2007,2008,2009,2010 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -31,10 +31,10 @@ libusrp_la_common_LIBADD = \ $(BOOST_THREAD_LIB) \ ../misc/libmisc.la -# darwin fusb requires omnithreads +# darwin fusb requires gruel (for threading) if FUSB_TECH_darwin -AM_CPPFLAGS = $(common_INCLUDES) $(OMNITHREAD_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES) -libusrp_la_LIBADD = $(libusrp_la_common_LIBADD) $(OMNITHREAD_LA) +AM_CPPFLAGS = $(common_INCLUDES) $(GRUEL_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES) +libusrp_la_LIBADD = $(libusrp_la_common_LIBADD) $(GRUEL_LA) libusrp_la_LDFLAGS = $(libusrp_la_common_LDFLAGS) -framework CoreFoundation else AM_CPPFLAGS = $(common_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES) @@ -70,7 +70,6 @@ darwin_CODE = \ circular_buffer.h \ circular_linked_list.h \ darwin_libusb.h \ - mld_threads.h \ usrp_prims_libusb0.cc diff --git a/usrp/host/lib/circular_buffer.h b/usrp/host/lib/circular_buffer.h index 6d491fb6f..48758bf87 100644 --- a/usrp/host/lib/circular_buffer.h +++ b/usrp/host/lib/circular_buffer.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. + * Copyright 2006,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -23,7 +23,7 @@ #ifndef _CIRCULAR_BUFFER_H_ #define _CIRCULAR_BUFFER_H_ -#include "mld_threads.h" +#include <gruel/thread.h> #include <iostream> #include <stdexcept> @@ -37,7 +37,8 @@ #define DEBUG(X) do{} while(0); #endif -template <class T> class circular_buffer +template <class T> +class circular_buffer { private: // the buffer to use @@ -48,8 +49,9 @@ private: size_t d_n_avail_write_I, d_n_avail_read_I; // stuff to control access to class internals - mld_mutex_ptr d_internal; - mld_condition_ptr d_readBlock, d_writeBlock; + gruel::mutex* d_internal; + gruel::condition_variable* d_readBlock; + gruel::condition_variable* d_writeBlock; // booleans to decide how to control reading, writing, and aborting bool d_doWriteBlock, d_doFullRead, d_doAbort; @@ -94,16 +96,14 @@ public: }; inline size_t n_avail_write_items () { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); size_t retVal = d_n_avail_write_I; - d_internal->unlock (); return (retVal); }; inline size_t n_avail_read_items () { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); size_t retVal = d_n_avail_read_I; - d_internal->unlock (); return (retVal); }; @@ -120,13 +120,13 @@ public: // create a mutex to handle contention of shared resources; // any routine needed access to shared resources uses lock() // before doing anything, then unlock() when finished. - d_internal = new mld_mutex (); + d_internal = new gruel::mutex (); // link the internal mutex to the read and write conditions; // when wait() is called, the internal mutex will automatically - // be unlock()'ed. Upon return (from a signal() to the condition), + // be unlock()'ed. Upon return (from a notify_one() to the condition), // the internal mutex will be lock()'ed. - d_readBlock = new mld_condition (d_internal); - d_writeBlock = new mld_condition (d_internal); + d_readBlock = new gruel::condition_variable (); + d_writeBlock = new gruel::condition_variable (); }; /* @@ -167,9 +167,8 @@ public: if (!buf) throw std::runtime_error ("circular_buffer::enqueue(): " "input buffer is NULL.\n"); - d_internal->lock (); + gruel::scoped_lock l (*d_internal); if (d_doAbort) { - d_internal->unlock (); return (2); } // set the return value to 1: success; change if needed @@ -178,11 +177,11 @@ public: if (d_doWriteBlock) { while (bufLen_I > d_n_avail_write_I) { DEBUG (std::cerr << "enqueue: #len > #a, waiting." << std::endl); - // wait will automatically unlock() the internal mutex - d_writeBlock->wait (); - // and lock() it here. + // wait; will automatically unlock() the internal mutex via + // the scoped lock + d_writeBlock->wait (l); + // and auto re-lock() it here. if (d_doAbort) { - d_internal->unlock (); DEBUG (std::cerr << "enqueue: #len > #a, aborting." << std::endl); return (2); } @@ -208,8 +207,7 @@ public: d_writeNdx_I += n_now_I; d_n_avail_read_I += bufLen_I; d_n_avail_write_I -= bufLen_I; - d_readBlock->signal (); - d_internal->unlock (); + d_readBlock->notify_one (); return (retval); }; @@ -255,19 +253,18 @@ public: throw std::runtime_error ("circular_buffer::dequeue()"); } - d_internal->lock (); + gruel::scoped_lock l (*d_internal); if (d_doAbort) { - d_internal->unlock (); return (2); } if (d_doFullRead) { while (d_n_avail_read_I < l_bufLen_I) { DEBUG (std::cerr << "dequeue: #a < #len, waiting." << std::endl); - // wait will automatically unlock() the internal mutex - d_readBlock->wait (); - // and lock() it here. + // wait; will automatically unlock() the internal mutex via + // the scoped lock + d_readBlock->wait (l); + // and re-lock() it here. if (d_doAbort) { - d_internal->unlock (); DEBUG (std::cerr << "dequeue: #a < #len, aborting." << std::endl); return (2); } @@ -276,11 +273,11 @@ public: } else { while (d_n_avail_read_I == 0) { DEBUG (std::cerr << "dequeue: #a == 0, waiting." << std::endl); - // wait will automatically unlock() the internal mutex - d_readBlock->wait (); - // and lock() it here. + // wait; will automatically unlock() the internal mutex via + // the scoped lock + d_readBlock->wait (l); + // and re-lock() it here. if (d_doAbort) { - d_internal->unlock (); DEBUG (std::cerr << "dequeue: #a == 0, aborting." << std::endl); return (2); } @@ -303,17 +300,15 @@ public: *bufLen_I = l_bufLen_I; d_n_avail_read_I -= l_bufLen_I; d_n_avail_write_I += l_bufLen_I; - d_writeBlock->signal (); - d_internal->unlock (); + d_writeBlock->notify_one (); return (1); }; void abort () { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); d_doAbort = true; - d_writeBlock->signal (); - d_readBlock->signal (); - d_internal->unlock (); + d_writeBlock->notify_one (); + d_readBlock->notify_one (); }; }; diff --git a/usrp/host/lib/circular_linked_list.h b/usrp/host/lib/circular_linked_list.h index 97fe2c1a8..bbed5e49b 100644 --- a/usrp/host/lib/circular_linked_list.h +++ b/usrp/host/lib/circular_linked_list.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. + * Copyright 2006,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -23,7 +23,7 @@ #ifndef _CIRCULAR_LINKED_LIST_H_ #define _CIRCULAR_LINKED_LIST_H_ -#include <mld_threads.h> +#include <gruel/thread.h> #include <stdexcept> #define __INLINE__ inline @@ -110,8 +110,8 @@ template <class T> class circular_linked_list { private: s_node_ptr d_current, d_iterate, d_available, d_inUse; size_t d_n_nodes, d_n_used; - mld_mutex_ptr d_internal; - mld_condition_ptr d_ioBlock; + gruel::mutex* d_internal; + gruel::condition_variable* d_ioBlock; public: circular_linked_list (size_t n_nodes) { @@ -150,8 +150,8 @@ public: } } d_available = d_current = l_prev; - d_ioBlock = new mld_condition (); - d_internal = d_ioBlock->mutex (); + d_ioBlock = new gruel::condition_variable (); + d_internal = new gruel::mutex (); }; ~circular_linked_list () { @@ -163,19 +163,21 @@ public: } delete d_ioBlock; d_ioBlock = NULL; + delete d_internal; + d_internal = NULL; d_available = d_inUse = d_iterate = d_current = NULL; d_n_used = d_n_nodes = 0; }; s_node_ptr find_next_available_node () { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); // find an available node s_node_ptr l_node = d_available; DEBUG (std::cerr << "w "); while (! l_node) { DEBUG (std::cerr << "x" << std::endl); // the ioBlock condition will automatically unlock() d_internal - d_ioBlock->wait (); + d_ioBlock->wait (l); // and lock() is here DEBUG (std::cerr << "y" << std::endl); l_node = d_available; @@ -196,13 +198,12 @@ public: l_node->insert_before (d_inUse); d_n_used++; l_node->set_not_available (); - d_internal->unlock (); return (l_node); }; void make_node_available (s_node_ptr l_node) { if (!l_node) return; - d_internal->lock (); + gruel::scoped_lock l (*d_internal); DEBUG (std::cerr << "::m_n_a: #u = " << num_used() << ", node = " << l_node << std::endl); // remove this node from the inUse list @@ -221,11 +222,8 @@ public: DEBUG (std::cerr << "s" << d_n_used); // signal the condition when new data arrives - d_ioBlock->signal (); + d_ioBlock->notify_one (); DEBUG (std::cerr << "t "); - -// unlock the mutex for thread safety - d_internal->unlock (); }; __INLINE__ void iterate_start () { d_iterate = d_current; }; @@ -233,7 +231,7 @@ public: s_node_ptr iterate_next () { #if 0 // lock the mutex for thread safety - d_internal->lock (); + gruel::scoped_lock l (*d_internal); #endif s_node_ptr l_this = NULL; if (d_iterate) { @@ -242,10 +240,6 @@ public: if (d_iterate == d_current) d_iterate = NULL; } -#if 0 -// unlock the mutex for thread safety - d_internal->unlock (); -#endif return (l_this); }; @@ -261,7 +255,7 @@ public: __INLINE__ void num_used_dec (void) { if (d_n_used != 0) --d_n_used; // signal the condition that new data has arrived - d_ioBlock->signal (); + d_ioBlock->notify_one (); }; __INLINE__ bool in_use () { return (d_n_used != 0); }; }; diff --git a/usrp/host/lib/fusb_darwin.cc b/usrp/host/lib/fusb_darwin.cc index 95c4878aa..d2966c115 100644 --- a/usrp/host/lib/fusb_darwin.cc +++ b/usrp/host/lib/fusb_darwin.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. + * Copyright 2006,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -24,9 +24,6 @@ #include "config.h" #endif -// tell mld_threads to NOT use omni_threads, -// but rather Darwin's pthreads -#define _USE_OMNI_THREADS_ #define DO_DEBUG 0 #include <usb.h> @@ -85,10 +82,12 @@ fusb_ephandle_darwin::fusb_ephandle_darwin (fusb_devhandle_darwin* dh, l_buf = NULL; } - d_readRunning = new mld_mutex (); - d_runThreadRunning = new mld_mutex (); - d_runBlock = new mld_condition (); - d_readBlock = new mld_condition (); + d_readRunning = new gruel::mutex (); + d_runThreadRunning = new gruel::mutex (); + d_runBlock = new gruel::condition_variable (); + d_readBlock = new gruel::condition_variable (); + d_runBlock_mutex = new gruel::mutex (); + d_readBlock_mutex = new gruel::mutex (); } fusb_ephandle_darwin::~fusb_ephandle_darwin () @@ -116,6 +115,10 @@ fusb_ephandle_darwin::~fusb_ephandle_darwin () d_readRunning = NULL; delete d_runThreadRunning; d_runThreadRunning = NULL; + delete d_runBlock_mutex; + d_runBlock_mutex = NULL; + delete d_readBlock_mutex; + d_readBlock_mutex = NULL; delete d_runBlock; d_runBlock = NULL; delete d_readBlock; @@ -200,14 +203,14 @@ fusb_ephandle_darwin::start () // lock the runBlock mutex, before creating the run thread. // this guarantees that we can control execution between these 2 threads - d_runBlock->mutex ()->lock (); + gruel::scoped_lock l (*d_runBlock_mutex); // create the run thread, which allows OSX to process I/O separately - d_runThread = new mld_thread (run_thread, this); + d_runThread = new gruel::thread (run_thread, this); // wait until the run thread (and possibky read thread) are -really- // going; this will unlock the mutex before waiting for a signal () - d_runBlock->wait (); + d_runBlock->wait (l); if (usb_debug) { std::cerr << "fusb_ephandle_darwin::start: " << (d_input_p ? "read" : "write") @@ -225,12 +228,12 @@ fusb_ephandle_darwin::run_thread (void* arg) // lock the run thread running mutex; if ::stop() is called, it will // first abort() the pipe then wait for the run thread to finish, // via a lock() on this mutex - mld_mutex_ptr l_runThreadRunning = This->d_runThreadRunning; - l_runThreadRunning->lock (); + gruel::mutex* l_runThreadRunning = This->d_runThreadRunning; + gruel::scoped_lock l0 (*l_runThreadRunning); - mld_mutex_ptr l_readRunning = This->d_readRunning; - mld_condition_ptr l_readBlock = This->d_readBlock; - mld_mutex_ptr l_readBlock_mutex = l_readBlock->mutex (); + gruel::mutex* l_readRunning = This->d_readRunning; + gruel::condition_variable* l_readBlock = This->d_readBlock; + gruel::mutex* l_readBlock_mutex = This->d_readBlock_mutex; bool l_input_p = This->d_input_p; @@ -250,41 +253,39 @@ fusb_ephandle_darwin::run_thread (void* arg) // get run loop reference, to allow other threads to stop This->d_CFRunLoopRef = CFRunLoopGetCurrent (); - mld_thread_ptr l_rwThread = NULL; + gruel::thread* l_rwThread = NULL; if (l_input_p) { // lock the readBlock mutex, before creating the read thread. // this guarantees that we can control execution between these 2 threads - l_readBlock_mutex->lock (); + gruel::scoped_lock l1 (*l_readBlock_mutex); // create the read thread, which just issues all of the starting // async read commands, then returns - l_rwThread = new mld_thread (read_thread, arg); + l_rwThread = new gruel::thread (read_thread, arg); // wait until the the read thread is -really- going; this will // unlock the read block mutex before waiting for a signal () - l_readBlock->wait (); + l_readBlock->wait (l1); } - // now signal the run condition to release and finish ::start(). + { + // now signal the run condition to release and finish ::start(). - // lock the runBlock mutex first; this will force waiting until the - // ->wait() command is issued in ::start() - mld_mutex_ptr l_run_block_mutex = This->d_runBlock->mutex (); - l_run_block_mutex->lock (); + // lock the runBlock mutex first; this will force waiting until the + // ->wait() command is issued in ::start() + gruel::mutex* l_run_block_mutex = This->d_runBlock_mutex; + gruel::scoped_lock l2 (*l_run_block_mutex); - // now that the lock is in place, signal the parent thread that - // things are running - This->d_runBlock->signal (); - - // release the run_block mutex, just in case - l_run_block_mutex->unlock (); + // now that the lock is in place, signal the parent thread that + // things are running + This->d_runBlock->notify_one (); + } // run the loop CFRunLoopRun (); if (l_input_p) { // wait for read_thread () to finish, if needed - l_readRunning->lock (); - l_readRunning->unlock (); + gruel::scoped_lock l3 (*l_readRunning); } // remove run loop stuff @@ -295,9 +296,6 @@ fusb_ephandle_darwin::run_thread (void* arg) std::cerr << "fusb_ephandle_darwin::run_thread: finished for " << (l_input_p ? "read" : "write") << "." << std::endl; } - - // release the run thread running mutex - l_runThreadRunning->unlock (); } void @@ -311,23 +309,23 @@ fusb_ephandle_darwin::read_thread (void* arg) // before doing anything else, lock the read running mutex. this // mutex does flow control between this thread and the run_thread - mld_mutex_ptr l_readRunning = This->d_readRunning; - l_readRunning->lock (); + gruel::mutex* l_readRunning = This->d_readRunning; + gruel::scoped_lock l0 (*l_readRunning); // signal the read condition from run_thread() to continue // lock the readBlock mutex first; this will force waiting until the // ->wait() command is issued in ::run_thread() - mld_condition_ptr l_readBlock = This->d_readBlock; - mld_mutex_ptr l_read_block_mutex = l_readBlock->mutex (); - l_read_block_mutex->lock (); + gruel::condition_variable* l_readBlock = This->d_readBlock; + gruel::mutex* l_read_block_mutex = This->d_readBlock_mutex; - // now that the lock is in place, signal the parent thread that - // things are running here - l_readBlock->signal (); + { + gruel::scoped_lock l1 (*l_read_block_mutex); - // release the run_block mutex, just in case - l_read_block_mutex->unlock (); + // now that the lock is in place, signal the parent thread that + // things are running here + l_readBlock->notify_one (); + } // queue up all of the available read requests s_queue_ptr l_queue = This->d_queue; @@ -341,10 +339,6 @@ fusb_ephandle_darwin::read_thread (void* arg) if (usb_debug) { std::cerr << "fusb_ephandle_darwin::read_thread: finished." << std::endl; } - - // release the read running mutex, to let the parent thread knows - // that this thread is finished - l_readRunning->unlock (); } void @@ -569,8 +563,7 @@ fusb_ephandle_darwin::stop () CFRunLoopStop (d_CFRunLoopRef); // wait for the runThread to stop - d_runThreadRunning->lock (); - d_runThreadRunning->unlock (); + gruel::scoped_lock l (*d_runThreadRunning); if (usb_debug) { std::cerr << "fusb_ephandle_darwin::stop: " << (d_input_p ? "read" : "write") diff --git a/usrp/host/lib/fusb_darwin.h b/usrp/host/lib/fusb_darwin.h index 735e5f16d..4d18177be 100644 --- a/usrp/host/lib/fusb_darwin.h +++ b/usrp/host/lib/fusb_darwin.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. + * Copyright 2006,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -150,8 +150,8 @@ class fusb_ephandle_darwin : public fusb_ephandle { private: fusb_devhandle_darwin* d_devhandle; - mld_thread_ptr d_runThread; - mld_mutex_ptr d_runThreadRunning; + gruel::thread* d_runThread; + gruel::mutex* d_runThreadRunning; CFRunLoopRef d_CFRunLoopRef; @@ -174,8 +174,11 @@ public: s_queue_ptr d_queue; circular_buffer<char>* d_buffer; size_t d_bufLenBytes; - mld_mutex_ptr d_readRunning; - mld_condition_ptr d_runBlock, d_readBlock; + gruel::mutex* d_readRunning; + gruel::mutex* d_runBlock_mutex; + gruel::mutex* d_readBlock_mutex; + gruel::condition_variable* d_runBlock; + gruel::condition_variable* d_readBlock; // CREATORS diff --git a/usrp/host/lib/mld_threads.h b/usrp/host/lib/mld_threads.h deleted file mode 100644 index 322f557b6..000000000 --- a/usrp/host/lib/mld_threads.h +++ /dev/null @@ -1,275 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _INCLUDED_MLD_THREADS_H_ -#define _INCLUDED_MLD_THREADS_H_ - -/* classes which allow for either pthreads or omni_threads */ - -#define __macos__ -#ifdef _USE_OMNI_THREADS_ -#include <gnuradio/omnithread.h> -#else -#include <pthread.h> -#endif - -#include <stdexcept> - -#define __INLINE__ inline - -#ifndef DO_DEBUG -#define DO_DEBUG 0 -#endif - -#if DO_DEBUG -#define DEBUG(X) do{X} while(0); -#else -#define DEBUG(X) do{} while(0); -#endif - -class mld_condition_t; - -class mld_mutex_t { -#ifdef _USE_OMNI_THREADS_ - typedef omni_mutex l_mutex, *l_mutex_ptr; -#else - typedef pthread_mutex_t l_mutex, *l_mutex_ptr; -#endif - - friend class mld_condition_t; - -private: - l_mutex_ptr d_mutex; - -protected: - inline l_mutex_ptr mutex () { return (d_mutex); }; - -public: - __INLINE__ mld_mutex_t () { -#ifdef _USE_OMNI_THREADS_ - d_mutex = new omni_mutex (); -#else - d_mutex = (l_mutex_ptr) new l_mutex; - int l_ret = pthread_mutex_init (d_mutex, NULL); - if (l_ret != 0) { - fprintf (stderr, "Error %d creating mutex.\n", l_ret); - throw std::runtime_error ("mld_mutex_t::mld_mutex_t()\n"); - } -#endif - }; - - __INLINE__ ~mld_mutex_t () { - unlock (); -#ifndef _USE_OMNI_THREADS_ - int l_ret = pthread_mutex_destroy (d_mutex); - if (l_ret != 0) { - fprintf (stderr, "mld_mutex_t::~mld_mutex_t(): " - "Error %d destroying mutex.\n", l_ret); - } -#endif - delete d_mutex; - d_mutex = NULL; - }; - - __INLINE__ void lock () { -#ifdef _USE_OMNI_THREADS_ - d_mutex->lock (); -#else - int l_ret = pthread_mutex_lock (d_mutex); - if (l_ret != 0) { - fprintf (stderr, "mld_mutex_t::lock(): " - "Error %d locking mutex.\n", l_ret); - } -#endif - }; - - __INLINE__ void unlock () { -#ifdef _USE_OMNI_THREADS_ - d_mutex->unlock (); -#else - int l_ret = pthread_mutex_unlock (d_mutex); - if (l_ret != 0) { - fprintf (stderr, "mld_mutex_t::unlock(): " - "Error %d locking mutex.\n", l_ret); - } -#endif - }; - - __INLINE__ bool trylock () { -#ifdef _USE_OMNI_THREADS_ - int l_ret = d_mutex->trylock (); -#else - int l_ret = pthread_mutex_unlock (d_mutex); -#endif - return (l_ret == 0 ? true : false); - }; - - inline void acquire () { lock(); }; - inline void release () { unlock(); }; - inline void wait () { lock(); }; - inline void post () { unlock(); }; -}; - -typedef mld_mutex_t mld_mutex, *mld_mutex_ptr; - -class mld_condition_t { -#ifdef _USE_OMNI_THREADS_ - typedef omni_condition l_condition, *l_condition_ptr; -#else - typedef pthread_cond_t l_condition, *l_condition_ptr; -#endif - -private: - l_condition_ptr d_condition; - mld_mutex_ptr d_mutex; - bool d_i_own_mutex; - -public: - __INLINE__ mld_condition_t (mld_mutex_ptr mutex = NULL) { - if (mutex) { - d_i_own_mutex = false; - d_mutex = mutex; - } else { - d_i_own_mutex = true; - d_mutex = new mld_mutex (); - } -#ifdef _USE_OMNI_THREADS_ - d_condition = new omni_condition (d_mutex->mutex ()); -#else - d_condition = (l_condition_ptr) new l_condition; - int l_ret = pthread_cond_init (d_condition, NULL); - if (l_ret != 0) { - fprintf (stderr, "Error %d creating condition.\n", l_ret); - throw std::runtime_error ("mld_condition_t::mld_condition_t()\n"); - } -#endif - }; - - __INLINE__ ~mld_condition_t () { - signal (); -#ifndef _USE_OMNI_THREADS_ - int l_ret = pthread_cond_destroy (d_condition); - if (l_ret != 0) { - fprintf (stderr, "mld_condition_t::mld_condition_t(): " - "Error %d destroying condition.\n", l_ret); - } -#endif - delete d_condition; - d_condition = NULL; - if (d_i_own_mutex) - delete d_mutex; - d_mutex = NULL; - }; - - __INLINE__ mld_mutex_ptr mutex () {return (d_mutex);}; - - __INLINE__ void signal () { - DEBUG (fprintf (stderr, "a ");); - -#ifdef _USE_OMNI_THREADS_ - d_condition->signal (); -#else - int l_ret = pthread_cond_signal (d_condition); - if (l_ret != 0) { - fprintf (stderr, "mld_condition_t::signal(): " - "Error %d.\n", l_ret); - } -#endif - DEBUG (fprintf (stderr, "b ");); - }; - - __INLINE__ void wait () { - DEBUG (fprintf (stderr, "c ");); -#ifdef _USE_OMNI_THREADS_ - d_condition->wait (); -#else - int l_ret = pthread_cond_wait (d_condition, d_mutex->mutex ()); - if (l_ret != 0) { - fprintf (stderr, "mld_condition_t::wait(): " - "Error %d.\n", l_ret); - } -#endif - DEBUG (fprintf (stderr, "d ");); - }; -}; - -typedef mld_condition_t mld_condition, *mld_condition_ptr; - -class mld_thread_t { -#ifdef _USE_OMNI_THREADS_ - typedef omni_thread l_thread, *l_thread_ptr; -#else - typedef pthread_t l_thread, *l_thread_ptr; -#endif - -private: -#ifndef _USE_OMNI_THREADS_ - l_thread d_thread; - void (*d_start_routine)(void*); - void *d_arg; -#else - l_thread_ptr d_thread; -#endif - -#ifndef _USE_OMNI_THREADS_ - static void* local_start_routine (void *arg) { - mld_thread_t* This = (mld_thread_t*) arg; - (*(This->d_start_routine))(This->d_arg); - return (NULL); - }; -#endif - -public: - __INLINE__ mld_thread_t (void (*start_routine)(void *), void *arg) { -#ifdef _USE_OMNI_THREADS_ - d_thread = new omni_thread (start_routine, arg); - d_thread->start (); -#else - d_start_routine = start_routine; - d_arg = arg; - int l_ret = pthread_create (&d_thread, NULL, local_start_routine, this); - if (l_ret != 0) { - fprintf (stderr, "Error %d creating thread.\n", l_ret); - throw std::runtime_error ("mld_thread_t::mld_thread_t()\n"); - } -#endif - }; - - __INLINE__ ~mld_thread_t () { -#ifdef _USE_OMNI_THREADS_ -// delete d_thread; - d_thread = NULL; -#else - int l_ret = pthread_detach (d_thread); - if (l_ret != 0) { - fprintf (stderr, "Error %d detaching thread.\n", l_ret); - throw std::runtime_error ("mld_thread_t::~mld_thread_t()\n"); - } -#endif - }; -}; - -typedef mld_thread_t mld_thread, *mld_thread_ptr; - -#endif /* _INCLUDED_MLD_THREADS_H_ */ diff --git a/usrp/usrp.pc.in b/usrp/usrp.pc.in index 2a15a05fd..d4794aa6f 100644 --- a/usrp/usrp.pc.in +++ b/usrp/usrp.pc.in @@ -5,7 +5,7 @@ includedir=@includedir@ Name: usrp Description: USRP Client Side C++ interface -Requires: @LIBUSB_PKG_CONFIG_NAME@ @usrp_darwin_omnithread_pc_requires@ +Requires: @LIBUSB_PKG_CONFIG_NAME@ Version: @VERSION@ Libs: -L${libdir} -lusrp Cflags: -I${includedir} |