Skip to content

Commit f0e8314

Browse files
committed
Execute findEviction critical section
under MMContainer combined_lock.
1 parent d57dba8 commit f0e8314

File tree

7 files changed

+70
-27
lines changed

7 files changed

+70
-27
lines changed

cachelib/allocator/CacheAllocator-inl.h

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,26 +1219,39 @@ CacheAllocator<CacheTrait>::findEviction(PoolId pid, ClassId cid) {
12191219
// Keep searching for a candidate until we were able to evict it
12201220
// or until the search limit has been exhausted
12211221
unsigned int searchTries = 0;
1222-
auto itr = mmContainer.getEvictionIterator();
12231222
while ((config_.evictionSearchTries == 0 ||
1224-
config_.evictionSearchTries > searchTries) &&
1225-
itr) {
1223+
config_.evictionSearchTries > searchTries)) {
12261224
++searchTries;
12271225

1228-
Item* toRecycle = itr.get();
1226+
Item* toRecycle = nullptr;
1227+
Item* candidate = nullptr;
12291228

1230-
Item* candidate =
1231-
toRecycle->isChainedItem()
1232-
? &toRecycle->asChainedItem().getParentItem(compressor_)
1233-
: toRecycle;
1229+
mmContainer.withEvictionIterator([this, &candidate, &toRecycle, &searchTries](auto &&itr){
1230+
while ((config_.evictionSearchTries == 0 ||
1231+
config_.evictionSearchTries > searchTries) && itr) {
1232+
++searchTries;
12341233

1235-
// make sure no other thead is evicting the item
1236-
if (candidate->getRefCount() != 0 || !candidate->markMoving()) {
1237-
++itr;
1234+
auto *toRecycle_ = itr.get();
1235+
auto *candidate_ = toRecycle_->isChainedItem()
1236+
? &toRecycle_->asChainedItem().getParentItem(compressor_)
1237+
: toRecycle_;
1238+
1239+
// make sure no other thead is evicting the item
1240+
if (candidate_->getRefCount() == 0 && candidate_->markMoving()) {
1241+
toRecycle = toRecycle_;
1242+
candidate = candidate_;
1243+
return;
1244+
}
1245+
1246+
++itr;
1247+
}
1248+
});
1249+
1250+
if (!toRecycle)
12381251
continue;
1239-
}
12401252

1241-
itr.destroy();
1253+
XDCHECK(toRecycle);
1254+
XDCHECK(candidate);
12421255

12431256
// for chained items, the ownership of the parent can change. We try to
12441257
// evict what we think as parent and see if the eviction of parent
@@ -1299,8 +1312,6 @@ CacheAllocator<CacheTrait>::findEviction(PoolId pid, ClassId cid) {
12991312
return toRecycle;
13001313
}
13011314
}
1302-
1303-
itr.resetToBegin();
13041315
}
13051316
return nullptr;
13061317
}

cachelib/allocator/MM2Q-inl.h

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -238,22 +238,21 @@ MM2Q::Container<T, HookPtr>::getEvictionIterator() const noexcept {
238238
// arbitrary amount of time outside a lambda-friendly piece of code (eg. they
239239
// can return the iterator from functions, pass it to functions, etc)
240240
//
241-
// it would be theoretically possible to refactor this interface into
242-
// something like the following to allow combining
243-
//
244-
// mm2q.withEvictionIterator([&](auto iterator) {
245-
// // user code
246-
// });
247-
//
248-
// at the time of writing it is unclear if the gains from combining are
249-
// reasonable justification for the codemod required to achieve combinability
250-
// as we don't expect this critical section to be the hotspot in user code.
251-
// This is however subject to change at some time in the future as and when
252-
// this assertion becomes false.
241+
// to get advantage of combining, use withEvictionIterator
253242
LockHolder l(*lruMutex_);
254243
return Iterator{std::move(l), lru_.rbegin()};
255244
}
256245

246+
template <typename T, MM2Q::Hook<T> T::*HookPtr>
247+
template <typename F>
248+
void
249+
MM2Q::Container<T, HookPtr>::withEvictionIterator(F&& fun) {
250+
lruMutex_->lock_combine([this, &fun]() {
251+
fun(Iterator{LockHolder{}, lru_.rbegin()});
252+
});
253+
}
254+
255+
257256
template <typename T, MM2Q::Hook<T> T::*HookPtr>
258257
void MM2Q::Container<T, HookPtr>::removeLocked(T& node,
259258
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
@@ -225,6 +225,15 @@ MMLru::Container<T, HookPtr>::getEvictionIterator() const noexcept {
225225
return Iterator{std::move(l), lru_.rbegin()};
226226
}
227227

228+
template <typename T, MMLru::Hook<T> T::*HookPtr>
229+
template <typename F>
230+
void
231+
MMLru::Container<T, HookPtr>::withEvictionIterator(F&& fun) {
232+
lruMutex_->lock_combine([this, &fun]() {
233+
fun(Iterator{LockHolder{}, lru_.rbegin()});
234+
});
235+
}
236+
228237
template <typename T, MMLru::Hook<T> T::*HookPtr>
229238
void MMLru::Container<T, HookPtr>::ensureNotInsertionPoint(T& node) noexcept {
230239
// 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
@@ -219,6 +219,15 @@ MMTinyLFU::Container<T, HookPtr>::getEvictionIterator() const noexcept {
219219
return Iterator{std::move(l), *this};
220220
}
221221

222+
template <typename T, MMTinyLFU::Hook<T> T::*HookPtr>
223+
template <typename F>
224+
void
225+
MMTinyLFU::Container<T, HookPtr>::withEvictionIterator(F&& fun) {
226+
LockHolder l(lruMutex_);
227+
fun(Iterator{LockHolder{}, *this});
228+
}
229+
230+
222231
template <typename T, MMTinyLFU::Hook<T> T::*HookPtr>
223232
void MMTinyLFU::Container<T, HookPtr>::removeLocked(T& node) noexcept {
224233
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)