From: Maged Michael <magedmichael@fb.com>
Date: Fri, 20 Jan 2017 20:20:31 +0000 (-0800)
Subject: Made atomics generic in hazptr_owner member functions
X-Git-Tag: v2017.03.06.00~89
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=dd5a72f2ef12333dff288994a9c778523a2adf78;p=folly.git

Made atomics generic in hazptr_owner member functions

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
---

diff --git a/folly/experimental/hazptr/hazptr-impl.h b/folly/experimental/hazptr/hazptr-impl.h
index 8e98d952..1ed15244 100644
--- a/folly/experimental/hazptr/hazptr-impl.h
+++ b/folly/experimental/hazptr/hazptr-impl.h
@@ -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);
diff --git a/folly/experimental/hazptr/hazptr.h b/folly/experimental/hazptr/hazptr.h
index 9ba9e2e8..464dc1f3 100644
--- a/folly/experimental/hazptr/hazptr.h
+++ b/folly/experimental/hazptr/hazptr.h
@@ -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"