From 2e0922d7732fd11a21309803a693c916e9f9e75a Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 27 Nov 2018 08:33:28 +0100 Subject: [PATCH] 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. --- .../netty/util/internal/PlatformDependent.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent.java b/common/src/main/java/io/netty/util/internal/PlatformDependent.java index d60c6e76e7..1baeecbf7c 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent.java @@ -649,16 +649,12 @@ public final class PlatformDependent { private static void incrementMemoryCounter(int capacity) { if (DIRECT_MEMORY_COUNTER != null) { - for (;;) { - long usedMemory = DIRECT_MEMORY_COUNTER.get(); - long newUsedMemory = usedMemory + capacity; - if (newUsedMemory > DIRECT_MEMORY_LIMIT) { - throw new OutOfDirectMemoryError("failed to allocate " + capacity - + " byte(s) of direct memory (used: " + usedMemory + ", max: " + DIRECT_MEMORY_LIMIT + ')'); - } - if (DIRECT_MEMORY_COUNTER.compareAndSet(usedMemory, newUsedMemory)) { - break; - } + long newUsedMemory = DIRECT_MEMORY_COUNTER.addAndGet(capacity); + if (newUsedMemory > DIRECT_MEMORY_LIMIT) { + DIRECT_MEMORY_COUNTER.addAndGet(-capacity); + throw new OutOfDirectMemoryError("failed to allocate " + capacity + + " byte(s) of direct memory (used: " + (newUsedMemory - capacity) + + ", max: " + DIRECT_MEMORY_LIMIT + ')'); } } }