~ubuntu-branches/ubuntu/trusty/eclipse-linuxtools/trusty

« back to all changes in this revision

Viewing changes to systemtap/org.eclipse.linuxtools.threadprofiler/threadprofiler.patch

  • Committer: Package Import Robot
  • Author(s): Jakub Adam
  • Date: 2012-06-29 12:07:30 UTC
  • Revision ID: package-import@ubuntu.com-20120629120730-bfri1xys1i71dpn6
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
diff --git a/ThreadProfile.stp b/ThreadProfile.stp
 
2
index 4d7fe50..daab497 100644
 
3
--- a/ThreadProfile.stp
 
4
+++ b/ThreadProfile.stp
 
5
@@ -39,31 +39,30 @@ probe process(@1).function("*").call {
 
6
                setup();
 
7
                pid = pid();
 
8
        }
 
9
+       if (! threadcounters[tid()] ) {
 
10
+               threadstacks[tid()] = probefunc();
 
11
+       }
 
12
        threadcounters[tid()]++;
 
13
-       threadstacks[tid(),threadcounters[tid()]] = probefunc();
 
14
 }
 
15
 
 
16
 probe process(@1).function("*").return {
 
17
-    delete(threadstacks[tid(),threadcounters[tid()]]);
 
18
-    if (threadcounters[tid()] == 1) {
 
19
+       threadcounters[tid()]--;
 
20
+    if (! threadcounters[tid()]) {
 
21
        delete(threadcounters[tid()]);
 
22
-       delete(threadstacks[tid(),0]);
 
23
+       delete(threadstacks[tid()]);
 
24
     }
 
25
-    else
 
26
-       threadcounters[tid()]--;
 
27
 }
 
28
 
 
29
 
 
30
 # ------------------------------------------------------------------------
 
31
 # general gnuplot graphical report generation
 
32
 
 
33
-probe timer.ms(500) {
 
34
+probe timer.ms(100) {
 
35
   printf("--\n");
 
36
   printf("%d, %d, %d, %d, %d, %d, %d, %d\n", counter, qsq_util_reset("cpu"), qsq_util_reset("ioblock"), proc_mem_size() * mem_page_size(), proc_mem_data() * mem_page_size(), reads + writes, reads, writes);
 
37
   foreach (tid in threadcounters) {
 
38
-     printf("%d:%s\n", tid, threadstacks[tid, 1]);
 
39
+     printf("%d:%s\n", tid, threadstacks[tid]);
 
40
   }
 
41
-  printf("--\n");
 
42
   reads = 0;
 
43
   writes = 0;
 
44
   counter++;
 
45
diff --git a/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class b/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class
 
46
index a620579..9f26a69 100644
 
47
Binary files a/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class and b/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class differ
 
48
diff --git a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class
 
49
index 2876d9d..a35972d 100644
 
50
Binary files a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class and b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class differ
 
51
diff --git a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class
 
52
index 2015b3b..924310a 100644
 
53
Binary files a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class and b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class differ
 
54
diff --git a/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java b/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java
 
55
index 8deb632..cac1b2d 100644
 
56
--- a/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java
 
57
+++ b/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java
 
58
@@ -1,10 +1,22 @@
 
59
 package org.eclipse.linuxtools.internal.threadprofiler;
 
60
 
 
61
 public class DataPoint {
 
62
+       
 
63
+       /** Indicates that this is a raw data point */
 
64
        public static final int DATA_POINT = 0;
 
65
+       
 
66
+       /** Indicates that this is a point relative to the axis  */
 
67
        public static final int AXIS_POINT = 1;
 
68
+       
 
69
+       /** Indicates that this is an absolute pixel point */
 
70
        public static final int PIXEL_POINT = 2;
 
71
        
 
72
+       /** Inactive, do not draw this point */
 
73
+       public static final int INACTIVE = 0;
 
74
+       
 
75
+       /** Active, draw this point */
 
76
+       public static final int ACTIVE = 1;
 
77
+       
 
78
        private int[] values;
 
79
        
 
80
        private int type;
 
81
diff --git a/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java b/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java
 
82
index 9cc6ec7..f6c5dec 100644
 
83
--- a/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java
 
84
+++ b/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java
 
85
@@ -1,21 +1,74 @@
 
86
 package org.eclipse.linuxtools.internal.threadprofiler;
 
87
 
 
88
-public class ThreadGraph {
 
89
-       
 
90
-       private final String name;
 
91
-       private final int tid;
 
92
+import java.util.Iterator;
 
93
+
 
94
+import org.eclipse.linuxtools.internal.threadprofiler.graphs.GraphModel;
 
95
+import org.eclipse.swt.graphics.GC;
 
96
+import org.eclipse.swt.widgets.Composite;
 
97
+
 
98
+public class ThreadGraph extends GraphModel{
 
99
+
 
100
+       private int tid;
 
101
+       private DataPoint dp;
 
102
+       private boolean empty;
 
103
        
 
104
-       public ThreadGraph(int tid, String name) {
 
105
-               this.name = name;
 
106
+       public ThreadGraph(String name, int x, int y, int type, String units, int tid) {
 
107
+               super(name, x, y, type, units);
 
108
                this.tid = tid;
 
109
+               empty = false;
 
110
        }
 
111
        
 
112
        public int getTid() {
 
113
                return tid;
 
114
        }
 
115
        
 
116
-       public String getName() {
 
117
-               return name;
 
118
+       private void setEmpty(boolean val) {
 
119
+               empty = val;
 
120
+       }
 
121
+       
 
122
+       /**
 
123
+        * Returns true if this graph has data points and they are all empty
 
124
+        * 
 
125
+        * @return
 
126
+        */
 
127
+       public boolean isEmpty() {
 
128
+               return empty;
 
129
+       }
 
130
+       
 
131
+       @Override
 
132
+       public void drawOn(GC gc, Composite graphCanvas) {
 
133
+               int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
 
134
+
 
135
+               //Each thread should only have one buffer
 
136
+               Iterator<DataPoint> buffer = data.get(0).getIterator();
 
137
+               int xPos = this.getXOffset();
 
138
+               boolean em = true;
 
139
+               if (!buffer.hasNext())
 
140
+                       em = false;
 
141
+               while (buffer.hasNext()) {
 
142
+                       DataPoint p = buffer.next();
 
143
+                       if (p.getType() == DataPoint.ACTIVE) {
 
144
+                               em = false;
 
145
+                               gc.drawLine(xPos, getYOffset(), xPos + increment, getYOffset());
 
146
+                       }
 
147
+                       xPos += increment;
 
148
+               }
 
149
+               
 
150
+               setEmpty(em);
 
151
+       }
 
152
+
 
153
+       public void prep(DataPoint dataPoint, int i) {
 
154
+               dp = dataPoint;
 
155
+       }
 
156
+       
 
157
+       public void tick() {
 
158
+               //TODO: This method if updating requires passing around a bulky datapoint variable
 
159
+               if (dp != null)
 
160
+                       add(dp, 0);
 
161
+               else {
 
162
+                       add(new DataPoint(0, 0, DataPoint.INACTIVE), 0);
 
163
+               }
 
164
+               dp = null;
 
165
        }
 
166
 
 
167
 }
 
168
diff --git a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java
 
169
index d9dac71..6fcd306 100644
 
170
--- a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java
 
171
+++ b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java
 
172
@@ -33,21 +33,20 @@ public class ThreadProfilerParser extends SystemTapParser {
 
173
                boolean changed = false;
 
174
                try {
 
175
                        while ((line = buff.readLine()) != null) {
 
176
-                               System.out.println("Parsed: " + line);
 
177
+//                             System.out.println("Parsed: " + line);
 
178
                                changed = true;
 
179
-                               if (line.equals("--"))
 
180
+                               if (line.equals("--")) {
 
181
+                                       ((ThreadProfilerView) view).closeThreads();
 
182
                                        continue;
 
183
+                               }
 
184
                                if (line.contains(", ")) {
 
185
                                        String[] blargh = line.split(", ");
 
186
-                                       ((ThreadProfilerView) view).addNextCPUPoint(counter, blargh);
 
187
-                                       ((ThreadProfilerView) view).addNextMemoryPoint(counter++, blargh);
 
188
-                                       ((ThreadProfilerView) view).addNextDiskPoint(counter++, blargh);
 
189
+                                       ((ThreadProfilerView) view).addDataPoints(counter++, blargh);
 
190
                                } else {
 
191
                                        String[] data = line.split(":");
 
192
                                        int tid = Integer.parseInt(data[0]);
 
193
                                        ((ThreadProfilerView) view).addThread(tid, data[1]);
 
194
                                }
 
195
-                               
 
196
                        }
 
197
                        if (changed) view.update();
 
198
                } catch (NumberFormatException e) {
 
199
diff --git a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java
 
200
index 2dbaaf7..40b7460 100644
 
201
--- a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java
 
202
+++ b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java
 
203
@@ -1,265 +1,297 @@
 
204
-package org.eclipse.linuxtools.internal.threadprofiler;
 
205
-
 
206
-import java.util.ArrayList;
 
207
-
 
208
-import org.eclipse.core.runtime.IProgressMonitor;
 
209
-import org.eclipse.core.runtime.IStatus;
 
210
-import org.eclipse.core.runtime.Status;
 
211
-import org.eclipse.linuxtools.callgraph.core.SystemTapView;
 
212
-import org.eclipse.linuxtools.internal.threadprofiler.graphs.GraphModel;
 
213
-import org.eclipse.linuxtools.internal.threadprofiler.graphs.MultiGraph;
 
214
-import org.eclipse.swt.SWT;
 
215
-import org.eclipse.swt.custom.ScrolledComposite;
 
216
-import org.eclipse.swt.events.MouseEvent;
 
217
-import org.eclipse.swt.events.MouseListener;
 
218
-import org.eclipse.swt.events.PaintEvent;
 
219
-import org.eclipse.swt.events.PaintListener;
 
220
-import org.eclipse.swt.graphics.Color;
 
221
-import org.eclipse.swt.graphics.GC;
 
222
-import org.eclipse.swt.layout.GridData;
 
223
-import org.eclipse.swt.layout.GridLayout;
 
224
-import org.eclipse.swt.widgets.Button;
 
225
-import org.eclipse.swt.widgets.Canvas;
 
226
-import org.eclipse.swt.widgets.Composite;
 
227
-import org.eclipse.swt.widgets.Display;
 
228
-
 
229
-public class ThreadProfilerView extends SystemTapView {
 
230
-       private static final int CPU_BUFFER = 0;
 
231
-       private static final int MEM_BUFFER = 1;
 
232
-       private static final int DISK_BUFFER = 2;
 
233
-       private ArrayList<GraphModel> graphs;
 
234
-       private ArrayList<ThreadGraph> threads;
 
235
-
 
236
-       private Composite graphCanvas;
 
237
-       private Canvas threadCanvas;
 
238
-       private final long REFRESH_TIME_MS = 700;
 
239
-       private final static int GRAPH_SEPARATION = 40;
 
240
-       private long time;
 
241
-       private int segments;
 
242
-
 
243
-       /*
 
244
-        * We have two frames of reference: 
 
245
-        * 
 
246
-        *  1. Pixel frame (absolute frame)
 
247
-        *  2. Axis frame (relative frame)
 
248
-        *  
 
249
-        *  The transformation from 1 to 2 is a coordinate shift and scale
 
250
-        *  
 
251
-        */
 
252
-       
 
253
-       
 
254
-       @Override
 
255
-       protected boolean createOpenAction() {
 
256
-               return false;
 
257
-       }
 
258
-
 
259
-       @Override
 
260
-       protected boolean createOpenDefaultAction() {
 
261
-               return false;
 
262
-       }
 
263
-
 
264
-       @Override
 
265
-       public IStatus initializeView(Display targetDisplay,
 
266
-                       IProgressMonitor monitor) {
 
267
-               if (graphs == null)
 
268
-                       graphs = new ArrayList<GraphModel>();
 
269
-               if (threads == null)
 
270
-                       threads = new ArrayList<ThreadGraph>();
 
271
-               graphs.clear();
 
272
-               threads.clear();
 
273
-               segments = 0;
 
274
-
 
275
-               //Create dataSet for CPU
 
276
-               createNewDataSet("CPU", GraphModel.CONSTANT_Y, "%");
 
277
-               ((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
 
278
-               ((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "IO Block");
 
279
-               
 
280
-               //Create dataSet for memory
 
281
-               createNewDataSet("Memory", GraphModel.FLEXIBLE_Y, "bytes");
 
282
-               ((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
 
283
-               ((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Data");
 
284
-               
 
285
-               //Create dataSet for disk usage
 
286
-               createNewDataSet("Disk", GraphModel.FLEXIBLE_Y, "bytes");
 
287
-               ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
 
288
-               ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Read");
 
289
-               ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Write");
 
290
-               ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_FILL);
 
291
-               ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
 
292
-               ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
 
293
-
 
294
-               time = System.currentTimeMillis();
 
295
-               
 
296
-               graphCanvas.addMouseListener(new MouseListener() {
 
297
-
 
298
-                       @Override
 
299
-                       public void mouseDoubleClick(MouseEvent e) {
 
300
-                               updateMethod();
 
301
-                       }
 
302
-
 
303
-                       @Override
 
304
-                       public void mouseDown(MouseEvent e) {
 
305
-                               System.out.println("LOCATION: " + e.x + "," + e.y);
 
306
-                       }
 
307
-
 
308
-                       @Override
 
309
-                       public void mouseUp(MouseEvent e) {
 
310
-                               // TODO Auto-generated method stub
 
311
-                               
 
312
-                       }
 
313
-                       
 
314
-               });
 
315
-               
 
316
-           graphCanvas.addPaintListener(new PaintListener() {
 
317
-               public void paintControl(PaintEvent e) {
 
318
-//                     if (!graphs.get(0).isChanged())
 
319
-//                             return;
 
320
-                       
 
321
-                       
 
322
-                       for (int i = 0; i < graphs.size(); i ++) {
 
323
-                               GraphModel graph = graphs.get(i);
 
324
-                               GC gc = new GC(graphCanvas);
 
325
-                               gc.setLineWidth(2);
 
326
-                               graph.setHeight((int) (graphCanvas.getSize().y/(2.5*graphs.size())));
 
327
-                               graph.setYAxisCoordinate((graph.getHeight() + GRAPH_SEPARATION) *(i + 1));
 
328
-                               graph.drawOn(gc, graphCanvas);
 
329
-                               gc.dispose();
 
330
-                       }
 
331
-               }
 
332
-           }); 
 
333
-           
 
334
-           
 
335
-           threadCanvas.addPaintListener(new PaintListener() {
 
336
-
 
337
-                       @Override
 
338
-                       public void paintControl(PaintEvent e) {
 
339
-                               if (threads == null)
 
340
-                                       return;
 
341
-                               int yOffset = 40;
 
342
-                               
 
343
-                       GC gc = new GC(threadCanvas);
 
344
-                       gc.setLineWidth(4);
 
345
-                       gc.setForeground(new Color(Display.getCurrent(), 0, 0, 200));
 
346
-                       int increment = (graphCanvas.getSize().x - 40)/GraphModel.BUFFER_SIZE;
 
347
-
 
348
-                               for (ThreadGraph tg : threads) {
 
349
-                                       gc.drawText(tg.getName(), 40, yOffset);
 
350
-                                       gc.drawLine(40, yOffset, 40 + increment*segments, yOffset);
 
351
-                               }
 
352
-                       }
 
353
-               
 
354
-           });
 
355
-           
 
356
-               return Status.OK_STATUS;
 
357
-       }
 
358
-
 
359
-       private void createNewDataSet(String name, int type, String units) {
 
360
-               GraphModel graph = new MultiGraph(name, 50, (GraphModel.DEFAULT_HEIGHT + GRAPH_SEPARATION) *(graphs.size() + 1), type, units);
 
361
-               graphs.add(graph);
 
362
-       }
 
363
-
 
364
-       @Override
 
365
-       public void setViewID() {
 
366
-               viewID = "org.eclipse.linuxtools.internal.threadprofiler.ThreadProfilerView";
 
367
-       }
 
368
-
 
369
-       @Override
 
370
-       public void updateMethod() {
 
371
-       if (System.currentTimeMillis() - time < REFRESH_TIME_MS)
 
372
-               return;
 
373
-       time = System.currentTimeMillis();
 
374
-               graphCanvas.redraw();
 
375
-       }
 
376
-       
 
377
-       @Override
 
378
-       public void createPartControl(Composite parent) {
 
379
-               GridLayout gl = new GridLayout(1, true);
 
380
-               parent.setLayout(gl);
 
381
-               Color white = new Color(Display.getCurrent(), 255, 255, 255);
 
382
-       
 
383
-               graphCanvas = new Composite(parent, SWT.BORDER);
 
384
-       graphCanvas.setBackground(white);
 
385
-       GridData gd = new GridData(GridData.FILL_BOTH);
 
386
-       gd.grabExcessHorizontalSpace = true;
 
387
-       graphCanvas.setLayoutData(gd);
 
388
-
 
389
-       threadCanvas = new Canvas(parent, SWT.BORDER);
 
390
-       threadCanvas.setBackground(white);
 
391
-       gd = new GridData(GridData.FILL_BOTH);
 
392
-       gd.grabExcessHorizontalSpace = true;
 
393
-       threadCanvas.setLayoutData(gd);
 
394
-       }
 
395
-       
 
396
-       @Override
 
397
-       public void setFocus() {
 
398
-               //Do nothing
 
399
-       }
 
400
-       
 
401
-
 
402
-       public void addNextCPUPoint(int counter, String[] blargh) {
 
403
-               if (blargh.length < 2)
 
404
-                       return;
 
405
-               this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[1]), 1), CPU_BUFFER, 0);
 
406
-               
 
407
-               if (blargh.length < 3)
 
408
-                       return;
 
409
-               this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[2]), 1), CPU_BUFFER, 1);
 
410
-       }
 
411
-       
 
412
-       public void addNextMemoryPoint(int counter, String[] blargh) {
 
413
-               if (blargh.length < 4)
 
414
-                       return;
 
415
-               this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[3]), 1), MEM_BUFFER, 0);           
 
416
-               if (blargh.length < 5)
 
417
-                       return;
 
418
-               this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[4]), 1), MEM_BUFFER, 1);
 
419
-       }
 
420
-       
 
421
-       public void addNextDiskPoint(int counter, String[] blargh) {
 
422
-               if (blargh.length < 6)
 
423
-                       return;
 
424
-               addPoint(new DataPoint(counter, Integer.parseInt(blargh[5]), 1), DISK_BUFFER, 0);
 
425
-               
 
426
-               if (blargh.length < 7)
 
427
-                       return;
 
428
-               addPoint(new DataPoint(counter, Integer.parseInt(blargh[6]), 1), DISK_BUFFER, 1);
 
429
-               
 
430
-               if (blargh.length < 8)
 
431
-                       return;
 
432
-               addPoint(new DataPoint(counter, Integer.parseInt(blargh[7]), 1), DISK_BUFFER, 2);
 
433
-       }
 
434
-       
 
435
-       private void addPoint(DataPoint point, int dataSet, int subIndex) {
 
436
-               if (graphs.size() < 1)
 
437
-                       return;
 
438
-               if (segments < GraphModel.BUFFER_SIZE)
 
439
-                       segments++;
 
440
-               graphs.get(dataSet).add(point, subIndex);
 
441
-       }
 
442
-
 
443
-       public void addThread(int tid, String line) {
 
444
-               if (!threadExists(tid)) {
 
445
-                       ThreadGraph tg = new ThreadGraph(tid, line);
 
446
-                       threads.add(tg);
 
447
-               }
 
448
-       }
 
449
-       
 
450
-       /**
 
451
-        * Returns true if a thread with the given tid exists
 
452
-        * 
 
453
-        * @param tid
 
454
-        * @return
 
455
-        */
 
456
-       private boolean threadExists(int tid) {
 
457
-               boolean exists = false;
 
458
-               for (ThreadGraph g : threads) {
 
459
-                       if (g.getTid() == tid) {
 
460
-                               exists = true;
 
461
-                               break;
 
462
-                       }
 
463
-               }
 
464
-               return exists;
 
465
-       }
 
466
-
 
467
-
 
468
+package org.eclipse.linuxtools.internal.threadprofiler;
 
469
+
 
470
+import java.util.ArrayList;
 
471
+
 
472
+import org.eclipse.core.resources.IContainer;
 
473
+import org.eclipse.core.runtime.IProgressMonitor;
 
474
+import org.eclipse.core.runtime.IStatus;
 
475
+import org.eclipse.core.runtime.Status;
 
476
+import org.eclipse.linuxtools.callgraph.core.SystemTapView;
 
477
+import org.eclipse.linuxtools.internal.threadprofiler.graphs.GraphModel;
 
478
+import org.eclipse.linuxtools.internal.threadprofiler.graphs.MultiGraph;
 
479
+import org.eclipse.swt.SWT;
 
480
+import org.eclipse.swt.custom.ScrolledComposite;
 
481
+import org.eclipse.swt.events.MouseEvent;
 
482
+import org.eclipse.swt.events.MouseListener;
 
483
+import org.eclipse.swt.events.PaintEvent;
 
484
+import org.eclipse.swt.events.PaintListener;
 
485
+import org.eclipse.swt.graphics.Color;
 
486
+import org.eclipse.swt.graphics.GC;
 
487
+import org.eclipse.swt.layout.GridData;
 
488
+import org.eclipse.swt.layout.GridLayout;
 
489
+import org.eclipse.swt.widgets.Canvas;
 
490
+import org.eclipse.swt.widgets.Composite;
 
491
+import org.eclipse.swt.widgets.Display;
 
492
+
 
493
+public class ThreadProfilerView extends SystemTapView {
 
494
+       private static final int CPU_BUFFER = 0;
 
495
+       private static final int MEM_BUFFER = 1;
 
496
+       private static final int DISK_BUFFER = 2;
 
497
+       
 
498
+       private static final int START_X_POS = 50;
 
499
+       private ArrayList<GraphModel> graphs;
 
500
+       private ArrayList<ThreadGraph> threads;
 
501
+
 
502
+       private Composite graphCanvas;
 
503
+       private Canvas threadCanvas;
 
504
+       private final static int GRAPH_SEPARATION = 40;
 
505
+       private int segments;
 
506
+
 
507
+       /*
 
508
+        * We have two frames of reference: 
 
509
+        * 
 
510
+        *  1. Pixel frame (absolute frame)
 
511
+        *  2. Axis frame (relative frame)
 
512
+        *  
 
513
+        *  The transformation from 1 to 2 is a coordinate shift and scale
 
514
+        *  
 
515
+        */
 
516
+       
 
517
+       
 
518
+       @Override
 
519
+       protected boolean createOpenAction() {
 
520
+               return false;
 
521
+       }
 
522
+
 
523
+       @Override
 
524
+       protected boolean createOpenDefaultAction() {
 
525
+               return false;
 
526
+       }
 
527
+
 
528
+       @Override
 
529
+       public IStatus initializeView(Display targetDisplay,
 
530
+                       IProgressMonitor monitor) {
 
531
+               if (graphs == null)
 
532
+                       graphs = new ArrayList<GraphModel>();
 
533
+               if (threads == null)
 
534
+                       threads = new ArrayList<ThreadGraph>();
 
535
+               graphs.clear();
 
536
+               threads.clear();
 
537
+               segments = 0;
 
538
+
 
539
+               //Create dataSet for CPU
 
540
+               createNewDataSet("CPU", GraphModel.CONSTANT_Y, "%");
 
541
+               ((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
 
542
+               ((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "IO Block");
 
543
+               
 
544
+               //Create dataSet for memory
 
545
+               createNewDataSet("Memory", GraphModel.FLEXIBLE_Y, "bytes");
 
546
+               ((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
 
547
+               ((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Data");
 
548
+               
 
549
+               //Create dataSet for disk usage
 
550
+               createNewDataSet("Disk", GraphModel.FLEXIBLE_Y, "bytes");
 
551
+               ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
 
552
+               ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Read");
 
553
+               ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Write");
 
554
+               ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_FILL);
 
555
+               ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
 
556
+               ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
 
557
+
 
558
+               graphCanvas.addMouseListener(new MouseListener() {
 
559
+
 
560
+                       @Override
 
561
+                       public void mouseDoubleClick(MouseEvent e) {
 
562
+                               updateMethod();
 
563
+                       }
 
564
+
 
565
+                       @Override
 
566
+                       public void mouseDown(MouseEvent e) {
 
567
+                               System.out.println("LOCATION: " + e.x + "," + e.y);
 
568
+                       }
 
569
+
 
570
+                       @Override
 
571
+                       public void mouseUp(MouseEvent e) {
 
572
+                               // TODO Auto-generated method stub
 
573
+                               
 
574
+                       }
 
575
+                       
 
576
+               });
 
577
+               
 
578
+           graphCanvas.addPaintListener(new PaintListener() {
 
579
+               public void paintControl(PaintEvent e) {
 
580
+                       //TODO: If the script is running and the graph is not changed, 
 
581
+                       //there is no need to update yet.
 
582
+                       for (int i = 0; i < graphs.size(); i ++) {
 
583
+                               GraphModel graph = graphs.get(i);
 
584
+                               GC gc = new GC(graphCanvas);
 
585
+                               gc.setLineWidth(2);
 
586
+                               graph.setHeight((int) (graphCanvas.getSize().y/(2.5*graphs.size())));
 
587
+                               graph.setYAxisCoordinate((graph.getHeight() + GRAPH_SEPARATION) *(i + 1));
 
588
+                               graph.drawOn(gc, graphCanvas);
 
589
+                               gc.dispose();
 
590
+                       }
 
591
+               }
 
592
+           }); 
 
593
+           
 
594
+           
 
595
+           threadCanvas.addPaintListener(new PaintListener() {
 
596
+               
 
597
+
 
598
+                       @Override
 
599
+                       public void paintControl(PaintEvent e) {
 
600
+                               if (threads == null)
 
601
+                                       return;
 
602
+                               int yOffset = GRAPH_SEPARATION;
 
603
+                               
 
604
+                       GC gc = new GC(threadCanvas);
 
605
+                       Color fg = new Color(Display.getCurrent(), 0, 0, 200);
 
606
+                       gc.setForeground(fg);
 
607
+
 
608
+                       int counter = 0;
 
609
+                       ArrayList<ThreadGraph> toRemove = new ArrayList<ThreadGraph>();
 
610
+                               for (ThreadGraph tg : threads) {
 
611
+                                       counter++;
 
612
+                                       tg.setYAxisCoordinate(counter*yOffset);
 
613
+                                       gc.setLineWidth(2);
 
614
+                                       tg.drawOn(gc, graphCanvas); 
 
615
+                                       gc.setLineWidth(0);
 
616
+                                       gc.drawText(tg.getTitle(), START_X_POS, counter*yOffset, true);
 
617
+                                       if (tg.isEmpty())
 
618
+                                               toRemove.add(tg);
 
619
+                               }
 
620
+                               //TODO: O(N^2) operation
 
621
+                               threads.removeAll(toRemove);
 
622
+                               fg.dispose();
 
623
+                               gc.dispose();
 
624
+                       }
 
625
+           });
 
626
+           
 
627
+               return Status.OK_STATUS;
 
628
+       }
 
629
+
 
630
+       private void createNewDataSet(String name, int type, String units) {
 
631
+               GraphModel graph = new MultiGraph(name, START_X_POS, (GraphModel.DEFAULT_HEIGHT + GRAPH_SEPARATION) *(graphs.size() + 1), type, units);
 
632
+               graphs.add(graph);
 
633
+       }
 
634
+
 
635
+       @Override
 
636
+       public void setViewID() {
 
637
+               viewID = "org.eclipse.linuxtools.internal.threadprofiler.ThreadProfilerView";
 
638
+       }
 
639
+
 
640
+       @Override
 
641
+       public void updateMethod() {
 
642
+               graphCanvas.redraw();
 
643
+               threadCanvas.redraw();
 
644
+       }
 
645
+       
 
646
+       @Override
 
647
+       public void createPartControl(Composite parent) {
 
648
+               GridLayout gl = new GridLayout(1, true);
 
649
+               parent.setLayout(gl);
 
650
+               Color white = new Color(Display.getCurrent(), 255, 255, 255);
 
651
+       
 
652
+       ScrolledComposite graphComp =new ScrolledComposite(parent, SWT.BORDER | SWT.V_SCROLL);
 
653
+       graphComp.setLayout (new GridLayout(1, true));
 
654
+       graphComp.setBackground(white);
 
655
+       GridData gd = new GridData(GridData.FILL_BOTH);
 
656
+       gd.grabExcessHorizontalSpace = true;
 
657
+       graphComp.setLayoutData(gd);
 
658
+       
 
659
+               graphCanvas = new Canvas(graphComp, SWT.BORDER | SWT.V_SCROLL);
 
660
+       graphCanvas.setBackground(white);
 
661
+       gd = new GridData(GridData.FILL_BOTH);
 
662
+       gd.grabExcessHorizontalSpace = true;
 
663
+       graphCanvas.setLayoutData(gd);
 
664
+       
 
665
+       ScrolledComposite threadComp =new ScrolledComposite(parent, SWT.BORDER | SWT.V_SCROLL);
 
666
+       threadComp.setLayout (new GridLayout(1, true));
 
667
+       threadComp.setBackground(white);
 
668
+       gd = new GridData(GridData.FILL_BOTH);
 
669
+       gd.grabExcessHorizontalSpace = true;
 
670
+       threadComp.setLayoutData(gd);
 
671
+       
 
672
+       threadCanvas = new Canvas(graphComp, SWT.BORDER | SWT.V_SCROLL);
 
673
+       threadCanvas.setBackground(white);
 
674
+       gd = new GridData(GridData.FILL_BOTH);
 
675
+       gd.grabExcessHorizontalSpace = true;
 
676
+       threadCanvas.setLayoutData(gd);
 
677
+       }
 
678
+       
 
679
+       @Override
 
680
+       public void setFocus() {
 
681
+               //Do nothing
 
682
+       }
 
683
+       
 
684
+
 
685
+       
 
686
+       public void addDataPoints(int counter, String[] blargh) {
 
687
+               if (segments < GraphModel.BUFFER_SIZE)
 
688
+                       segments++;
 
689
+               if (blargh.length < 2)
 
690
+                       return;
 
691
+               this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[1]), 1), CPU_BUFFER, 0);
 
692
+               
 
693
+               if (blargh.length < 3)
 
694
+                       return;
 
695
+               this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[2]), 1), CPU_BUFFER, 1);
 
696
+               
 
697
+               if (blargh.length < 4)
 
698
+                       return;
 
699
+               this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[3]), 1), MEM_BUFFER, 0);
 
700
+               
 
701
+               if (blargh.length < 5)
 
702
+                       return;
 
703
+               this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[4]), 1), MEM_BUFFER, 1);
 
