mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-02-22 18:05:33 +01:00
Atomic fusion before Flywheel 1.0
- Add workaround for race condition flipping the "mergeable" bit for instance pages - Sometimes a page would end up full while another thread was racing to set the mergeable bit, so when we later tried to merge pages we'd get an array index out of bounds - This change makes it so we only ever set the mergeable bit and handle the case of a full page when trying to merge - Should also help us avoid the alternative case where a page that is actually mergeable isn't marked as such
This commit is contained in:
parent
68ed161269
commit
c438fb57ca
1 changed files with 9 additions and 10 deletions
|
@ -141,12 +141,8 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
// This is safe because only one bit position changes at a time.
|
// This is safe because only one bit position changes at a time.
|
||||||
parent.fullPages.set(pageNo);
|
parent.fullPages.set(pageNo);
|
||||||
}
|
}
|
||||||
if (isEmpty(currentValue)) {
|
if (isMergeable(newValue)) {
|
||||||
// Value we just saw was zero, so since we added something we are now mergeable!
|
|
||||||
parent.mergeablePages.set(pageNo);
|
parent.mergeablePages.set(pageNo);
|
||||||
} else if (Integer.bitCount(currentValue) == 16) {
|
|
||||||
// We just filled the 17th instance, so we are no longer mergeable.
|
|
||||||
parent.mergeablePages.clear(pageNo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.instanceCount.incrementAndGet();
|
parent.instanceCount.incrementAndGet();
|
||||||
|
@ -199,11 +195,7 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
|
|
||||||
if (valid.compareAndSet(currentValue, newValue)) {
|
if (valid.compareAndSet(currentValue, newValue)) {
|
||||||
parent.validityChanged.set(pageNo);
|
parent.validityChanged.set(pageNo);
|
||||||
if (isEmpty(newValue)) {
|
if (isMergeable(newValue)) {
|
||||||
// If we decremented to zero then we're no longer mergeable.
|
|
||||||
parent.mergeablePages.clear(pageNo);
|
|
||||||
} else if (Integer.bitCount(newValue) == 16) {
|
|
||||||
// If we decremented to 16 then we're now mergeable.
|
|
||||||
parent.mergeablePages.set(pageNo);
|
parent.mergeablePages.set(pageNo);
|
||||||
}
|
}
|
||||||
// Set full page last so that other threads don't race to set the other bitsets.
|
// Set full page last so that other threads don't race to set the other bitsets.
|
||||||
|
@ -223,6 +215,13 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
// Fill the holes in this page with instances from the other page.
|
// Fill the holes in this page with instances from the other page.
|
||||||
|
|
||||||
int valid = this.valid.get();
|
int valid = this.valid.get();
|
||||||
|
|
||||||
|
if (isFull(valid)) {
|
||||||
|
// We got filled after being marked mergeable, nothing to do
|
||||||
|
parent.mergeablePages.clear(pageNo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int otherValid = other.valid.get();
|
int otherValid = other.valid.get();
|
||||||
|
|
||||||
for (int i = 0; i < ObjectStorage.PAGE_SIZE; i++) {
|
for (int i = 0; i < ObjectStorage.PAGE_SIZE; i++) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue