From 21d2423709946d77981d6bc151c4729bb361b2ec Mon Sep 17 00:00:00 2001 From: Miguel Ferreira Date: Thu, 17 Dec 2015 16:29:59 +0100 Subject: [PATCH 1/2] Add test to check that each thread has it's own execution counter --- .../network/nicira/ExecutionCounterTest.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/nicira/ExecutionCounterTest.java b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/nicira/ExecutionCounterTest.java index 18797dfc544..f063b7597c3 100644 --- a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/nicira/ExecutionCounterTest.java +++ b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/nicira/ExecutionCounterTest.java @@ -22,6 +22,10 @@ package com.cloud.network.nicira; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; + import org.junit.Test; public class ExecutionCounterTest { @@ -52,4 +56,45 @@ public class ExecutionCounterTest { assertThat(executionCounter.hasReachedExecutionLimit(), equalTo(true)); } + + @Test + public void testConcurrentUpdatesToCounter() throws Exception { + final ExecutionCounter executionCounter = new ExecutionCounter(0); + final ExecutorService executorService = Executors.newFixedThreadPool(3); + final AtomicInteger counterTask1 = new AtomicInteger(-1); + final AtomicInteger counterTask2 = new AtomicInteger(-1); + final AtomicInteger counterTask3 = new AtomicInteger(-1); + + final Runnable task1 = new Runnable() { + @Override + public void run() { + executionCounter.incrementExecutionCounter().incrementExecutionCounter(); + executionCounter.incrementExecutionCounter().incrementExecutionCounter(); + counterTask1.set(executionCounter.getValue()); + } + }; + final Runnable task2 = new Runnable() { + @Override + public void run() { + executionCounter.incrementExecutionCounter().incrementExecutionCounter(); + counterTask2.set(executionCounter.getValue()); + } + }; + final Runnable task3 = new Runnable() { + @Override + public void run() { + counterTask3.set(executionCounter.getValue()); + } + }; + + executorService.execute(task1); + executorService.execute(task2); + executorService.execute(task3); + + executorService.shutdown(); + + assertThat(counterTask1.get(), equalTo(4)); + assertThat(counterTask2.get(), equalTo(2)); + assertThat(counterTask3.get(), equalTo(0)); + } } From c35c4164d94cd6c1878b841080e96ac073342ddd Mon Sep 17 00:00:00 2001 From: Miguel Ferreira Date: Thu, 17 Dec 2015 19:47:08 +0100 Subject: [PATCH 2/2] Fix execution counter to support separate counts per thread --- .../com/cloud/network/nicira/ExecutionCounter.java | 12 ++++++++---- .../cloud/network/nicira/ExecutionCounterTest.java | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/ExecutionCounter.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/ExecutionCounter.java index 1314498211b..7eedebbf1d9 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/ExecutionCounter.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/ExecutionCounter.java @@ -19,15 +19,19 @@ package com.cloud.network.nicira; -import java.util.concurrent.atomic.AtomicInteger; - public class ExecutionCounter { private final int executionLimit; - private final AtomicInteger executionCount = new AtomicInteger(0); + private final ThreadLocal executionCount; public ExecutionCounter(final int executionLimit) { this.executionLimit = executionLimit; + executionCount = new ThreadLocal() { + @Override + protected Integer initialValue() { + return new Integer(0); + } + }; } public ExecutionCounter resetExecutionCounter() { @@ -40,7 +44,7 @@ public class ExecutionCounter { } public ExecutionCounter incrementExecutionCounter() { - executionCount.incrementAndGet(); + executionCount.set(executionCount.get() + 1); return this; } diff --git a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/nicira/ExecutionCounterTest.java b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/nicira/ExecutionCounterTest.java index f063b7597c3..b14694dc098 100644 --- a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/nicira/ExecutionCounterTest.java +++ b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/nicira/ExecutionCounterTest.java @@ -24,6 +24,7 @@ import static org.hamcrest.Matchers.equalTo; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.junit.Test; @@ -92,6 +93,7 @@ public class ExecutionCounterTest { executorService.execute(task3); executorService.shutdown(); + executorService.awaitTermination(5L, TimeUnit.SECONDS); assertThat(counterTask1.get(), equalTo(4)); assertThat(counterTask2.get(), equalTo(2));