704
+               
 
705
+               if (blargh.length < 6)
 
706
+                       return;
 
707
+               addPoint(new DataPoint(counter, Integer.parseInt(blargh[5]), 1), DISK_BUFFER, 0);
 
708
+               
 
709
+               if (blargh.length < 7)
 
710
+                       return;
 
711
+               addPoint(new DataPoint(counter, Integer.parseInt(blargh[6]), 1), DISK_BUFFER, 1);
 
712
+               
 
713
+               if (blargh.length < 8)
 
714
+                       return;
 
715
+               addPoint(new DataPoint(counter, Integer.parseInt(blargh[7]), 1), DISK_BUFFER, 2);
 
716
+       }
 
717
+       
 
718
+       
 
719
+       private void addPoint(DataPoint point, int dataSet, int subIndex) {
 
720
+               if (graphs.size() < 1)
 
721
+                       return;
 
722
+               graphs.get(dataSet).add(point, subIndex);
 
723
+       }
 
724
+
 
725
+       public void addThread(int tid, String line) {
 
726
+               int i = threadExists(tid);
 
727
+               if (i < 0) {
 
728
+                       ThreadGraph tg = new ThreadGraph(line, START_X_POS, GRAPH_SEPARATION, 0, "", tid);
 
729
+                       for (int j = 0; j < segments; j++) {
 
730
+                               //Fill with empty segments
 
731
+                               tg.add(new DataPoint(0, 0, DataPoint.INACTIVE), 0);
 
732
+                       }
 
733
+                               threads.add(tg);
 
734
+                       i = threads.size() - 1;
 
735
+               }
 
736
+               threads.get(i).prep(new DataPoint(0, 0, DataPoint.ACTIVE), 0);
 
737
+       }
 
