Skip to content

Commit b3faea9

Browse files
committed
Optimize RefcountWithFlags::decRef() implementation
1 parent 1a9525b commit b3faea9

File tree

1 file changed

+5
-22
lines changed

1 file changed

+5
-22
lines changed

Diff for: cachelib/allocator/Refcount.h

+5-22
Original file line numberDiff line numberDiff line change
@@ -170,29 +170,12 @@ class FOLLY_PACK_ATTR RefcountWithFlags {
170170
// @throw RefcountUnderflow when we are trying to decremenet from 0
171171
// refcount and have a refcount leak.
172172
FOLLY_ALWAYS_INLINE Value decRef() {
173-
Value* const refPtr = &refCount_;
174-
unsigned int nCASFailures = 0;
175-
constexpr bool isWeak = false;
176-
177-
Value oldVal = __atomic_load_n(refPtr, __ATOMIC_RELAXED);
178-
while (true) {
179-
const Value newCount = oldVal - static_cast<Value>(1);
180-
if ((oldVal & kAccessRefMask) == 0) {
181-
throw exception::RefcountUnderflow(
182-
"Trying to decRef with no refcount. RefCount Leak!");
183-
}
184-
185-
if (__atomic_compare_exchange_n(refPtr, &oldVal, newCount, isWeak,
186-
__ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) {
187-
return newCount & kRefMask;
188-
}
189-
if ((++nCASFailures % 4) == 0) {
190-
// this pause takes up to 40 clock cycles on intel and the lock cmpxchgl
191-
// above should take about 100 clock cycles. we pause once every 400
192-
// cycles or so if we are extremely unlucky
193-
folly::asm_volatile_pause();
194-
}
173+
Value oldVal = __atomic_fetch_sub(&refPtr, static_cast<Value>(1), __ATOMIC_ACQ_REL);
174+
if (UNLIKELY((oldVal & kAccessRefMask) == 0)) {
175+
throw exception::RefcountUnderflow(
176+
"Trying to decRef with no refcount. RefCount Leak!");
195177
}
178+
return oldVal - static_cast<Value>(1);
196179
}
197180

198181
// Return refcount excluding control bits and flags

0 commit comments

Comments
 (0)