Skip to content

Commit 9283cc8

Browse files
igchorbyrnedj
authored andcommitted
wakeUpWaiters in SlabRelease code (based on upstream)
1 parent 7d105a7 commit 9283cc8

File tree

2 files changed

+58
-25
lines changed

2 files changed

+58
-25
lines changed

cachelib/allocator/CacheAllocator-inl.h

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,7 +1237,7 @@ CacheAllocator<CacheTrait>::handleWithWaitContextForMovingItem(Item& item) {
12371237
}
12381238

12391239
template <typename CacheTrait>
1240-
size_t CacheAllocator<CacheTrait>::wakeUpWaiters(folly::StringPiece key,
1240+
size_t CacheAllocator<CacheTrait>::wakeUpWaitersLocked(folly::StringPiece key,
12411241
WriteHandle&& handle) {
12421242
std::unique_ptr<MoveCtx> ctx;
12431243
auto shard = getShardForKey(key);
@@ -1606,7 +1606,7 @@ CacheAllocator<CacheTrait>::findEviction(TierId tid, PoolId pid, ClassId cid) {
16061606
// wake up any readers that wait for the move to complete
16071607
// it's safe to do now, as we have the item marked exclusive and
16081608
// no other reader can be added to the waiters list
1609-
wakeUpWaiters(candidate->getKey(), WriteHandle{});
1609+
wakeUpWaiters(*candidate, {});
16101610

16111611
if (token.isValid() && shouldWriteToNvmCacheExclusive(*candidate)) {
16121612
nvmCache_->put(*candidate, std::move(token));
@@ -1617,7 +1617,7 @@ CacheAllocator<CacheTrait>::findEviction(TierId tid, PoolId pid, ClassId cid) {
16171617
XDCHECK(!candidate->isAccessible());
16181618
XDCHECK(candidate->getKey() == evictedToNext->getKey());
16191619

1620-
wakeUpWaiters(candidate->getKey(), std::move(evictedToNext));
1620+
wakeUpWaiters(*candidate, std::move(evictedToNext));
16211621
}
16221622

16231623
XDCHECK(!candidate->isMarkedForEviction() && !candidate->isMoving());
@@ -1706,7 +1706,7 @@ CacheAllocator<CacheTrait>::tryEvictToNextMemoryTier(
17061706
if(item.isExpired()) {
17071707
accessContainer_->remove(item);
17081708
item.unmarkMoving();
1709-
return acquire(&item); // TODO: wakeUpWaiters with null handle?
1709+
return acquire(&item);
17101710
}
17111711

17121712
TierId nextTier = tid; // TODO - calculate this based on some admission policy
@@ -2881,6 +2881,14 @@ void CacheAllocator<CacheTrait>::throttleWith(util::Throttler& t,
28812881
}
28822882
}
28832883

2884+
template <typename CacheTrait>
2885+
typename RefcountWithFlags::Value CacheAllocator<CacheTrait>::unmarkMovingAndWakeUpWaiters(Item &item, WriteHandle handle)
2886+
{
2887+
auto ret = item.unmarkMoving();
2888+
wakeUpWaiters(item, std::move(handle));
2889+
return ret;
2890+
}
2891+
28842892
template <typename CacheTrait>
28852893
bool CacheAllocator<CacheTrait>::moveForSlabRelease(
28862894
const SlabReleaseContext& ctx, Item& oldItem, util::Throttler& throttler) {
@@ -2899,7 +2907,8 @@ bool CacheAllocator<CacheTrait>::moveForSlabRelease(
28992907

29002908
// Nothing to move and the key is likely also bogus for chained items.
29012909
if (oldItem.isOnlyMoving()) {
2902-
oldItem.unmarkMoving();
2910+
auto ret = unmarkMovingAndWakeUpWaiters(oldItem, {});
2911+
XDCHECK(ret == 0);
29032912
const auto res =
29042913
releaseBackToAllocator(oldItem, RemoveContext::kNormal, false);
29052914
XDCHECK(res == ReleaseRes::kReleased);
@@ -2947,8 +2956,9 @@ bool CacheAllocator<CacheTrait>::moveForSlabRelease(
29472956
});
29482957
}
29492958
auto tid = getTierId(oldItem);
2950-
auto ref = oldItem.unmarkMoving();
2951-
XDCHECK_EQ(ref, 0);
2959+
auto ref = unmarkMovingAndWakeUpWaiters(oldItem, std::move(newItemHdl));
2960+
XDCHECK(ref == 0);
2961+
29522962
const auto allocInfo = allocator_[tid]->getAllocInfo(oldItem.getMemory());
29532963
allocator_[tid]->free(&oldItem);
29542964

@@ -3066,9 +3076,26 @@ bool CacheAllocator<CacheTrait>::tryMovingForSlabRelease(
30663076
}
30673077
}
30683078

3069-
return oldItem.isChainedItem()
3070-
? moveChainedItem(oldItem.asChainedItem(), newItemHdl)
3071-
: moveRegularItem(oldItem, newItemHdl);
3079+
// TODO: we can unify move*Item and move*ItemWithSync by always
3080+
// using the moving bit to block readers.
3081+
if (getNumTiers() == 1) {
3082+
return oldItem.isChainedItem()
3083+
? moveChainedItem(oldItem.asChainedItem(), newItemHdl)
3084+
: moveRegularItem(oldItem, newItemHdl);
3085+
} else {
3086+
// TODO: add support for chained items
3087+
moveRegularItemWithSync(oldItem, newItemHdl);
3088+
return true;
3089+
}
3090+
}
3091+
3092+
template <typename CacheTrait>
3093+
void CacheAllocator<CacheTrait>::wakeUpWaiters(Item& item, WriteHandle handle)
3094+
{
3095+
// readers do not block on 'moving' items in case there is only one tier
3096+
if (getNumTiers() > 1) {
3097+
wakeUpWaitersLocked(item.getKey(), std::move(handle));
3098+
}
30723099
}
30733100

30743101
template <typename CacheTrait>
@@ -3081,7 +3108,7 @@ void CacheAllocator<CacheTrait>::evictForSlabRelease(
30813108
stats_.numEvictionAttempts.inc();
30823109

30833110
if (shutDownInProgress_) {
3084-
item.unmarkMoving();
3111+
auto ref = unmarkMovingAndWakeUpWaiters(item, {});
30853112
allocator_[getTierId(item)]->abortSlabRelease(ctx);
30863113
throw exception::SlabReleaseAborted(
30873114
folly::sformat("Slab Release aborted while trying to evict"
@@ -3105,7 +3132,8 @@ void CacheAllocator<CacheTrait>::evictForSlabRelease(
31053132
// nothing needs to be done. We simply need to call unmarkMoving and free
31063133
// the item.
31073134
if (item.isOnlyMoving()) {
3108-
item.unmarkMoving();
3135+
auto ref = unmarkMovingAndWakeUpWaiters(item, {});
3136+
XDCHECK(ref == 0);
31093137
const auto res =
31103138
releaseBackToAllocator(item, RemoveContext::kNormal, false);
31113139
XDCHECK(ReleaseRes::kReleased == res);
@@ -3162,12 +3190,10 @@ void CacheAllocator<CacheTrait>::evictForSlabRelease(
31623190
// unmark the child so it will be freed
31633191
item.unmarkMoving();
31643192
unlinkItemForEviction(*evicted);
3165-
if (getNumTiers() > 1) {
3166-
// wake up any readers that wait for the move to complete
3167-
// it's safe to do now, as we have the item marked exclusive and
3168-
// no other reader can be added to the waiters list
3169-
wakeUpWaiters(evicted->getKey(), WriteHandle{});
3170-
}
3193+
// wake up any readers that wait for the move to complete
3194+
// it's safe to do now, as we have the item marked exclusive and
3195+
// no other reader can be added to the waiters list
3196+
wakeUpWaiters(*evicted, {});
31713197
} else {
31723198
continue;
31733199
}
@@ -3177,12 +3203,7 @@ void CacheAllocator<CacheTrait>::evictForSlabRelease(
31773203
token = createPutToken(*evicted);
31783204
if (evicted->markForEvictionWhenMoving()) {
31793205
unlinkItemForEviction(*evicted);
3180-
if (getNumTiers() > 1) {
3181-
// wake up any readers that wait for the move to complete
3182-
// it's safe to do now, as we have the item marked exclusive and
3183-
// no other reader can be added to the waiters list
3184-
wakeUpWaiters(evicted->getKey(), WriteHandle{});
3185-
}
3206+
wakeUpWaiters(*evicted, {});
31863207
} else {
31873208
continue;
31883209
}

cachelib/allocator/CacheAllocator.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,18 @@ class CacheAllocator : public CacheBase {
17251725
// handle to the item. On failure an empty handle.
17261726
WriteHandle tryEvictToNextMemoryTier(TierId tid, PoolId pid, Item& item);
17271727

1728+
// Wakes up waiters if there are any
1729+
//
1730+
// @param item wakes waiters that are waiting on that item
1731+
// @param handle handle to pass to the waiters
1732+
void wakeUpWaiters(Item& item, WriteHandle handle);
1733+
1734+
// Unmarks item as moving and wakes up any waiters waiting on that item
1735+
//
1736+
// @param item wakes waiters that are waiting on that item
1737+
// @param handle handle to pass to the waiters
1738+
typename RefcountWithFlags::Value unmarkMovingAndWakeUpWaiters(Item &item, WriteHandle handle);
1739+
17281740
// Try to move the item down to the next memory tier
17291741
//
17301742
// @param item the item to evict
@@ -2042,7 +2054,7 @@ class CacheAllocator : public CacheBase {
20422054

20432055
WriteHandle handleWithWaitContextForMovingItem(Item& item);
20442056

2045-
size_t wakeUpWaiters(folly::StringPiece key, WriteHandle&& handle);
2057+
size_t wakeUpWaitersLocked(folly::StringPiece key, WriteHandle&& handle);
20462058

20472059
class MoveCtx {
20482060
public:

0 commit comments

Comments
 (0)