Fix offset calculation in PooledByteBufAllocator when used
Motivation: When we create new chunk with memory aligned, the offset of direct memory should be 'alignment - address & (alignment - 1)', not just 'address & (alignment - 1)'. Modification: Change offset calculating formula to offset = alignment - address & (alignment - 1) in PoolArena.DirectArena#offsetCacheLine and add a unit test to assert that. Result: Correctly calculate offset.
This commit is contained in:
parent
f4e4147df8
commit
89639ce322
@ -725,11 +725,16 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int offsetCacheLine(ByteBuffer memory) {
|
// mark as package-private, only for unit test
|
||||||
|
int offsetCacheLine(ByteBuffer memory) {
|
||||||
// We can only calculate the offset if Unsafe is present as otherwise directBufferAddress(...) will
|
// We can only calculate the offset if Unsafe is present as otherwise directBufferAddress(...) will
|
||||||
// throw an NPE.
|
// throw an NPE.
|
||||||
return HAS_UNSAFE ?
|
int remainder = HAS_UNSAFE
|
||||||
(int) (PlatformDependent.directBufferAddress(memory) & directMemoryCacheAlignmentMask) : 0;
|
? (int) (PlatformDependent.directBufferAddress(memory) & directMemoryCacheAlignmentMask)
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
// offset = alignment - address & (alignment - 1)
|
||||||
|
return directMemoryCacheAlignment - remainder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
|
import io.netty.util.internal.PlatformDependent;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -43,6 +44,25 @@ public class PoolArenaTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectArenaOffsetCacheLine() throws Exception {
|
||||||
|
int capacity = 5;
|
||||||
|
int alignment = 128;
|
||||||
|
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
ByteBuffer bb = PlatformDependent.useDirectBufferNoCleaner()
|
||||||
|
? PlatformDependent.allocateDirectNoCleaner(capacity + alignment)
|
||||||
|
: ByteBuffer.allocateDirect(capacity + alignment);
|
||||||
|
|
||||||
|
PoolArena.DirectArena arena = new PoolArena.DirectArena(null, 0, 0, 9, 9, alignment);
|
||||||
|
int offset = arena.offsetCacheLine(bb);
|
||||||
|
long address = PlatformDependent.directBufferAddress(bb);
|
||||||
|
|
||||||
|
Assert.assertEquals(0, (offset + address) & (alignment - 1));
|
||||||
|
PlatformDependent.freeDirectBuffer(bb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void testAllocationCounter() {
|
public final void testAllocationCounter() {
|
||||||
final PooledByteBufAllocator allocator = new PooledByteBufAllocator(
|
final PooledByteBufAllocator allocator = new PooledByteBufAllocator(
|
||||||
|
Loading…
Reference in New Issue
Block a user