Reduce the scope of synchronized block in PoolArena (#10410)

Motivation:

We shouldn't call incSmallAllocation() in a synchronized block as its backed by a concurrent datastructure

Modifications:

Move call of incSmallAllocation() out of synchronized block

Result:

Minimize scope of synchronized block
This commit is contained in:
Norman Maurer 2020-07-16 19:40:40 +02:00
parent 72758f7587
commit 8c0f1428af

View File

@ -158,21 +158,24 @@ abstract class PoolArena<T> extends SizeClasses implements PoolArenaMetric {
* {@link PoolChunk#free(long)} may modify the doubly linked list as well. * {@link PoolChunk#free(long)} may modify the doubly linked list as well.
*/ */
final PoolSubpage<T> head = smallSubpagePools[sizeIdx]; final PoolSubpage<T> head = smallSubpagePools[sizeIdx];
final boolean needsNormalAllocation;
synchronized (head) { synchronized (head) {
final PoolSubpage<T> s = head.next; final PoolSubpage<T> s = head.next;
if (s != head) { needsNormalAllocation = s == head;
if (!needsNormalAllocation) {
assert s.doNotDestroy && s.elemSize == sizeIdx2size(sizeIdx); assert s.doNotDestroy && s.elemSize == sizeIdx2size(sizeIdx);
long handle = s.allocate(); long handle = s.allocate();
assert handle >= 0; assert handle >= 0;
s.chunk.initBufWithSubpage(buf, null, handle, reqCapacity, cache); s.chunk.initBufWithSubpage(buf, null, handle, reqCapacity, cache);
incSmallAllocation();
return;
} }
} }
synchronized (this) { if (needsNormalAllocation) {
allocateNormal(buf, reqCapacity, sizeIdx, cache); synchronized (this) {
allocateNormal(buf, reqCapacity, sizeIdx, cache);
}
} }
incSmallAllocation(); incSmallAllocation();
} }