738
+       
 
739
+
 
740
+       public void closeThreads() {
 
741
+               // TODO Auto-generated method stub
 
742
+               for (ThreadGraph tg : threads) {
 
743
+                       tg.tick();
 
744
+               }
 
745
+       }               
 
746
+       
 
747
+       /**
 
748
+        * Returns true if a thread with the given tid exists
 
749
+        * 
 
750
+        * @param tid
 
751
+        * @return
 
752
+        */
 
753
+       private int threadExists(int tid) {
 
754
+               for (int i = 0; i < threads.size(); i++) {
 
755
+                       if (threads.get(i).getTid() == tid) {
 
756
+                               return i;
 
757
+                       }
 
758
+               }
 
759
+               return -1;
 
760
+       }
 
761
+
 
762
+
 
763
+
 
764
 }
 
765
\ No newline at end of file
 
766
diff --git a/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java b/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java
 
767
index 5bf0531..1b07e18 100644
 
768
--- a/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java
 
769
+++ b/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java
 
770
@@ -1,226 +1,229 @@
 
771
-package org.eclipse.linuxtools.internal.threadprofiler.graphs;
 
772
-
 
773
-import java.util.ArrayList;
 
774
-import java.util.Iterator;
 
775
-
 
776
-import org.eclipse.linuxtools.internal.threadprofiler.CircularPointBuffer;
 
