Skip to content

Commit 6138a5a

Browse files
authored
Adapt: Only add Chunk to central Queue if unused (#14580) (#14583)
Motivation: We can only add a Chunk to the central Queue if it is completely unused as otherwise it still is exclusively used by a Magazine Modifications: Ensure we only use the queue once the Chunk is not used anymore Result: Correctly reuse Chunks
1 parent 6c3041f commit 6138a5a

1 file changed

Lines changed: 11 additions & 16 deletions

File tree

buffer/src/main/java/io/netty/buffer/AdaptivePoolingAllocator.java

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ private boolean allocate(int size, int sizeBucket, int maxCapacity, AdaptiveByte
624624
if (last.remainingCapacity() < RETIRE_CAPACITY) {
625625
last.release();
626626
} else {
627-
transferChunk(last);
627+
transferToNextInLineOrRelease(last);
628628
}
629629
}
630630
if (curr.remainingCapacity() > size) {
@@ -646,7 +646,7 @@ private boolean allocate(int size, int sizeBucket, int maxCapacity, AdaptiveByte
646646
curr.release();
647647
current = newChunk;
648648
} else {
649-
transferChunk(newChunk);
649+
transferToNextInLineOrRelease(newChunk);
650650
}
651651
newChunk = null;
652652
} finally {
@@ -667,29 +667,24 @@ private void restoreMagazineFreed() {
667667
}
668668
}
669669

670-
private void transferChunk(Chunk current) {
671-
if (NEXT_IN_LINE.compareAndSet(this, null, current)) {
670+
private void transferToNextInLineOrRelease(Chunk chunk) {
671+
if (NEXT_IN_LINE.compareAndSet(this, null, chunk)) {
672672
return;
673673
}
674674

675-
// Detach the chunk as we are about to offer it back for reuse.
676-
current.detachFromMagazine();
677-
if (parent.offerToQueue(current)) {
678-
return;
679-
}
680-
// Attach it again
681-
current.attachToMagazine(this);
682675
Chunk nextChunk = NEXT_IN_LINE.get(this);
683676
if (nextChunk != null && nextChunk != MAGAZINE_FREED
684-
&& current.remainingCapacity() > nextChunk.remainingCapacity()) {
685-
if (NEXT_IN_LINE.compareAndSet(this, nextChunk, current)) {
677+
&& chunk.remainingCapacity() > nextChunk.remainingCapacity()) {
678+
if (NEXT_IN_LINE.compareAndSet(this, nextChunk, chunk)) {
686679
nextChunk.release();
687680
return;
688681
}
689682
}
690-
// Next-in-line is occupied AND the central queue is full.
691-
// Rare that we should get here, but we'll only do one allocation out of this chunk, then.
692-
current.release();
683+
// Next-in-line is occupied. We don't try to add it to the central queue yet as it might still be used
684+
// by some buffers and so is attached to a Magazine.
685+
// Once a Chunk is completely released by Chunk.release() it will try to move itself to the queue
686+
// as last resort.
687+
chunk.release();
693688
}
694689

695690
private Chunk newChunkAllocation(int promptingSize) {

0 commit comments

Comments
 (0)