Skip to content

Commit 41f8425

Browse files
igchorvinser52
authored andcommitted
critical section inside combined_lock
1 parent e59b1fe commit 41f8425

File tree

7 files changed

+71
-28
lines changed

7 files changed

+71
-28
lines changed

cachelib/allocator/CacheAllocator-inl.h

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,27 +1482,40 @@ CacheAllocator<CacheTrait>::findEviction(TierId tid, PoolId pid, ClassId cid) {
14821482
// Keep searching for a candidate until we were able to evict it
14831483
// or until the search limit has been exhausted
14841484
unsigned int searchTries = 0;
1485-
auto itr = mmContainer.getEvictionIterator();
14861485
while ((config_.evictionSearchTries == 0 ||
1487-
config_.evictionSearchTries > searchTries) &&
1488-
itr) {
1486+
config_.evictionSearchTries > searchTries)) {
14891487
++searchTries;
14901488
(*stats_.evictionAttempts)[pid][cid].inc();
14911489

1492-
Item* toRecycle = itr.get();
1490+
Item* toRecycle = nullptr;
1491+
Item* candidate = nullptr;
14931492

1494-
Item* candidate =
1495-
toRecycle->isChainedItem()
1496-
? &toRecycle->asChainedItem().getParentItem(compressor_)
1497-
: toRecycle;
1493+
mmContainer.withEvictionIterator([this, &candidate, &toRecycle, &searchTries](auto &&itr){
1494+
while ((config_.evictionSearchTries == 0 ||
1495+
config_.evictionSearchTries > searchTries) && itr) {
1496+
++searchTries;
14981497

1499-
// make sure no other thead is evicting the item
1500-
if (candidate->getRefCount() != 0 || !candidate->markMoving()) {
1501-
++itr;
1498+
auto *toRecycle_ = itr.get();
1499+
auto *candidate_ = toRecycle_->isChainedItem()
1500+
? &toRecycle_->asChainedItem().getParentItem(compressor_)
1501+
: toRecycle_;
1502+
1503+
// make sure no other thead is evicting the item
1504+
if (candidate_->getRefCount() == 0 && candidate_->markMoving()) {
1505+
toRecycle = toRecycle_;
1506+
candidate = candidate_;
1507+
return;
1508+
}
1509+
1510+
++itr;
1511+
}
1512+
});
1513+
1514+
if (!toRecycle)
15021515
continue;
1503-
}
1504-
1505-
itr.destroy();
1516+
1517+
XDCHECK(toRecycle);
1518+
XDCHECK(candidate);
15061519

15071520
// for chained items, the ownership of the parent can change. We try to
15081521
// evict what we think as parent and see if the eviction of parent
@@ -1563,8 +1576,6 @@ CacheAllocator<CacheTrait>::findEviction(TierId tid, PoolId pid, ClassId cid) {
15631576
return toRecycle;
15641577
}
15651578
}
1566-
1567-
itr.resetToBegin();
15681579
}
15691580
return nullptr;
15701581
}

cachelib/allocator/MM2Q-inl.h

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -250,22 +250,21 @@ MM2Q::Container<T, HookPtr>::getEvictionIterator() const noexcept {
250250
// arbitrary amount of time outside a lambda-friendly piece of code (eg. they
251251
// can return the iterator from functions, pass it to functions, etc)
252252
//
253-
// it would be theoretically possible to refactor this interface into
254-
// something like the following to allow combining
255-
//
256-
// mm2q.withEvictionIterator([&](auto iterator) {
257-
// // user code
258-
// });
259-
//
260-
// at the time of writing it is unclear if the gains from combining are
261-
// reasonable justification for the codemod required to achieve combinability
262-
// as we don't expect this critical section to be the hotspot in user code.
263-
// This is however subject to change at some time in the future as and when
264-
// this assertion becomes false.
253+
// to get advantage of combining, use withEvictionIterator
265254
LockHolder l(*lruMutex_);
266255
return Iterator{std::move(l), lru_.rbegin()};
267256
}
268257

258+
template <typename T, MM2Q::Hook<T> T::*HookPtr>
259+
template <typename F>
260+
void
261+
MM2Q::Container<T, HookPtr>::withEvictionIterator(F&& fun) {
262+
lruMutex_->lock_combine([this, &fun]() {
263+
fun(Iterator{LockHolder{}, lru_.rbegin()});
264+
});
265+
}
266+
267+
269268
template <typename T, MM2Q::Hook<T> T::*HookPtr>
270269
void MM2Q::Container<T, HookPtr>::removeLocked(T& node,
271270
bool doRebalance) noexcept {

cachelib/allocator/MM2Q.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,11 @@ class MM2Q {
447447
// container and only one such iterator can exist at a time
448448
Iterator getEvictionIterator() const noexcept;
449449

450+
// Execute provided function under container lock. Function gets
451+
// iterator passed as parameter.
452+
template <typename F>
453+
void withEvictionIterator(F&& f);
454+
450455
// get the current config as a copy
451456
Config getConfig() const;
452457

cachelib/allocator/MMLru-inl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,15 @@ MMLru::Container<T, HookPtr>::getEvictionIterator() const noexcept {
218218
return Iterator{std::move(l), lru_.rbegin()};
219219
}
220220

221+
template <typename T, MMLru::Hook<T> T::*HookPtr>
222+
template <typename F>
223+
void
224+
MMLru::Container<T, HookPtr>::withEvictionIterator(F&& fun) {
225+
lruMutex_->lock_combine([this, &fun]() {
226+
fun(Iterator{LockHolder{}, lru_.rbegin()});
227+
});
228+
}
229+
221230
template <typename T, MMLru::Hook<T> T::*HookPtr>
222231
void MMLru::Container<T, HookPtr>::ensureNotInsertionPoint(T& node) noexcept {
223232
// If we are removing the insertion point node, grow tail before we remove

cachelib/allocator/MMLru.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,11 @@ class MMLru {
332332
// container and only one such iterator can exist at a time
333333
Iterator getEvictionIterator() const noexcept;
334334

335+
// Execute provided function under container lock. Function gets
336+
// iterator passed as parameter.
337+
template <typename F>
338+
void withEvictionIterator(F&& f);
339+
335340
// get copy of current config
336341
Config getConfig() const;
337342

cachelib/allocator/MMTinyLFU-inl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,15 @@ MMTinyLFU::Container<T, HookPtr>::getEvictionIterator() const noexcept {
220220
return Iterator{std::move(l), *this};
221221
}
222222

223+
template <typename T, MMTinyLFU::Hook<T> T::*HookPtr>
224+
template <typename F>
225+
void
226+
MMTinyLFU::Container<T, HookPtr>::withEvictionIterator(F&& fun) {
227+
LockHolder l(lruMutex_);
228+
fun(Iterator{LockHolder{}, *this});
229+
}
230+
231+
223232
template <typename T, MMTinyLFU::Hook<T> T::*HookPtr>
224233
void MMTinyLFU::Container<T, HookPtr>::removeLocked(T& node) noexcept {
225234
if (isTiny(node)) {

cachelib/allocator/MMTinyLFU.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,11 @@ class MMTinyLFU {
491491
// container and only one such iterator can exist at a time
492492
Iterator getEvictionIterator() const noexcept;
493493

494+
// Execute provided function under container lock. Function gets
495+
// iterator passed as parameter.
496+
template <typename F>
497+
void withEvictionIterator(F&& f);
498+
494499
// for saving the state of the lru
495500
//
496501
// precondition: serialization must happen without any reader or writer

0 commit comments

Comments
 (0)