777
-import org.eclipse.linuxtools.internal.threadprofiler.CoordinateSystem;
 
778
-import org.eclipse.linuxtools.internal.threadprofiler.DataPoint;
 
779
-import org.eclipse.linuxtools.internal.threadprofiler.GraphAxis;
 
780
-import org.eclipse.swt.graphics.Color;
 
781
-import org.eclipse.swt.graphics.GC;
 
782
-import org.eclipse.swt.widgets.Canvas;
 
783
-import org.eclipse.swt.widgets.Composite;
 
784
-import org.eclipse.swt.widgets.Display;
 
785
-
 
786
-public abstract class GraphModel {
 
787
-       
 
788
-       //Constant Y scale
 
789
-       public static final int CONSTANT_Y = 0;
 
790
-       //Change Y scale as the maximum y point increases
 
791
-       public static final int FLEXIBLE_Y = 1;
 
792
-       //Maximum buffer size
 
793
-       public static final int BUFFER_SIZE = 30;
 
794
-       //Default height
 
795
-       public static final int DEFAULT_HEIGHT = 100;
 
796
-       
 
797
-       private final CoordinateSystem coordinates;
 
798
-       private final DataPoint startPoint;
 
799
-       private final int graphType;
 
800
-       private final String title;
 
801
-       private final String units;
 
802
-       private boolean changed;
 
803
-       protected final ArrayList<CircularPointBuffer> data;
 
804
-       
 
805
-       private int height;
 
806
-       
 
807
-       private int maxY;
 
808
-       //Height in pixels
 
809
-       
 
810
-       public GraphModel(String name, int x, int y, int type, String units) {
 
811
-               graphType = type;
 
812
-               changed = false;
 
813
-               data = new ArrayList<CircularPointBuffer>();
 
814
-               title = name;
 
815
-               this.units = units;
 
816
-               height = DEFAULT_HEIGHT;
 
817
-               maxY = 100;
 
818
-               coordinates = new CoordinateSystem(x, y);
 
819
-               coordinates.setYScale(0.2);
 
820
-               coordinates.getAxis().setTopLabel(DEFAULT_HEIGHT + units);
 
821
-               
 
822
-               startPoint = new DataPoint(coordinates.getXOffset(), coordinates.getYOffset(), 1);
 
823
-       }
 
824
-       
 
825
-       public void setMaxY(int max) {
 
826
-               maxY = max;
 
827
-       }
 
828
-       
 
829
-       public int getXOffset() {
 
830
-               return (int) coordinates.getAxisToPixel().entries[0][2];
 
831
-       }
 
832
-       
 
833
-       public int getYOffset() {
 
834
-               return (int) coordinates.getAxisToPixel().entries[1][2];
 
835
-       }
 
836
-
 
837
-
 
838
-       /**
 
839
-        * 
 
840
-        * @return
 
841
-        *                        First available point buffer if any is available, else null
 
842
-        */
 
843
-       public Iterator<DataPoint> getPointBuffer() {
 
844
-               if (data.size() > 1)
 
845
-                       return getPointBuffer(0);
 
846
-               return null;
 
847
-       }
 
848
-       
 
849
-       public Iterator<DataPoint> getPointBuffer(int index) {
 
850
-               return data.get(index).getIterator();
 
851
-       }
 
852
-
 
853
-       public GraphAxis getAxis() {
 
854
-               return coordinates.getAxis();
 
855
-       }
 
856
-       
 
857
-       public DataPoint getStartPoint() {
 
858
-               return startPoint;
 
859
-       }
 
860
-
 
861
-       public void add(DataPoint point, int subIndex) {
 
862
-               if (subIndex >= data.size()) {
 
863
-                       data.add(new CircularPointBuffer(BUFFER_SIZE));
 
864
-               }
 
865
-               if (graphType == FLEXIBLE_Y) {
 
866
-                       if (point.getY() > maxY ) {
 
867
-                               maxY = point.getY();
 
868
-                               coordinates.getAxis().setTopLabel(maxY + " " + units);
 
869
-                               if ( point.getY() > height) {
 
870
-                                       double newScale = (double) height/maxY;
 
871
-                                       coordinates.setYScale(newScale);
 
872
-                               }
 
873
-                       }
 
874
-               }
 
875
-               data.get(subIndex).add(point);
 
876
-               setChanged(true);
 
877
-       }
 
878
-       
 
879
-       public DataPoint transform(DataPoint toTransform) {
 
880
-               return coordinates.dataToPixel(toTransform);
 
881
-       }
 
882
-
 
883
-       public boolean isChanged() {
 
884
-               return changed;
 
885
-       }
 
886
-       
 
887
-       public void setChanged(boolean val) {
 
888
-               changed = val;
 
889
-       }
 
890
-
 
891
-       public String getTitle() {
 
892
-               return title;
 
893
-       }
 
894
-
 
895
-       public int getHeight() {
 
896
-               return height;
 
897
-       }
 
898
-       
 
899
-       public void setHeight(int value) {
 
900
-               if (height == value)
 
901
-                       return;
 
902
-               height = value;
 
903
-               double newScale = (double) height/maxY;
 
904
-               coordinates.setYScale(newScale);
 
905
-       }
 
906
-
 
907
-
 
908
-       public void setYAxisCoordinate(int value) {
 
909
-               coordinates.setYAxisCoordinate(value);
 
910
-               startPoint.setY(value);
 
911
-       }
 
912
-       
 
913
-       public void setXAxisCoordinate(int value) {
 
914
-               coordinates.setXAxisCoordinate(value);
 
915
-               startPoint.setX(value);
 
916
-       }
 
917
-
 
918
-
 
919
-       public CoordinateSystem getCoordinates() {
 
920
-               return coordinates;
 
921
-       }
 
922
-
 
923
-       /**
 
924
-        * The main draw function -- implement this method to change
 
925
-        * the way things are graphed
 
926
-        * 
 
927
-        * @param gc
 
928
-        * @param graphCanvas
 
929
-        */
 
930
-       public abstract void drawOn(GC gc, Composite graphCanvas);
 
931
-
 
932
-       
 
933
-       protected void drawLine(GC gc, DataPoint p1, DataPoint p2) {
 
934
-               gc.drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
 
935
-       }
 
936
-       
 
937
-       /**
 
938
-        * 
 
939
-        * @return
 
940
-        *                        Number of data buffers in this model
 
941
-        */
 
942
-       public int getBufferCount() {
 
943
-               return data.size();
 
944
-       }
 
945
-       
 
946
-       /**
 
947
-        * Draws the x-axis and sets up the graph's title.
 
948
-        * Also draws graduations for the x-axis
 
949
-        * 
 
950
-        * @param gc
 
951
-        * @param width
 
952
-        */
 
953
-       protected void drawAxis(GC gc, int width) {
 
954
-               gc.setLineWidth(2);
 
955
-               gc.drawLine(getXOffset(), getYOffset(), width, getYOffset());
 
956
-               int xSeg = getXOffset();
 
957
-               int increment = width/BUFFER_SIZE;
 
958
-               while (xSeg < width) {
 
959
-                       gc.drawLine(xSeg, getYOffset(), xSeg, getYOffset() - getHeight());
 
960
-                       xSeg += increment;
 
961
-               }
 
962
-               gc.setForeground(new Color(Display.getCurrent(), 10, 10, 10));
 
963
-               gc.drawText(getTitle(), getXOffset(), getYOffset() + 5, true);
 
964
-//             gc.drawText(this.getCoordinates().getAxis().getTopLabel(), this.getXOffset(), this.getYOffset() - this.getHeight(), true);
 
965
-       }
 
966
-       
 
967
-       protected void drawFillPolygons(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
 
968
-               DataPoint pp = this.getStartPoint();
 
969
-               int xSeg = this.getXOffset();
 
970
-               int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
 
971
-               
 
972
-               gc.setLineWidth(0);
 
973
-               while (nextPointBuffer.hasNext()) {
 
974
-                       gc.setAlpha(170);
 
975
-                       DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
 
976
-                       //Use old point, new point, and the corresponding intersections with the x-axis to fill
 
977
-                       gc.fillPolygon(new int[] {pp.getX(), pp.getY(), nextPoint.getX(), nextPoint.getY(), nextPoint.getX(), getStartPoint().getY(), pp.getX(), getStartPoint().getY()});
 
978
-                       xSeg += increment;
 
979
-                       pp = nextPoint;
 
980
-       }
 
981
-       }
 
982
-       
 
983
-       protected void drawLines(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
 
984
-               DataPoint pp = this.getStartPoint();
 
985
-               int xSeg = this.getXOffset();
 
986
-               int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
 
987
-               
 
988
-               while (nextPointBuffer.hasNext()) {
 
989
-                       DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
 
990
-                       xSeg += increment;
 
991
-                       drawLine(gc, pp, nextPoint);
 
992
-                       pp = nextPoint;
 
993
-       }
 
994
-       }
 
995
-
 
996
-}
 
