This is an automated email from the ASF dual-hosted git repository. mck pushed a commit to branch cassandra-3.0 in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/cassandra-3.0 by this push: new 5a6d52b Remove CAS failures and competition in Region.allocate(..) methods with use of getAndAdd(..) updates instead of compareAndSet(..) loops. 5a6d52b is described below commit 5a6d52b26191ab1f5df6e9cf941e0f964dd95a28 Author: Mick Semb Wever <m...@apache.org> AuthorDate: Sun Jul 5 14:06:25 2020 +0200 Remove CAS failures and competition in Region.allocate(..) methods with use of getAndAdd(..) updates instead of compareAndSet(..) loops. patch by Mick Semb Wever; reviewed by Robert Stupp, Benedict Elliott Smith for CASSANDRA-15922 --- CHANGES.txt | 1 + .../cassandra/utils/memory/NativeAllocator.java | 34 ++++++---------------- .../cassandra/utils/memory/SlabAllocator.java | 31 +++++--------------- 3 files changed, 18 insertions(+), 48 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d94041b..a363005 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.0.21 + * Avoid thread starvation, and improve compare-and-swap performance, in the slab allocators (CASSANDRA-15922) * Fix broken KEYS 2i queries after DROP COMPACT STORAGE (CASSANDRA-15906) * Add token to tombstone warning and error messages (CASSANDRA-15890) * Fixed range read concurrency factor computation and capped as 10 times tpc cores (CASSANDRA-15752) diff --git a/src/java/org/apache/cassandra/utils/memory/NativeAllocator.java b/src/java/org/apache/cassandra/utils/memory/NativeAllocator.java index 67f2a36..3d4ec16 100644 --- a/src/java/org/apache/cassandra/utils/memory/NativeAllocator.java +++ b/src/java/org/apache/cassandra/utils/memory/NativeAllocator.java @@ -24,7 +24,6 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.db.DecoratedKey; import org.apache.cassandra.db.NativeDecoratedKey; import org.apache.cassandra.db.rows.Row; @@ -188,11 +187,6 @@ public class NativeAllocator extends MemtableAllocator private AtomicInteger nextFreeOffset = new AtomicInteger(0); /** - * Total number of allocations satisfied from this buffer - */ - private AtomicInteger allocCount = new AtomicInteger(); - - /** * Create an uninitialized region. Note that memory is not allocated yet, so * this is cheap. * @@ -207,34 +201,24 @@ public class NativeAllocator extends MemtableAllocator /** * Try to allocate <code>size</code> bytes from the region. * - * @return the successful allocation, or null to indicate not-enough-space + * @return the successful allocation, or -1 to indicate not-enough-space */ long allocate(int size) { - while (true) - { - int oldOffset = nextFreeOffset.get(); - - if (oldOffset + size > capacity) // capacity == remaining - return -1; - - // Try to atomically claim this region - if (nextFreeOffset.compareAndSet(oldOffset, oldOffset + size)) - { - // we got the alloc - allocCount.incrementAndGet(); - return peer + oldOffset; - } - // we raced and lost alloc, try again - } + int newOffset = nextFreeOffset.getAndAdd(size); + + if (newOffset + size > capacity) + // this region is full + return -1; + + return peer + newOffset; } @Override public String toString() { return "Region@" + System.identityHashCode(this) + - " allocs=" + allocCount.get() + "waste=" + - (capacity - nextFreeOffset.get()); + "waste=" + Math.max(0, capacity - nextFreeOffset.get()); } } diff --git a/src/java/org/apache/cassandra/utils/memory/SlabAllocator.java b/src/java/org/apache/cassandra/utils/memory/SlabAllocator.java index e797575..5a8ec18 100644 --- a/src/java/org/apache/cassandra/utils/memory/SlabAllocator.java +++ b/src/java/org/apache/cassandra/utils/memory/SlabAllocator.java @@ -172,11 +172,6 @@ public class SlabAllocator extends MemtableBufferAllocator private AtomicInteger nextFreeOffset = new AtomicInteger(0); /** - * Total number of allocations satisfied from this buffer - */ - private AtomicInteger allocCount = new AtomicInteger(); - - /** * Create an uninitialized region. Note that memory is not allocated yet, so * this is cheap. * @@ -194,30 +189,20 @@ public class SlabAllocator extends MemtableBufferAllocator */ public ByteBuffer allocate(int size) { - while (true) - { - int oldOffset = nextFreeOffset.get(); - - if (oldOffset + size > data.capacity()) // capacity == remaining - return null; - - // Try to atomically claim this region - if (nextFreeOffset.compareAndSet(oldOffset, oldOffset + size)) - { - // we got the alloc - allocCount.incrementAndGet(); - return (ByteBuffer) data.duplicate().position(oldOffset).limit(oldOffset + size); - } - // we raced and lost alloc, try again - } + int newOffset = nextFreeOffset.getAndAdd(size); + + if (newOffset + size > data.capacity()) + // this region is full + return null; + + return (ByteBuffer) data.duplicate().position((newOffset)).limit(newOffset + size); } @Override public String toString() { return "Region@" + System.identityHashCode(this) + - " allocs=" + allocCount.get() + "waste=" + - (data.capacity() - nextFreeOffset.get()); + "waste=" + Math.max(0, data.capacity() - nextFreeOffset.get()); } } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org