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;
|
||||
}
|
||||
|
||||
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
|
||||
// throw an NPE.
|
||||
return HAS_UNSAFE ?
|
||||
(int) (PlatformDependent.directBufferAddress(memory) & directMemoryCacheAlignmentMask) : 0;
|
||||
int remainder = HAS_UNSAFE
|
||||
? (int) (PlatformDependent.directBufferAddress(memory) & directMemoryCacheAlignmentMask)
|
||||
: 0;
|
||||
|
||||
// offset = alignment - address & (alignment - 1)
|
||||
return directMemoryCacheAlignment - remainder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import org.junit.Assert;
|
||||
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
|
||||
public final void testAllocationCounter() {
|
||||
final PooledByteBufAllocator allocator = new PooledByteBufAllocator(
|
||||
|
Loading…
Reference in New Issue
Block a user