// // Reference count states: // // * If the reference count is zero, it will never change again. // // * If the reference count is positive, it can be both retained // (increased) and released (decreased). // // * If the reference count is negative, is can only be released // (increased). A negative reference count means that one or more // threads are waiting for one or more other threads to release // their references. // // The reference lock is used for waiting until the reference // count has become zero (released) or negative one (claimed). //
// If the previous reference count was 1, then we just changed it to -1, // and we have now claimed the page. Otherwise we wait until it is claimed. if (ref_count != 1) {
ZLocker<ZConditionLock> locker(&_ref_lock); while (Atomic::load_acquire(&_ref_count) != -1) {
_ref_lock.wait();
}
}
if (ref_count > 0) { // Decrement reference count if (Atomic::cmpxchg(&_ref_count, ref_count, ref_count - 1) != ref_count) { continue;
}
// If the previous reference count was 1, then we just decremented // it to 0 and we should signal that the page is now released. if (ref_count == 1) { // Notify released
ZLocker<ZConditionLock> locker(&_ref_lock);
_ref_lock.notify_all();
}
} else { // Increment reference count if (Atomic::cmpxchg(&_ref_count, ref_count, ref_count + 1) != ref_count) { continue;
}
// If the previous reference count was -2 or -1, then we just incremented it // to -1 or 0, and we should signal the that page is now claimed or released. if (ref_count == -2 || ref_count == -1) { // Notify claimed or released
ZLocker<ZConditionLock> locker(&_ref_lock);
_ref_lock.notify_all();
}
}
return;
}
}
bool ZForwarding::wait_page_released() const { if (Atomic::load_acquire(&_ref_count) != 0) {
ZStatTimer timer(ZCriticalPhaseRelocationStall);
ZLocker<ZConditionLock> locker(&_ref_lock); while (Atomic::load_acquire(&_ref_count) != 0) { if (_ref_abort) { returnfalse;
}
_ref_lock.wait();
}
}
returntrue;
}
ZPage* ZForwarding::detach_page() { // Wait until released if (Atomic::load_acquire(&_ref_count) != 0) {
ZLocker<ZConditionLock> locker(&_ref_lock); while (Atomic::load_acquire(&_ref_count) != 0) {
_ref_lock.wait();
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.