00001 package edu.rice.cs.hpc.traceviewer.painter;
00002
00003 import java.io.IOException;
00004 import java.util.ArrayList;
00005 import java.util.List;
00006 import java.util.concurrent.ExecutionException;
00007 import java.util.concurrent.ExecutorCompletionService;
00008 import java.util.concurrent.ExecutorService;
00009 import java.util.concurrent.Future;
00010 import java.util.Queue;
00011 import java.util.LinkedList;
00012 import java.util.concurrent.ConcurrentLinkedQueue;
00013 import java.util.concurrent.atomic.AtomicInteger;
00014
00015 import org.eclipse.core.runtime.IProgressMonitor;
00016 import org.eclipse.core.runtime.IStatus;
00017 import org.eclipse.core.runtime.Status;
00018 import org.eclipse.jface.dialogs.MessageDialog;
00019 import org.eclipse.swt.custom.BusyIndicator;
00020 import org.eclipse.swt.graphics.Device;
00021 import org.eclipse.swt.widgets.Display;
00022 import org.eclipse.ui.IWorkbenchWindow;
00023 import org.eclipse.ui.progress.UIJob;
00024
00025 import edu.rice.cs.hpc.common.ui.Util;
00026 import edu.rice.cs.hpc.data.util.OSValidator;
00027
00028 import edu.rice.cs.hpc.traceviewer.spaceTimeData.SpaceTimeDataController;
00029 import edu.rice.cs.hpc.traceviewer.timeline.BaseTimelineThread;
00030 import edu.rice.cs.hpc.traceviewer.data.db.TimelineDataSet;
00031 import edu.rice.cs.hpc.traceviewer.data.util.Debugger;
00032 import edu.rice.cs.hpc.traceviewer.util.Utility;
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 public abstract class BaseViewPaint extends UIJob
00044 {
00045
00046 protected ImageTraceAttributes attributes;
00047 protected boolean changedBounds;
00048
00049 protected final IWorkbenchWindow window;
00050
00051 protected SpaceTimeDataController controller;
00052
00053 final private ExecutorService threadExecutor;
00054 final private ISpaceTimeCanvas canvas;
00055
00067 public BaseViewPaint(String title, SpaceTimeDataController _data, ImageTraceAttributes _attributes, boolean _changeBound,
00068 IWorkbenchWindow window, ISpaceTimeCanvas canvas, ExecutorService threadExecutor)
00069 {
00070 super(title);
00071
00072 changedBounds = _changeBound;
00073 controller = _data;
00074 attributes = _data.getAttributes();
00075
00076 this.window = (window == null ? Util.getActiveWindow() : window);
00077 this.canvas = canvas;
00078 this.threadExecutor = threadExecutor;
00079 }
00080
00081
00082 @Override
00083 public IStatus runInUIThread(IProgressMonitor monitor) {
00084 IStatus status = Status.OK_STATUS;
00085
00086 BusyIndicator.showWhile(getDisplay(), getThread());
00087 if (!paint(canvas, monitor))
00088 {
00089 status = Status.CANCEL_STATUS;
00090 }
00091
00092 return status;
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 public boolean paint(ISpaceTimeCanvas canvas, IProgressMonitor monitor)
00104 {
00105
00106
00107 int linesToPaint = getNumberOfLines();
00108 Debugger.printDebug(2, "BVP-begin " + linesToPaint + " lines");
00109
00110
00111
00112
00113
00114 if (attributes.numPixelsH <= 0)
00115 return false;
00116
00117
00118
00119
00120 int launch_threads = Utility.getNumThreads(linesToPaint);
00121 if (!startPainting(linesToPaint, launch_threads, changedBounds))
00122 return false;
00123
00124 monitor.beginTask(getName(), linesToPaint);
00125
00126
00127
00128
00129
00130
00131
00132 Debugger.printDebug(2, "BVP launch threads " + launch_threads);
00133 try {
00134 launchDataGettingThreads(changedBounds, launch_threads);
00135
00136 } catch (Exception e) {
00137 MessageDialog.openError(window.getShell(), "Error while reading data",
00138 e.getMessage());
00139 e.printStackTrace();
00140
00141
00142 monitor.done();
00143 return false;
00144 }
00145
00146
00147
00148
00149
00150 final Queue<TimelineDataSet> queue;
00151 if (launch_threads > 1) {
00152 queue = new ConcurrentLinkedQueue<TimelineDataSet>();
00153 } else {
00154 queue = new LinkedList<TimelineDataSet>();
00155 }
00156
00157
00158
00159
00160
00161
00162 Debugger.printTimestampDebug("Rendering beginning (" + canvas.toString()+")");
00163
00164
00165 controller.resetCounters();
00166
00167
00168 final AtomicInteger timelineDone = new AtomicInteger(linesToPaint);
00169
00170 final double xscale = canvas.getScalePixelsPerTime();
00171 final double yscale = Math.max(canvas.getScalePixelsPerRank(), 1);
00172
00173 ExecutorCompletionService<Integer> ecs = new ExecutorCompletionService<>(threadExecutor);
00174
00175 for (int threadNum = 0; threadNum < launch_threads; threadNum++) {
00176 final BaseTimelineThread thread = getTimelineThread(canvas, xscale, yscale, queue,
00177 timelineDone, monitor);
00178 ecs.submit(thread);
00179
00180
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 Debugger.printDebug(1, canvas.toString() + " BVP --- lp: " + linesToPaint + ", tld: " + timelineDone + ", qs: " + queue.size());
00196 Debugger.printTimestampDebug("Rendering mostly finished. (" + canvas.toString()+")");
00197
00198 if (OSValidator.isUnix())
00199 {
00200
00201
00202
00203 final BasePaintThread thread = getPaintThread(queue, linesToPaint, timelineDone,
00204 Display.getCurrent(), attributes.numPixelsH);
00205 ArrayList<Integer> result = new ArrayList<Integer>();
00206 waitDataPreparationThreads(ecs, result, 1);
00207 doSingleThreadPainting(canvas, thread);
00208 } else
00209 {
00210
00211
00212
00213 final List<Future<List<ImagePosition>>> threadsPaint = new ArrayList<Future<List<ImagePosition>>>();
00214
00215 for (int threadNum=0; threadNum < launch_threads; threadNum++)
00216 {
00217 final BasePaintThread thread = getPaintThread(queue, linesToPaint, timelineDone,
00218 Display.getCurrent(), attributes.numPixelsH);
00219 if (thread != null) {
00220 final Future<List<ImagePosition>> submit = threadExecutor.submit( thread );
00221 threadsPaint.add(submit);
00222 }
00223 }
00224
00225
00226
00227 ArrayList<Integer> result = new ArrayList<Integer>();
00228 waitDataPreparationThreads(ecs, result, launch_threads);
00229 endPainting(canvas, threadsPaint);
00230 }
00231 Debugger.printTimestampDebug("Rendering finished. (" + canvas.toString()+")");
00232 monitor.done();
00233 changedBounds = false;
00234
00235 return true;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 private void doSingleThreadPainting(ISpaceTimeCanvas canvas, BasePaintThread paintThread)
00247 {
00248 try {
00249
00250 List<ImagePosition> listImages = paintThread.call();
00251
00252
00253 for ( ImagePosition image: listImages )
00254 {
00255 drawPainting(canvas, image);
00256 }
00257 } catch (Exception e) {
00258 e.printStackTrace();
00259 }
00260 }
00261
00262 private void waitDataPreparationThreads(ExecutorCompletionService<Integer> ecs,
00263 ArrayList<Integer> result, int launch_threads)
00264 {
00265 for (int i=0; i<launch_threads; i++)
00266 {
00267 try {
00268 Integer linenum = ecs.take().get();
00269 result.add(linenum);
00270 } catch (Exception e) {
00271 e.printStackTrace();
00272 }
00273 }
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 private void endPainting(ISpaceTimeCanvas canvas, List<Future<List<ImagePosition>>> listOfImageThreads)
00283 {
00284 for( Future<List<ImagePosition>> listFutures : listOfImageThreads )
00285 {
00286 try {
00287 List<ImagePosition> listImages = listFutures.get();
00288 for (ImagePosition image : listImages)
00289 {
00290 drawPainting(canvas, image);
00291 }
00292
00293 } catch (InterruptedException e) {
00294
00295 e.printStackTrace();
00296 } catch (ExecutionException e) {
00297
00298 e.printStackTrace();
00299 }
00300 }
00301 }
00302
00303
00304
00305
00306
00307
00316 abstract protected boolean startPainting(int linesToPaint, int numThreads, boolean changedBounds);
00317
00318
00319
00320
00321
00322
00323
00324 abstract protected void drawPainting(ISpaceTimeCanvas canvas, ImagePosition imagePosition);
00325
00330 abstract protected int getNumberOfLines();
00331
00332
00333
00334
00335
00336
00337
00338
00339 abstract protected void launchDataGettingThreads(boolean changedBounds, int numThreads)
00340 throws IOException;
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 abstract protected BaseTimelineThread getTimelineThread(ISpaceTimeCanvas canvas, double xscale, double yscale,
00352 Queue<TimelineDataSet> queue, AtomicInteger timelineDone, IProgressMonitor monitor);
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 abstract protected BasePaintThread getPaintThread( Queue<TimelineDataSet> queue, int numLines,
00364 AtomicInteger timelineDone, Device device, int width);
00365 }