Use addAndGet(...) as a replacement for compareAndSet(...) when tracking the direct memory usage. (#8596)

Motivation:

We can change from using compareAndSet to addAndGet, which emits a different CPU instruction on x86 (CMPXCHG to XADD) when count direct memory usage. This instruction is cheaper in general and so produce less overhead on the "happy path". If we detect too much memory usage we just rollback the change before throwing the Error.

Modifications:

Replace compareAndSet(...) with addAndGet(...)

Result:

Less overhead when tracking direct memory.
This commit is contained in:
Norman Maurer 2018-11-27 08:33:28 +01:00
parent 48c7ca8edd
commit 2e0922d773

View File

@ -649,16 +649,12 @@ public final class PlatformDependent {
private static void incrementMemoryCounter(int capacity) { private static void incrementMemoryCounter(int capacity) {
if (DIRECT_MEMORY_COUNTER != null) { if (DIRECT_MEMORY_COUNTER != null) {
for (;;) { long newUsedMemory = DIRECT_MEMORY_COUNTER.addAndGet(capacity);
long usedMemory = DIRECT_MEMORY_COUNTER.get();
long newUsedMemory = usedMemory + capacity;
if (newUsedMemory > DIRECT_MEMORY_LIMIT) { if (newUsedMemory > DIRECT_MEMORY_LIMIT) {
DIRECT_MEMORY_COUNTER.addAndGet(-capacity);
throw new OutOfDirectMemoryError("failed to allocate " + capacity throw new OutOfDirectMemoryError("failed to allocate " + capacity
+ " byte(s) of direct memory (used: " + usedMemory + ", max: " + DIRECT_MEMORY_LIMIT + ')'); + " byte(s) of direct memory (used: " + (newUsedMemory - capacity)
} + ", max: " + DIRECT_MEMORY_LIMIT + ')');
if (DIRECT_MEMORY_COUNTER.compareAndSet(usedMemory, newUsedMemory)) {
break;
}
} }
} }
} }