From 8f590d7bfaa22a42ccb2392f9822206ed003c82a Mon Sep 17 00:00:00 2001
From: Darek Kawamoto <darek@he360.com>
Date: Thu, 1 Dec 2016 11:59:03 -0500
Subject: pmt: Adding memory fence to ~pmt_t for proper multi-core ARM
 execution.

Occasionally, flowgraphs running on my E3xx processor would segfault in the pmt_t destructor (an odd place to crash).  When this segfault happens, it's common (but not guaranteed) for the top of the coredump backtrace to be at 0x0000001c or 0x00000018. Always near or at the top was always a pmt destructor, such as ~pmt_pair() or ~pmt_tuple().

After reading up in Boost Reference Counter Example Implementation, it seems as though we need to add a memory fence to ensure proper memory ordering (this issue did not happen on Intel processors due to the stronger memory model there).

This commit changes the pmt_t's internal implementation (pmt_int.h and pmt.cc) of intrusive_ptr_add_ref and intrusive_ptr_release to be exactly like boost's recommended example, and seems to prevent this kind of segfault.

Additionally, since Ubuntu 12.04 comes with boost 1.48, which does not have boost/atomic.hpp, the changes are wrapped in #if conditions until support for this configuration is discontinued.
---
 gnuradio-runtime/lib/pmt/pmt_int.h | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

(limited to 'gnuradio-runtime/lib/pmt/pmt_int.h')

diff --git a/gnuradio-runtime/lib/pmt/pmt_int.h b/gnuradio-runtime/lib/pmt/pmt_int.h
index 49bde52063..de91d0ec5b 100644
--- a/gnuradio-runtime/lib/pmt/pmt_int.h
+++ b/gnuradio-runtime/lib/pmt/pmt_int.h
@@ -24,7 +24,13 @@
 
 #include <pmt/pmt.h>
 #include <boost/utility.hpp>
-#include <boost/detail/atomic_count.hpp>
+#if ((BOOST_VER_MAJOR >= 1) && (BOOST_VER_MINOR >= 53)) 
+  #include <boost/atomic.hpp>
+#else
+  // boost::atomic not available before 1.53
+  // This section will be removed when support for boost 1.48 ceases
+  #include <boost/detail/atomic_count.hpp>
+#endif
 
 /*
  * EVERYTHING IN THIS FILE IS PRIVATE TO THE IMPLEMENTATION!
@@ -36,10 +42,23 @@
 namespace pmt {
 
 class PMT_API pmt_base : boost::noncopyable {
+
+#if ((BOOST_VER_MAJOR >= 1) && (BOOST_VER_MINOR >= 53)) 
+  mutable boost::atomic<int> refcount_;
+#else
+  // boost::atomic not available before 1.53
+  // This section will be removed when support for boost 1.48 ceases
   mutable boost::detail::atomic_count count_;
+#endif
 
 protected:
+#if ((BOOST_VER_MAJOR >= 1) && (BOOST_VER_MINOR >= 53)) 
+  pmt_base() : refcount_(0) {};
+#else
+  // boost::atomic not available before 1.53
+  // This section will be removed when support for boost 1.48 ceases
   pmt_base() : count_(0) {};
+#endif
   virtual ~pmt_base();
 
 public:
-- 
cgit v1.2.3


From 5cab06fcd36e42631d94625eb3e737d94be7bdf4 Mon Sep 17 00:00:00 2001
From: Darek Kawamoto <darek@he360.com>
Date: Mon, 5 Dec 2016 00:51:57 -0500
Subject: pmt: Fixing #if boost version checks in pmt_t.

---
 gnuradio-runtime/lib/pmt/pmt.cc    | 2 +-
 gnuradio-runtime/lib/pmt/pmt_int.h | 7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

(limited to 'gnuradio-runtime/lib/pmt/pmt_int.h')

diff --git a/gnuradio-runtime/lib/pmt/pmt.cc b/gnuradio-runtime/lib/pmt/pmt.cc
index 204befebaa..3b92481549 100644
--- a/gnuradio-runtime/lib/pmt/pmt.cc
+++ b/gnuradio-runtime/lib/pmt/pmt.cc
@@ -63,7 +63,7 @@ pmt_base::operator delete(void *p, size_t size)
 
 #endif
 
-#if ((BOOST_VER_MAJOR >= 1) && (BOOST_VER_MINOR >= 53))
+#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53)) 
 void intrusive_ptr_add_ref(pmt_base* p)
 {
   p->refcount_.fetch_add(1, boost::memory_order_relaxed);
diff --git a/gnuradio-runtime/lib/pmt/pmt_int.h b/gnuradio-runtime/lib/pmt/pmt_int.h
index de91d0ec5b..da48a0ddc8 100644
--- a/gnuradio-runtime/lib/pmt/pmt_int.h
+++ b/gnuradio-runtime/lib/pmt/pmt_int.h
@@ -24,7 +24,8 @@
 
 #include <pmt/pmt.h>
 #include <boost/utility.hpp>
-#if ((BOOST_VER_MAJOR >= 1) && (BOOST_VER_MINOR >= 53)) 
+#include <boost/version.hpp>
+#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53)) 
   #include <boost/atomic.hpp>
 #else
   // boost::atomic not available before 1.53
@@ -43,7 +44,7 @@ namespace pmt {
 
 class PMT_API pmt_base : boost::noncopyable {
 
-#if ((BOOST_VER_MAJOR >= 1) && (BOOST_VER_MINOR >= 53)) 
+#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53)) 
   mutable boost::atomic<int> refcount_;
 #else
   // boost::atomic not available before 1.53
@@ -52,7 +53,7 @@ class PMT_API pmt_base : boost::noncopyable {
 #endif
 
 protected:
-#if ((BOOST_VER_MAJOR >= 1) && (BOOST_VER_MINOR >= 53)) 
+#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53)) 
   pmt_base() : refcount_(0) {};
 #else
   // boost::atomic not available before 1.53
-- 
cgit v1.2.3


From dcf8928e61d1c3a50391dc077b804bd0e6e1e403 Mon Sep 17 00:00:00 2001
From: Darek Kawamoto <darek@he360.com>
Date: Wed, 7 Dec 2016 19:19:03 -0500
Subject: pmt: Removing support for boost < 1.53 in ~pmt_t

---
 gnuradio-runtime/lib/pmt/pmt.cc    |  8 --------
 gnuradio-runtime/lib/pmt/pmt_int.h | 21 +--------------------
 2 files changed, 1 insertion(+), 28 deletions(-)

(limited to 'gnuradio-runtime/lib/pmt/pmt_int.h')

diff --git a/gnuradio-runtime/lib/pmt/pmt.cc b/gnuradio-runtime/lib/pmt/pmt.cc
index 3b92481549..da2a7e5cc2 100644
--- a/gnuradio-runtime/lib/pmt/pmt.cc
+++ b/gnuradio-runtime/lib/pmt/pmt.cc
@@ -63,7 +63,6 @@ pmt_base::operator delete(void *p, size_t size)
 
 #endif
 
-#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53)) 
 void intrusive_ptr_add_ref(pmt_base* p)
 {
   p->refcount_.fetch_add(1, boost::memory_order_relaxed);
@@ -75,13 +74,6 @@ void intrusive_ptr_release(pmt_base* p) {
     delete p;
   }
 }
-#else
-// boost::atomic not available before 1.53
-// This section will be removed when support for boost 1.48 ceases
-// NB: This code is prone to segfault on non-Intel architectures.
-void intrusive_ptr_add_ref(pmt_base* p) { ++(p->count_); }
-void intrusive_ptr_release(pmt_base* p) { if (--(p->count_) == 0 ) delete p; }
-#endif
  
 pmt_base::~pmt_base()
 {
diff --git a/gnuradio-runtime/lib/pmt/pmt_int.h b/gnuradio-runtime/lib/pmt/pmt_int.h
index da48a0ddc8..f06f507944 100644
--- a/gnuradio-runtime/lib/pmt/pmt_int.h
+++ b/gnuradio-runtime/lib/pmt/pmt_int.h
@@ -25,13 +25,7 @@
 #include <pmt/pmt.h>
 #include <boost/utility.hpp>
 #include <boost/version.hpp>
-#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53)) 
-  #include <boost/atomic.hpp>
-#else
-  // boost::atomic not available before 1.53
-  // This section will be removed when support for boost 1.48 ceases
-  #include <boost/detail/atomic_count.hpp>
-#endif
+#include <boost/atomic.hpp>
 
 /*
  * EVERYTHING IN THIS FILE IS PRIVATE TO THE IMPLEMENTATION!
@@ -43,23 +37,10 @@
 namespace pmt {
 
 class PMT_API pmt_base : boost::noncopyable {
-
-#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53)) 
   mutable boost::atomic<int> refcount_;
-#else
-  // boost::atomic not available before 1.53
-  // This section will be removed when support for boost 1.48 ceases
-  mutable boost::detail::atomic_count count_;
-#endif
 
 protected:
-#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53)) 
   pmt_base() : refcount_(0) {};
-#else
-  // boost::atomic not available before 1.53
-  // This section will be removed when support for boost 1.48 ceases
-  pmt_base() : count_(0) {};
-#endif
   virtual ~pmt_base();
 
 public:
-- 
cgit v1.2.3