@@ -116,10 +116,6 @@ class FOLLY_PACK_ATTR RefcountWithFlags {
116116 // unevictable in the past.
117117 kUnevictable_NOOP ,
118118
119- // Item is accecible but content is not ready yet. Used by eviction
120- // when Item is moved between memory tiers.
121- kIncomplete ,
122-
123119 // Unused. This is just to indciate the maximum number of flags
124120 kFlagMax ,
125121 };
@@ -135,12 +131,18 @@ class FOLLY_PACK_ATTR RefcountWithFlags {
135131 RefcountWithFlags (RefcountWithFlags&&) = delete ;
136132 RefcountWithFlags& operator =(RefcountWithFlags&&) = delete ;
137133
134+ enum incResult {
135+ incOk,
136+ incFailedMoving,
137+ incFailedExclusive
138+ };
139+
138140 // Bumps up the reference count only if the new count will be strictly less
139141 // than or equal to the maxCount and the item is not exclusive
140142 // @return true if refcount is bumped. false otherwise (if item is exclusive)
141143 // @throw exception::RefcountOverflow if new count would be greater than
142144 // maxCount
143- FOLLY_ALWAYS_INLINE bool incRef () {
145+ FOLLY_ALWAYS_INLINE incResult incRef (bool failIfMoving ) {
144146 Value* const refPtr = &refCount_;
145147 unsigned int nCASFailures = 0 ;
146148 constexpr bool isWeak = false ;
@@ -155,12 +157,15 @@ class FOLLY_PACK_ATTR RefcountWithFlags {
155157 throw exception::RefcountOverflow (" Refcount maxed out." );
156158 }
157159 if (alreadyExclusive && (oldVal & kAccessRefMask ) == 0 ) {
158- return false ;
160+ return incFailedExclusive;
161+ }
162+ else if (alreadyExclusive && failIfMoving) {
163+ return incFailedMoving;
159164 }
160165
161166 if (__atomic_compare_exchange_n (refPtr, &oldVal, newCount, isWeak,
162167 __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) {
163- return true ;
168+ return incOk ;
164169 }
165170
166171 if ((++nCASFailures % 4 ) == 0 ) {
@@ -327,8 +332,8 @@ class FOLLY_PACK_ATTR RefcountWithFlags {
327332 *
328333 * Unmarking moving does not depend on `isInMMContainer`
329334 */
330- bool markMoving () {
331- auto predicate = [](const Value curValue) {
335+ bool markMoving (bool failIfRefNotZero ) {
336+ auto predicate = [failIfRefNotZero ](const Value curValue) {
332337 Value conditionBitMask = getAdminRef<kLinked >();
333338 const bool flagSet = curValue & conditionBitMask;
334339 const bool alreadyExclusive = curValue & getAdminRef<kExclusive >();
@@ -337,6 +342,9 @@ class FOLLY_PACK_ATTR RefcountWithFlags {
337342 if (!flagSet || alreadyExclusive) {
338343 return false ;
339344 }
345+ if (failIfRefNotZero && (curValue & kAccessRefMask ) != 0 ) {
346+ return false ;
347+ }
340348 if (UNLIKELY ((curValue & kAccessRefMask ) == (kAccessRefMask ))) {
341349 throw exception::RefcountOverflow (" Refcount maxed out." );
342350 }
@@ -424,14 +432,6 @@ class FOLLY_PACK_ATTR RefcountWithFlags {
424432 void unmarkNvmEvicted () noexcept { return unSetFlag<kNvmEvicted >(); }
425433 bool isNvmEvicted () const noexcept { return isFlagSet<kNvmEvicted >(); }
426434
427- /* *
428- * Marks that the item is migrating between memory tiers and
429- * not ready for access now. Accessing thread should wait.
430- */
431- void markIncomplete () noexcept { return setFlag<kIncomplete >(); }
432- void unmarkIncomplete () noexcept { return unSetFlag<kIncomplete >(); }
433- bool isIncomplete () const noexcept { return isFlagSet<kIncomplete >(); }
434-
435435 // Whether or not an item is completely drained of access
436436 // Refcount is 0 and the item is not linked, accessible, nor exclusive
437437 bool isDrained () const noexcept { return getRefWithAccessAndAdmin () == 0 ; }
0 commit comments