Commit ea244c69 authored by Maged Michael's avatar Maged Michael Committed by Facebook Github Bot

ConcurrentHashMap: Use synchronization/hazptr and hazptr_obj_base_linked

Summary:
- Use the hazard pointer library under folly/synchronization.
  - NodeT derived from hazptr_obj_base_linked.
  - Bucket heads are hazptr_root-s with dtor that automatically unlinks nodes
  - Provides support for uncertain removal of NodeT-s both from NodeT and Buckets
  - As intended, hazptr_cleanup reclaims all unprotected removed objects even if they have not been determined to be retirable at the start of cleanup.

Fixes the following:
- The pattern of calling h.get_protected(node->next_), when hazptr_holder h is protecting node is unsafe because try_protect (inside get_protected) may fail and we end protecting neither node nor next. This diff uses a different hazptr_holder to protect the next node. A correct pattern is to call h2.get_protected(node->next_) then h.swap(h2); h2.reset();
- The pattern of calling h2.reset(node) then h1.reset() to continue protecting a node already protected by h1 is unsafe because h2's protection may be too late after node was retired. A correct pattern is h2.swap(h1).

Reviewed By: djwatson

Differential Revision: D7708325

fbshipit-source-id: 617dcfe19410071888abafa32f0e1ada9d123983
parent 8fb5c152
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <folly/Optional.h> #include <folly/Optional.h>
#include <folly/concurrency/detail/ConcurrentHashMap-detail.h> #include <folly/concurrency/detail/ConcurrentHashMap-detail.h>
#include <folly/experimental/hazptr/hazptr.h> #include <folly/synchronization/Hazptr.h>
#include <atomic> #include <atomic>
#include <mutex> #include <mutex>
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <folly/test/DeterministicSchedule.h> #include <folly/test/DeterministicSchedule.h>
using namespace folly::test; using namespace folly::test;
using namespace folly::hazptr;
using namespace folly; using namespace folly;
using namespace std; using namespace std;
...@@ -610,6 +609,8 @@ TEST(ConcurrentHashMap, Deletion) { ...@@ -610,6 +609,8 @@ TEST(ConcurrentHashMap, Deletion) {
map.insert(0, std::make_shared<Wrapper>(del)); map.insert(0, std::make_shared<Wrapper>(del));
} }
folly::hazptr_cleanup();
EXPECT_TRUE(del); EXPECT_TRUE(del);
} }
...@@ -623,7 +624,7 @@ TEST(ConcurrentHashMap, DeletionWithErase) { ...@@ -623,7 +624,7 @@ TEST(ConcurrentHashMap, DeletionWithErase) {
map.erase(0); map.erase(0);
} }
hazptr_cleanup(); folly::hazptr_cleanup();
EXPECT_TRUE(del); EXPECT_TRUE(del);
} }
...@@ -639,7 +640,7 @@ TEST(ConcurrentHashMap, DeletionWithIterator) { ...@@ -639,7 +640,7 @@ TEST(ConcurrentHashMap, DeletionWithIterator) {
map.erase(it); map.erase(it);
} }
hazptr_cleanup(); folly::hazptr_cleanup();
EXPECT_TRUE(del); EXPECT_TRUE(del);
} }
...@@ -656,6 +657,8 @@ TEST(ConcurrentHashMap, DeletionWithForLoop) { ...@@ -656,6 +657,8 @@ TEST(ConcurrentHashMap, DeletionWithForLoop) {
} }
} }
folly::hazptr_cleanup();
EXPECT_TRUE(del); EXPECT_TRUE(del);
} }
...@@ -669,6 +672,8 @@ TEST(ConcurrentHashMap, DeletionMultiple) { ...@@ -669,6 +672,8 @@ TEST(ConcurrentHashMap, DeletionMultiple) {
map.insert(1, std::make_shared<Wrapper>(del2)); map.insert(1, std::make_shared<Wrapper>(del2));
} }
folly::hazptr_cleanup();
EXPECT_TRUE(del1); EXPECT_TRUE(del1);
EXPECT_TRUE(del2); EXPECT_TRUE(del2);
} }
...@@ -683,7 +688,7 @@ TEST(ConcurrentHashMap, DeletionAssigned) { ...@@ -683,7 +688,7 @@ TEST(ConcurrentHashMap, DeletionAssigned) {
map.insert_or_assign(0, std::make_shared<Wrapper>(del2)); map.insert_or_assign(0, std::make_shared<Wrapper>(del2));
} }
hazptr_cleanup(); folly::hazptr_cleanup();
EXPECT_TRUE(del1); EXPECT_TRUE(del1);
EXPECT_TRUE(del2); EXPECT_TRUE(del2);
...@@ -700,7 +705,7 @@ TEST(ConcurrentHashMap, DeletionMultipleMaps) { ...@@ -700,7 +705,7 @@ TEST(ConcurrentHashMap, DeletionMultipleMaps) {
map2.insert(0, std::make_shared<Wrapper>(del2)); map2.insert(0, std::make_shared<Wrapper>(del2));
} }
hazptr_cleanup(); folly::hazptr_cleanup();
EXPECT_TRUE(del1); EXPECT_TRUE(del1);
EXPECT_TRUE(del2); EXPECT_TRUE(del2);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment