diff options
author | Tom Rondeau <trondeau@vt.edu> | 2013-06-14 18:15:50 -0400 |
---|---|---|
committer | Tom Rondeau <trondeau@vt.edu> | 2013-06-14 18:15:50 -0400 |
commit | 234b0f02a954928c54485c38ef37126ba5197597 (patch) | |
tree | f5e8050e9463d80e81e48addb9da873a3c3a20dd | |
parent | 2fb6d0a21a133207e9b93545c4fe3754d22cdfc7 (diff) |
runtime: 2 threading issues with the shared memory system.
1. Making a global mutex for the VM circular buffers to use and lock for multiple top_blocks to handle accessing the memory.
2. Catch the bad_alloc exception once and retry. After 1., this rarely happens unless the thread count gets large (> 20 as an estimate).
-rw-r--r-- | gnuradio-runtime/lib/block_registry.cc | 4 | ||||
-rw-r--r-- | gnuradio-runtime/lib/flat_flowgraph.cc | 11 | ||||
-rw-r--r-- | gnuradio-runtime/lib/vmcircbuf.cc | 6 | ||||
-rw-r--r-- | gnuradio-runtime/lib/vmcircbuf.h | 3 | ||||
-rw-r--r-- | gnuradio-runtime/lib/vmcircbuf_sysv_shm.cc | 4 |
5 files changed, 27 insertions, 1 deletions
diff --git a/gnuradio-runtime/lib/block_registry.cc b/gnuradio-runtime/lib/block_registry.cc index f2e69aad60..c4dc7647d6 100644 --- a/gnuradio-runtime/lib/block_registry.cc +++ b/gnuradio-runtime/lib/block_registry.cc @@ -82,6 +82,8 @@ namespace gr { void block_registry::register_symbolic_name(basic_block* block, std::string name) { + gr::thread::scoped_lock guard(d_mutex); + if(pmt::dict_has_key(d_ref_map, pmt::intern(name))) { throw std::runtime_error("symbol already exists, can not re-use!"); } @@ -91,6 +93,8 @@ namespace gr { basic_block_sptr block_registry::block_lookup(pmt::pmt_t symbol) { + gr::thread::scoped_lock guard(d_mutex); + pmt::pmt_t ref = pmt::dict_ref(d_ref_map, symbol, pmt::PMT_NIL); if(pmt::eq(ref, pmt::PMT_NIL)) { throw std::runtime_error("block lookup failed! block not found!"); diff --git a/gnuradio-runtime/lib/flat_flowgraph.cc b/gnuradio-runtime/lib/flat_flowgraph.cc index b8a1a67bc7..ae79288334 100644 --- a/gnuradio-runtime/lib/flat_flowgraph.cc +++ b/gnuradio-runtime/lib/flat_flowgraph.cc @@ -161,7 +161,16 @@ namespace gr { } // std::cout << "make_buffer(" << nitems << ", " << item_size << ", " << grblock << "\n"; - return make_buffer(nitems, item_size, grblock); + // We're going to let this fail once and retry. If that fails, + // throw and exit. + buffer_sptr b; + try { + b = make_buffer(nitems, item_size, grblock); + } + catch(std::bad_alloc&) { + b = make_buffer(nitems, item_size, grblock); + } + return b; } void diff --git a/gnuradio-runtime/lib/vmcircbuf.cc b/gnuradio-runtime/lib/vmcircbuf.cc index 0fccb3d914..e4e1590205 100644 --- a/gnuradio-runtime/lib/vmcircbuf.cc +++ b/gnuradio-runtime/lib/vmcircbuf.cc @@ -40,6 +40,8 @@ #include "vmcircbuf_mmap_shm_open.h" #include "vmcircbuf_mmap_tmpfile.h" +gr::thread::mutex s_vm_mutex; + namespace gr { static const char *FACTORY_PREF_KEY = "vmcircbuf_default_factory"; @@ -64,6 +66,8 @@ namespace gr { bool verbose = false; + gr::thread::scoped_lock guard(s_vm_mutex); + std::vector<gr::vmcircbuf_factory *> all = all_factories (); const char *name = gr::vmcircbuf_prefs::get(FACTORY_PREF_KEY); @@ -288,6 +292,8 @@ namespace gr { { bool ok = false; + gr::thread::scoped_lock guard(s_vm_mutex); + std::vector<vmcircbuf_factory *> all = all_factories(); for(unsigned int i = 0; i < all.size (); i++) diff --git a/gnuradio-runtime/lib/vmcircbuf.h b/gnuradio-runtime/lib/vmcircbuf.h index c3ddfe0043..f9ed045168 100644 --- a/gnuradio-runtime/lib/vmcircbuf.h +++ b/gnuradio-runtime/lib/vmcircbuf.h @@ -24,8 +24,11 @@ #define GR_VMCIRCBUF_H #include <gnuradio/api.h> +#include <gnuradio/thread/thread.h> #include <vector> +extern gr::thread::mutex s_vm_mutex; + namespace gr { /*! diff --git a/gnuradio-runtime/lib/vmcircbuf_sysv_shm.cc b/gnuradio-runtime/lib/vmcircbuf_sysv_shm.cc index 0d7e9b7d34..484b1a914e 100644 --- a/gnuradio-runtime/lib/vmcircbuf_sysv_shm.cc +++ b/gnuradio-runtime/lib/vmcircbuf_sysv_shm.cc @@ -46,6 +46,8 @@ namespace gr { vmcircbuf_sysv_shm::vmcircbuf_sysv_shm(int size) : gr::vmcircbuf(size) { + gr::thread::scoped_lock guard(s_vm_mutex); + #if !defined(HAVE_SYS_SHM_H) fprintf(stderr, "gr::vmcircbuf_sysv_shm: sysv shared memory is not available\n"); throw std::runtime_error("gr::vmcircbuf_sysv_shm"); @@ -150,6 +152,8 @@ namespace gr { vmcircbuf_sysv_shm::~vmcircbuf_sysv_shm() { + gr::thread::scoped_lock guard(s_vm_mutex); + #if defined(HAVE_SYS_SHM_H) if(shmdt(d_base - gr::pagesize()) == -1 || shmdt(d_base) == -1 |