From 3df8878550a64c132475f142e1b88541e91ef032 Mon Sep 17 00:00:00 2001 From: Georg Wiedebach Date: Wed, 8 May 2019 14:45:08 -0500 Subject: [PATCH 1/4] Fix a shutdown issue when using busy wait where the scheduler could get stuck. --- .../runtime/barrierScheduler/implicitContext/Task.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/Task.java b/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/Task.java index 54b71162..32429a2a 100644 --- a/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/Task.java +++ b/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/Task.java @@ -91,7 +91,7 @@ public Task(long divisor) */ boolean isPending(long schedulerTick) { - return schedulerTick % divisor == 0; + return schedulerTick % divisor == 0 && !hasShutdown(); } /** From b5880ec3c1269483be905898055485852339ec94 Mon Sep 17 00:00:00 2001 From: Georg Wiedebach Date: Wed, 8 May 2019 14:45:40 -0500 Subject: [PATCH 2/4] Added a single threaded scheduler that can use the same tasks the barrier scheduler uses but in a single threaded context. --- .../SingleThreadedScheduler.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/SingleThreadedScheduler.java diff --git a/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/SingleThreadedScheduler.java b/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/SingleThreadedScheduler.java new file mode 100644 index 00000000..26f7e4a6 --- /dev/null +++ b/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/SingleThreadedScheduler.java @@ -0,0 +1,71 @@ +package us.ihmc.concurrent.runtime.barrierScheduler.implicitContext; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * A single threaded version of the {@link BarrierScheduler}. This allows running a set of tasks in + * a single thread sequentially using the same {@link Task} API as the multi-threaded version. The + * {@link #run()} method needs to be invoked every scheduler tick but no task threads need to be + * started. When a task is executed the {@link #run()} method blocks until completion of the task. + * + * @param the context type + */ +public class SingleThreadedScheduler implements Runnable +{ + private final List> tasks; + + private final C masterContext; + + private final boolean[] tasksInitialized; + + private long tick; + + public SingleThreadedScheduler(Collection> tasks, C masterContext) + { + this.tasks = new ArrayList<>(tasks); + this.masterContext = masterContext; + this.tasksInitialized = new boolean[tasks.size()]; + } + + @Override + public void run() + { + for (int i = 0; i < tasks.size(); i++) + { + Task task = tasks.get(i); + if (task.isPending(tick)) + task.updateMasterContext(masterContext); + } + + for (int i = 0; i < tasks.size(); i++) + { + Task task = tasks.get(i); + if (task.isPending(tick)) + task.updateLocalContext(masterContext); + } + + for (int i = 0; i < tasks.size(); i++) + { + Task task = tasks.get(i); + if (task.isPending(tick)) + { + if (!tasksInitialized[i]) + tasksInitialized[i] = task.initialize(); + if (tasksInitialized[i]) + task.execute(); + } + } + + tick++; + } + + public void shutdown() + { + for (int i = 0; i < tasks.size(); i++) + { + tasks.get(i).cleanup(); + } + } +} From 04f32fce689953c0e5b80b62eaf918d304f89cd8 Mon Sep 17 00:00:00 2001 From: Georg Wiedebach Date: Wed, 8 May 2019 16:53:41 -0500 Subject: [PATCH 3/4] Avoid shutdown issue by not calling run after shutdown. --- .../barrierScheduler/implicitContext/BarrierScheduler.java | 4 ++-- .../runtime/barrierScheduler/implicitContext/Task.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/BarrierScheduler.java b/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/BarrierScheduler.java index e06ea7d8..72024cea 100644 --- a/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/BarrierScheduler.java +++ b/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/BarrierScheduler.java @@ -178,8 +178,8 @@ private boolean allTasksOnSchedule() } /** - * Requests shutdown on all tasks. - * This is a blocking call. + * Requests shutdown on all tasks. This is a blocking call. After calling this do not call the + * {@link #run()} method anymore. */ public void shutdown() { diff --git a/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/Task.java b/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/Task.java index 32429a2a..54b71162 100644 --- a/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/Task.java +++ b/src/main/java/us/ihmc/concurrent/runtime/barrierScheduler/implicitContext/Task.java @@ -91,7 +91,7 @@ public Task(long divisor) */ boolean isPending(long schedulerTick) { - return schedulerTick % divisor == 0 && !hasShutdown(); + return schedulerTick % divisor == 0; } /** From a79d8157e6cc2682b51f1eea52c78437cb30999d Mon Sep 17 00:00:00 2001 From: Georg Wiedebach Date: Wed, 8 May 2019 17:05:15 -0500 Subject: [PATCH 4/4] Bump version. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 61042ae6..141440ee 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { ihmc { group = "us.ihmc" - version = "1.2.4" + version = "1.2.5" vcsUrl = "https://github.com/ihmcrobotics/ihmc-realtime" openSource = true