Repository: cassandra
Updated Branches:
  refs/heads/trunk 14bbab642 -> d8164c643


In BufferPool, make allocating thread receive a Chunk.

Prevents a condition where the thread allocating the macro chunk
could have all of the chunks taken from the queue before it
is able to use one.

patch by Jon Meredith; reviewed by Benedict for CASSANDRA-14832


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/d8164c64
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/d8164c64
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/d8164c64

Branch: refs/heads/trunk
Commit: d8164c643395e3b6579a2fe6ce6ff0423df2f520
Parents: 14bbab6
Author: Jon Meredith <jmeredit...@gmail.com>
Authored: Thu Oct 18 09:56:46 2018 -0600
Committer: Benedict Elliott Smith <bened...@apache.org>
Committed: Fri Nov 30 12:35:50 2018 +0000

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/utils/memory/BufferPool.java      | 33 +++++++++++---------
 2 files changed, 19 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/d8164c64/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 6d04416..f145a06 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 4.0
+ * BufferPool: allocating thread for new chunks should acquire directly 
(CASSANDRA-14832)
  * Send correct messaging version in internode messaging handshake's third 
message (CASSANDRA-14896)
  * Make Read and Write Latency columns consistent for proxyhistograms and 
tablehistograms (CASSANDRA-11939)
  * Make protocol checksum type option case insensitive (CASSANDRA-14716)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/d8164c64/src/java/org/apache/cassandra/utils/memory/BufferPool.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/memory/BufferPool.java 
b/src/java/org/apache/cassandra/utils/memory/BufferPool.java
index c8ad078..a67f520 100644
--- a/src/java/org/apache/cassandra/utils/memory/BufferPool.java
+++ b/src/java/org/apache/cassandra/utils/memory/BufferPool.java
@@ -241,23 +241,23 @@ public class BufferPool
         /** Return a chunk, the caller will take owership of the parent chunk. 
*/
         public Chunk get()
         {
-            while (true)
-            {
-                Chunk chunk = chunks.poll();
-                if (chunk != null)
-                    return chunk;
+            Chunk chunk = chunks.poll();
+            if (chunk != null)
+                return chunk;
 
-                if (!allocateMoreChunks())
-                    // give it one last attempt, in case someone else 
allocated before us
-                    return chunks.poll();
-            }
+            chunk = allocateMoreChunks();
+            if (chunk != null)
+                return chunk;
+
+            // another thread may have just allocated last macro chunk, so 
make one final attempt before returning null
+            return chunks.poll();
         }
 
         /**
          * This method might be called by multiple threads and that's fine if 
we add more
          * than one chunk at the same time as long as we don't exceed the 
MEMORY_USAGE_THRESHOLD.
          */
-        private boolean allocateMoreChunks()
+        private Chunk allocateMoreChunks()
         {
             while (true)
             {
@@ -266,7 +266,7 @@ public class BufferPool
                 {
                     noSpamLogger.info("Maximum memory usage reached ({}), 
cannot allocate chunk of {}",
                                       MEMORY_USAGE_THRESHOLD, 
MACRO_CHUNK_SIZE);
-                    return false;
+                    return null;
                 }
                 if (memoryUsage.compareAndSet(cur, cur + MACRO_CHUNK_SIZE))
                     break;
@@ -284,20 +284,23 @@ public class BufferPool
                                    "Attempting to continue; buffers will be 
allocated in on-heap memory which can degrade performance. " +
                                    "Make sure direct memory size 
(-XX:MaxDirectMemorySize) is large enough to accommodate off-heap memtables and 
caches.",
                                    MACRO_CHUNK_SIZE, sizeInBytes(), 
oom.toString());
-                return false;
+                return null;
             }
 
             chunk.acquire(null);
             macroChunks.add(chunk);
-            for (int i = 0 ; i < MACRO_CHUNK_SIZE ; i += CHUNK_SIZE)
+
+            final Chunk callerChunk = new Chunk(chunk.get(CHUNK_SIZE));
+            if (DEBUG)
+                debug.register(callerChunk);
+            for (int i = CHUNK_SIZE ; i < MACRO_CHUNK_SIZE; i += CHUNK_SIZE)
             {
                 Chunk add = new Chunk(chunk.get(CHUNK_SIZE));
                 chunks.add(add);
                 if (DEBUG)
                     debug.register(add);
             }
-
-            return true;
+            return callerChunk;
         }
 
         public void recycle(Chunk chunk)


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to