997
+package org.eclipse.linuxtools.internal.threadprofiler.graphs;
 
998
+
 
999
+import java.util.ArrayList;
 
1000
+import java.util.Iterator;
 
1001
+
 
1002
+import org.eclipse.linuxtools.internal.threadprofiler.CircularPointBuffer;
 
1003
+import org.eclipse.linuxtools.internal.threadprofiler.CoordinateSystem;
 
1004
+import org.eclipse.linuxtools.internal.threadprofiler.DataPoint;
 
1005
+import org.eclipse.linuxtools.internal.threadprofiler.GraphAxis;
 
1006
+import org.eclipse.swt.graphics.Color;
 
1007
+import org.eclipse.swt.graphics.GC;
 
1008
+import org.eclipse.swt.widgets.Canvas;
 
1009
+import org.eclipse.swt.widgets.Composite;
 
1010
+import org.eclipse.swt.widgets.Display;
 
1011
+
 
1012
+public abstract class GraphModel {
 
1013
+       
 
1014
+       //Constant Y scale
 
1015
+       public static final int CONSTANT_Y = 0;
 
1016
+       //Change Y scale as the maximum y point increases
 
1017
+       public static final int FLEXIBLE_Y = 1;
 
1018
+       /** Maximum buffer size. This affects the number of data points*/
 
1019
+       public static final int BUFFER_SIZE = 100;
 
1020
+       //Default height
 
1021
+       public static final int DEFAULT_HEIGHT = 100;
 
1022
+       
 
1023
+       /** Number of spaces between graduations on the axis */
 
1024
+       private static final int GRADUATION_SEPARATION = 5;
 
1025
+       
 
1026
+       private final CoordinateSystem coordinates;
 
1027
+       private final DataPoint startPoint;
 
1028
+       private final int graphType;
 
1029
+       private final String title;
 
1030
+       private final String units;
 
1031
+       private boolean changed;
 
1032
+       protected final ArrayList<CircularPointBuffer> data;
 
1033
+       
 
1034
+       private int height;
 
1035
+       
 
1036
+       private int maxY;
 
1037
+       //Height in pixels
 
1038
+       
 
1039
+       public GraphModel(String name, int x, int y, int type, String units) {
 
1040
+               graphType = type;
 
1041
+               changed = false;
 
1042
+               data = new ArrayList<CircularPointBuffer>();
 
1043
+               title = name;
 
1044
+               this.units = units;
 
1045
+               height = DEFAULT_HEIGHT;
 
1046
+               maxY = 100;
 
1047
+               coordinates = new CoordinateSystem(x, y);
 
1048
+               coordinates.setYScale(0.2);
 
1049
+               coordinates.getAxis().setTopLabel(DEFAULT_HEIGHT + units);
 
1050
+               
 
1051
+               startPoint = new DataPoint(coordinates.getXOffset(), coordinates.getYOffset(), 1);
 
1052
+       }
 
1053
+       
 
1054
+       public void setMaxY(int max) {
 
1055
+               maxY = max;
 
1056
+       }
 
1057
+       
 
1058
+       public int getXOffset() {
 
1059
+               return (int) coordinates.getAxisToPixel().entries[0][2];
 
1060
+       }
 
1061
+       
 
1062
+       public int getYOffset() {
 
1063
+               return (int) coordinates.getAxisToPixel().entries[1][2];
 
1064
+       }
 
1065
+
 
1066
+
 
1067
+       /**
 
1068
+        * 
 
1069
+        * @return
 
1070
+        *                        First available point buffer if any is available, else null
 
1071
+        */
 
1072
+       public Iterator<DataPoint> getPointBuffer() {
 
1073
+               if (data.size() > 1)
 
1074
+                       return getPointBuffer(0);
 
1075
+               return null;
 
1076
+       }
 
1077
+       
 
1078
+       public Iterator<DataPoint> getPointBuffer(int index) {
 
1079
+               return data.get(index).getIterator();
 
1080
+       }
 
1081
+
 
1082
+       public GraphAxis getAxis() {
 
1083
+               return coordinates.getAxis();
 
1084
+       }
 
1085
+       
 
1086
+       public DataPoint getStartPoint() {
 
1087
+               return startPoint;
 
1088
+       }
 
1089
+
 
1090
+       public void add(DataPoint point, int subIndex) {
 
1091
+               if (subIndex >= data.size()) {
 
1092
+                       data.add(new CircularPointBuffer(BUFFER_SIZE));
 
1093
+               }
 
1094
+               if (graphType == FLEXIBLE_Y) {
 
1095
+                       if (point.getY() > maxY ) {
 
1096
+                               maxY = point.getY();
 
1097
+                               coordinates.getAxis().setTopLabel(maxY + " " + units);
 
1098
+                               if ( point.getY() > height) {
 
1099
+                                       double newScale = (double) height/maxY;
 
1100
+                                       coordinates.setYScale(newScale);
 
1101
+                               }
 
1102
+                       }
 
1103
+               }
 
1104
+               data.get(subIndex).add(point);
 
1105
+               setChanged(true);
 
1106
+       }
 
1107
+       
 
1108
+       public DataPoint transform(DataPoint toTransform) {
 
1109
+               return coordinates.dataToPixel(toTransform);
 
1110
+       }
 
1111
+
 
1112
+       public boolean isChanged() {
 
1113
+               return changed;
 
1114
+       }
 
1115
+       
 
1116
+       public void setChanged(boolean val) {
 
1117
+               changed = val;
 
1118
+       }
 
1119
+
 
1120
+       public String getTitle() {
 
1121
+               return title;
 
1122
+       }
 
1123
+
 
1124
+       public int getHeight() {
 
1125
+               return height;
 
1126
+       }
 
1127
+       
 
1128
+       public void setHeight(int value) {
 
1129
+               if (height == value)
 
1130
+                       return;
 
1131
+               height = value;
 
1132
+               double newScale = (double) height/maxY;
 
1133
+               coordinates.setYScale(newScale);
 
1134
+       }
 
1135
+
 
1136
+
 
1137
+       public void setYAxisCoordinate(int value) {
 
1138
+               coordinates.setYAxisCoordinate(value);
 
1139
+               startPoint.setY(value);
 
1140
+       }
 
1141
+       
 
1142
+       public void setXAxisCoordinate(int value) {
 
1143
+               coordinates.setXAxisCoordinate(value);
 
1144
+               startPoint.setX(value);
 
1145
+       }
 
1146
+
 
1147
+
 
1148
+       public CoordinateSystem getCoordinates() {
 
1149
+               return coordinates;
 
1150
+       }
 
1151
+
 
1152
+       /**
 
1153
+        * The main draw function -- implement this method to change
 
1154
+        * the way things are graphed
 
1155
+        * 
 
1156
+        * @param gc
 
1157
+        * @param graphCanvas
 
1158
+        */
 
1159
+       public abstract void drawOn(GC gc, Composite graphCanvas);
 
1160
+
 
1161
+       
 
1162
+       protected void drawLine(GC gc, DataPoint p1, DataPoint p2) {
 
1163
+               gc.drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
 
1164
+       }
 
1165
+       
 
1166
+       /**
 
1167
+        * 
 
1168
+        * @return
 
1169
+        *                        Number of data buffers in this model
 
1170
+        */
 
1171
+       public int getBufferCount() {
 
1172
+               return data.size();
 
1173
+       }
 
1174
+       
 
1175
+       /**
 
1176
+        * Draws the x-axis and sets up the graph's title.
 
1177
+        * Also draws graduations for the x-axis
 
1178
+        * 
 
1179
+        * @param gc
 
1180
+        * @param width
 
1181
+        */
 
1182
+       protected void drawAxis(GC gc, int width) {
 
1183
+               gc.setLineWidth(2);
 
1184
+               gc.drawLine(getXOffset(), getYOffset(), width, getYOffset());
 
1185
+               int xSeg = getXOffset();
 
1186
+               int increment = width/BUFFER_SIZE;
 
1187
+               while (xSeg < width) {
 
1188
+                       gc.drawLine(xSeg, getYOffset(), xSeg, getYOffset() - getHeight());
 
1189
+                       xSeg += GRADUATION_SEPARATION * increment;
 
1190
+               }
 
1191
+               gc.setForeground(new Color(Display.getCurrent(), 10, 10, 10));
 
1192
+               gc.drawText(getTitle(), getXOffset(), getYOffset() + 5, true);
 
1193
+//             gc.drawText(this.getCoordinates().getAxis().getTopLabel(), this.getXOffset(), this.getYOffset() - this.getHeight(), true);
 
1194
+       }
 
1195
+       
 
1196
+       protected void drawFillPolygons(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
 
1197
+               DataPoint pp = this.getStartPoint();
 
1198
+               int xSeg = this.getXOffset();
 
1199
+               int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
 
1200
+               
 
1201
+               gc.setLineWidth(0);
 
1202
+               while (nextPointBuffer.hasNext()) {
 
1203
+                       gc.setAlpha(170);
 
1204
+                       DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
 
1205
+                       //Use old point, new point, and the corresponding intersections with the x-axis to fill
 
1206
+                       gc.fillPolygon(new int[] {pp.getX(), pp.getY(), nextPoint.getX(), nextPoint.getY(), nextPoint.getX(), getStartPoint().getY(), pp.getX(), getStartPoint().getY()});
 
1207
+                       xSeg += increment;
 
1208
+                       pp = nextPoint;
 
1209
+       }
 
1210
+       }
 
1211
+       
 
1212
+       protected void drawLines(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
 
1213
+               DataPoint pp = this.getStartPoint();
 
1214
+               int xSeg = this.getXOffset();
 
1215
+               int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
 
1216
+               
 
1217
+               while (nextPointBuffer.hasNext()) {
 
1218
+                       DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
 
1219
+                       xSeg += increment;
 
1220
+                       drawLine(gc, pp, nextPoint);
 
1221
+                       pp = nextPoint;
 
1222
+       }
 
1223
+       }
 
1224
+
 
1225
+}
 
1226
diff --git a/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java b/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java
 
1227
index ee3565e..5d958b2 100644
 
1228
--- a/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java
 
1229
+++ b/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java
 
1230
@@ -80,6 +80,7 @@ public class MultiGraph extends GraphModel {
 
1231
                                        gc.setBackground(oldBg);
 
1232
                                }
 
1233
                                
 
1234
+                               gc.setLineWidth(0);
 
1235
                                gc.drawText(getPointBuffer(i).toString(), xPos, yPos);
 
1236
                                prev = getPointBuffer(i).toString();
 
1237
                                xPos = xPos + separation(prev);