Skip to content

Commit e52a7ad

Browse files
committed
guard against fixed tt insertion race
If insert fails due to the hash already being present, an effort is made to use the cached one instead.
1 parent 00ef1d2 commit e52a7ad

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

src/search/dag_classic/search.cc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2239,17 +2239,23 @@ void SearchWorker::DoBackupUpdateSingleNode(
22392239
if (node_to_process.nn_queried) {
22402240
#ifdef FIX_TT
22412241
auto entry = search_->tt_->LookupAndPin(node_to_process.hash);
2242+
if (!entry) {
2243+
bool insert_ok = search_->tt_->Insert(
2244+
node_to_process.hash, std::make_unique<std::weak_ptr<LowNode>>(
2245+
node_to_process.tt_low_node));
2246+
if (!insert_ok) {
2247+
// The insert may fail if another thread added the same hash.
2248+
// In the unlikely case it fails, the search will still work OK.
2249+
entry = search_->tt_->LookupAndPin(node_to_process.hash);
2250+
}
2251+
}
22422252
bool is_tt_miss = !entry;
22432253
#else
22442254
auto [tt_iter, is_tt_miss] = search_->tt_->try_emplace(
22452255
node_to_process.hash, node_to_process.tt_low_node);
22462256
#endif
22472257
if (is_tt_miss) {
2248-
#ifdef FIX_TT
2249-
search_->tt_->Insert(node_to_process.hash,
2250-
std::make_unique<std::weak_ptr<LowNode>>(
2251-
node_to_process.tt_low_node));
2252-
#else
2258+
#ifndef FIX_TT
22532259
assert(!tt_iter->second.expired());
22542260
#endif
22552261
node_to_process.node->SetLowNode(node_to_process.tt_low_node);

src/utils/cache.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ class HashKeyedCache {
6363

6464
// Inserts the element under key @key with value @val. Unless the key is
6565
// already in the cache.
66-
void Insert(uint64_t key, std::unique_ptr<V> val) {
67-
if (capacity_.load(std::memory_order_relaxed) == 0) return;
66+
// Returns false if the hash is found in the cache, blocking insertion.
67+
bool Insert(uint64_t key, std::unique_ptr<V> val) {
68+
if (capacity_.load(std::memory_order_relaxed) == 0) return true;
6869

6970
SpinMutex::Lock lock(mutex_);
7071

@@ -73,7 +74,7 @@ class HashKeyedCache {
7374
if (!hash_[idx].in_use) break;
7475
if (hash_[idx].key == key) {
7576
// Already exists.
76-
return;
77+
return false;
7778
}
7879
++idx;
7980
if (idx >= hash_.size()) idx -= hash_.size();
@@ -87,6 +88,7 @@ class HashKeyedCache {
8788
++allocated_;
8889

8990
EvictToCapacity(capacity_);
91+
return true;
9092
}
9193

9294
// Checks whether a key exists. Doesn't pin. Of course the next moment the

0 commit comments

Comments
 (0)