Made atomics generic in hazptr_owner member functions
authorMaged Michael <magedmichael@fb.com>
Fri, 20 Jan 2017 20:20:31 +0000 (12:20 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Fri, 20 Jan 2017 20:33:01 +0000 (12:33 -0800)
Summary:
As suggested by the C++ committee in November 2016, made atomics generic to allow other atomic types (e.g.,  folly::DeterministicAtomic<T*>),

Also removed obsolete comments.

Reviewed By: davidtgoldblatt

Differential Revision: D4443355

fbshipit-source-id: d9e21a959f2c7e3dd07c0ed4808236da80ef6dcd

folly/experimental/hazptr/hazptr-impl.h
folly/experimental/hazptr/hazptr.h

index 8e98d9529901bdc327c2471ba090d7eb3bc85398..1ed1524448a7ec7276fb21b2dd32901f377ed5e2 100644 (file)
@@ -78,9 +78,11 @@ hazptr_owner<T>::~hazptr_owner() {
 }
 
 template <typename T>
-inline bool hazptr_owner<T>::try_protect(
-    T*& ptr,
-    const std::atomic<T*>& src) noexcept {
+template <typename A>
+inline bool hazptr_owner<T>::try_protect(T*& ptr, const A& src) noexcept {
+  static_assert(
+      std::is_same<decltype(std::declval<A>().load()), T*>::value,
+      "Return type of A::load() must be T*");
   DEBUG_PRINT(this << " " << ptr << " " << &src);
   set(ptr);
   T* p = src.load();
@@ -93,7 +95,11 @@ inline bool hazptr_owner<T>::try_protect(
 }
 
 template <typename T>
-inline T* hazptr_owner<T>::get_protected(const std::atomic<T*>& src) noexcept {
+template <typename A>
+inline T* hazptr_owner<T>::get_protected(const A& src) noexcept {
+  static_assert(
+      std::is_same<decltype(std::declval<A>().load()), T*>::value,
+      "Return type of A::load() must be T*");
   T* p = src.load();
   while (!try_protect(p, src)) {}
   DEBUG_PRINT(this << " " << p << " " << &src);
index 9ba9e2e86fd3999f94318884461e66f3ed4e86ca..464dc1f3f792e5bbb8e7b27b4bf3b497397098cb 100644 (file)
@@ -19,6 +19,7 @@
 #include <atomic>
 #include <functional>
 #include <memory>
+#include <type_traits>
 
 /* Stand-in for C++17 std::pmr::memory_resource */
 #include <folly/experimental/hazptr/memory_resource.h>
@@ -120,10 +121,12 @@ template <typename T> class hazptr_owner {
 
   /** Hazard pointer operations */
   /* Returns a protected pointer from the source */
-  T* get_protected(const std::atomic<T*>& src) noexcept;
+  template <typename A = std::atomic<T*>>
+  T* get_protected(const A& src) noexcept;
   /* Return true if successful in protecting ptr if src == ptr after
    * setting the hazard pointer.  Otherwise sets ptr to src. */
-  bool try_protect(T*& ptr, const std::atomic<T*>& src) noexcept;
+  template <typename A = std::atomic<T*>>
+  bool try_protect(T*& ptr, const A& src) noexcept;
   /* Set the hazard pointer to ptr */
   void set(const T* ptr) noexcept;
   /* Clear the hazard pointer */
@@ -146,21 +149,4 @@ void swap(hazptr_owner<T>&, hazptr_owner<T>&) noexcept;
 } // namespace hazptr
 } // namespace folly
 
-////////////////////////////////////////////////////////////////////////////////
-/// Notes
-////////////////////////////////////////////////////////////////////////////////
-
-/* The hazptr_obj_base template uses a reclamation function as a
- * parameter for the retire() member function instead of taking an
- * allocator template as an extra template parameter because objects
- * of the same type may need different reclamation functions. */
-
-/* The hazptr interface supports reclamation by one domain at a
- * time. If an abject belongs to multiple domains simultaneously, a
- * workaround may be to design reclamation functions to form a series
- * of retirements from one domain to the next until it reaches the
- * final domain in the series that finally reclaims the object. */
-
-////////////////////////////////////////////////////////////////////////////////
-
 #include "hazptr-impl.h"