summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Ostroukhov2012-05-11 18:40:47 (EDT)
committerPawel Piech2012-05-14 17:29:06 (EDT)
commit03d1253f689c45fcc963eff82837595a1e12ce73 (patch)
tree23a063f34cf675012f7a50f889bb39355ec89aef
parentd5cb9f4f8ff821d26f813d438f9d9df56607927e (diff)
downloadorg.eclipse.cdt-03d1253f689c45fcc963eff82837595a1e12ce73.zip
org.eclipse.cdt-03d1253f689c45fcc963eff82837595a1e12ce73.tar.gz
org.eclipse.cdt-03d1253f689c45fcc963eff82837595a1e12ce73.tar.bz2
Bug 379317 - This change coalesces runnables into one.
This improves perceived performance as repaints are not interleaved with updates. Change-Id: If9674e45adf1aa5b4d8530e22dfcd494d228f329 Reviewed-on: https://git.eclipse.org/r/5956 Reviewed-by: Pawel Piech <pawel.piech@windriver.com> IP-Clean: Pawel Piech <pawel.piech@windriver.com> Tested-by: Pawel Piech <pawel.piech@windriver.com>
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/concurrent/SimpleDisplayExecutor.java80
1 files changed, 61 insertions, 19 deletions
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/concurrent/SimpleDisplayExecutor.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/concurrent/SimpleDisplayExecutor.java
index a6fe2ec..e4a12bd 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/concurrent/SimpleDisplayExecutor.java
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/concurrent/SimpleDisplayExecutor.java
@@ -4,15 +4,18 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Wind River Systems - initial API and implementation
+ * NVIDIA - coalesce runnable in the single event loop iteration
*******************************************************************************/
package org.eclipse.cdt.dsf.ui.concurrent;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.Map;
+import java.util.Queue;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
@@ -22,13 +25,13 @@ import org.eclipse.swt.SWTException;
import org.eclipse.swt.widgets.Display;
/**
- * A simple executor which uses the display thread to run the submitted
+ * A simple executor which uses the display thread to run the submitted
* runnables. It only implements the {@link Executor}, and NOT the more
- * sophisticated {@link DsfExecutor} (which extends
- * {@link java.util.concurrent.ScheduledExecutorService}). However, this
+ * sophisticated {@link DsfExecutor} (which extends
+ * {@link java.util.concurrent.ScheduledExecutorService}). However, this
* implementation is much more efficient than DisplayDsfExecutor as it does
* not use a separate thread or maintain its own queue.
- *
+ *
* @since 1.0
*/
public class SimpleDisplayExecutor implements Executor{
@@ -36,13 +39,13 @@ public class SimpleDisplayExecutor implements Executor{
* Internal mapping of display objects to executors.
*/
private static Map<Display, SimpleDisplayExecutor> fExecutors = Collections.synchronizedMap( new HashMap<Display, SimpleDisplayExecutor>() );
-
+
/**
* Factory method for display executors.
* @param display Display to create an executor for.
* @return The new (or re-used) executor.
*/
- public static SimpleDisplayExecutor getSimpleDisplayExecutor(Display display) {
+ public static SimpleDisplayExecutor getSimpleDisplayExecutor(final Display display) {
synchronized (fExecutors) {
SimpleDisplayExecutor executor = fExecutors.get(display);
if (executor == null) {
@@ -52,26 +55,65 @@ public class SimpleDisplayExecutor implements Executor{
return executor;
}
}
-
+
/**
- * The display class used by this executor to execute the submitted runnables.
+ * The display class used by this executor to execute the submitted runnables.
*/
private final Display fDisplay;
-
- private SimpleDisplayExecutor(Display display) {
+ /**
+ * Runnables waiting for the UI loop iteration
+ */
+ private Queue<Runnable> runnables;
+
+ private SimpleDisplayExecutor(final Display display) {
fDisplay = display;
}
@Override
- public void execute(Runnable command) {
- try {
- fDisplay.asyncExec(command);
- } catch (SWTException e) {
- if (e.code == SWT.ERROR_DEVICE_DISPOSED) {
- throw new RejectedExecutionException("Display " + fDisplay + " is disposed", e); //$NON-NLS-1$ //$NON-NLS-2$
- } else {
- throw e;
+ public void execute(final Runnable command) {
+ final boolean needsPosting = enqueue(command);
+ if (needsPosting) {
+ try {
+ fDisplay.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ runInSwtThread();
+ }
+ });
+ } catch (final SWTException e) {
+ if (e.code == SWT.ERROR_DEVICE_DISPOSED) {
+ throw new RejectedExecutionException("Display " + fDisplay + " is disposed", e); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ throw e;
+ }
}
}
}
+
+ private synchronized boolean enqueue(final Runnable runnable) {
+ boolean needsPosting = false;
+ if (runnables == null) {
+ runnables = new LinkedList<Runnable>();
+ needsPosting = true;
+ }
+ runnables.offer(runnable);
+ return needsPosting;
+ }
+
+ private synchronized Runnable getNextRunnable() {
+ final Runnable runnable = runnables.poll();
+ if (runnable == null) {
+ runnables = null;
+ return null;
+ } else {
+ return runnable;
+ }
+ }
+
+ protected void runInSwtThread() {
+ Runnable runnable;
+ while ((runnable = getNextRunnable()) != null) {
+ runnable.run();
+ }
+ }
}