diff --git a/ThreadProfile.stp b/ThreadProfile.stp
index 4d7fe50..daab497 100644
--- a/ThreadProfile.stp
+++ b/ThreadProfile.stp
@@ -39,31 +39,30 @@ probe process(@1).function("*").call {
setup();
pid = pid();
}
+ if (! threadcounters[tid()] ) {
+ threadstacks[tid()] = probefunc();
+ }
threadcounters[tid()]++;
- threadstacks[tid(),threadcounters[tid()]] = probefunc();
}
probe process(@1).function("*").return {
- delete(threadstacks[tid(),threadcounters[tid()]]);
- if (threadcounters[tid()] == 1) {
+ threadcounters[tid()]--;
+ if (! threadcounters[tid()]) {
delete(threadcounters[tid()]);
- delete(threadstacks[tid(),0]);
+ delete(threadstacks[tid()]);
}
- else
- threadcounters[tid()]--;
}
# ------------------------------------------------------------------------
# general gnuplot graphical report generation
-probe timer.ms(500) {
+probe timer.ms(100) {
printf("--\n");
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);
foreach (tid in threadcounters) {
- printf("%d:%s\n", tid, threadstacks[tid, 1]);
+ printf("%d:%s\n", tid, threadstacks[tid]);
}
- printf("--\n");
reads = 0;
writes = 0;
counter++;
diff --git a/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class b/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class
index a620579..9f26a69 100644
Binary files a/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class and b/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class differ
diff --git a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class
index 2876d9d..a35972d 100644
Binary files a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class and b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class differ
diff --git a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class
index 2015b3b..924310a 100644
Binary files a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class and b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class differ
diff --git a/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java b/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java
index 8deb632..cac1b2d 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java
@@ -1,10 +1,22 @@
package org.eclipse.linuxtools.threadprofiler;
public class DataPoint {
+
+ /** Indicates that this is a raw data point */
public static final int DATA_POINT = 0;
+
+ /** Indicates that this is a point relative to the axis */
public static final int AXIS_POINT = 1;
+
+ /** Indicates that this is an absolute pixel point */
public static final int PIXEL_POINT = 2;
+ /** Inactive, do not draw this point */
+ public static final int INACTIVE = 0;
+
+ /** Active, draw this point */
+ public static final int ACTIVE = 1;
+
private int[] values;
private int type;
diff --git a/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java b/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java
index 9cc6ec7..f6c5dec 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java
@@ -1,21 +1,74 @@
package org.eclipse.linuxtools.threadprofiler;
-public class ThreadGraph {
-
- private final String name;
- private final int tid;
+import java.util.Iterator;
+
+import org.eclipse.linuxtools.threadprofiler.graphs.GraphModel;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Composite;
+
+public class ThreadGraph extends GraphModel{
+
+ private int tid;
+ private DataPoint dp;
+ private boolean empty;
- public ThreadGraph(int tid, String name) {
- this.name = name;
+ public ThreadGraph(String name, int x, int y, int type, String units, int tid) {
+ super(name, x, y, type, units);
this.tid = tid;
+ empty = false;
}
public int getTid() {
return tid;
}
- public String getName() {
- return name;
+ private void setEmpty(boolean val) {
+ empty = val;
+ }
+
+ /**
+ * Returns true if this graph has data points and they are all empty
+ *
+ * @return
+ */
+ public boolean isEmpty() {
+ return empty;
+ }
+
+ @Override
+ public void drawOn(GC gc, Composite graphCanvas) {
+ int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
+
+ //Each thread should only have one buffer
+ Iterator<DataPoint> buffer = data.get(0).getIterator();
+ int xPos = this.getXOffset();
+ boolean em = true;
+ if (!buffer.hasNext())
+ em = false;
+ while (buffer.hasNext()) {
+ DataPoint p = buffer.next();
+ if (p.getType() == DataPoint.ACTIVE) {
+ em = false;
+ gc.drawLine(xPos, getYOffset(), xPos + increment, getYOffset());
+ }
+ xPos += increment;
+ }
+
+ setEmpty(em);
+ }
+
+ public void prep(DataPoint dataPoint, int i) {
+ dp = dataPoint;
+ }
+
+ public void tick() {
+ //TODO: This method if updating requires passing around a bulky datapoint variable
+ if (dp != null)
+ add(dp, 0);
+ else {
+ add(new DataPoint(0, 0, DataPoint.INACTIVE), 0);
+ }
+ dp = null;
}
}
diff --git a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java
index d9dac71..6fcd306 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java
@@ -33,21 +33,20 @@ public class ThreadProfilerParser extends SystemTapParser {
boolean changed = false;
try {
while ((line = buff.readLine()) != null) {
- System.out.println("Parsed: " + line);
+// System.out.println("Parsed: " + line);
changed = true;
- if (line.equals("--"))
+ if (line.equals("--")) {
+ ((ThreadProfilerView) view).closeThreads();
continue;
+ }
if (line.contains(", ")) {
String[] blargh = line.split(", ");
- ((ThreadProfilerView) view).addNextCPUPoint(counter, blargh);
- ((ThreadProfilerView) view).addNextMemoryPoint(counter++, blargh);
- ((ThreadProfilerView) view).addNextDiskPoint(counter++, blargh);
+ ((ThreadProfilerView) view).addDataPoints(counter++, blargh);
} else {
String[] data = line.split(":");
int tid = Integer.parseInt(data[0]);
((ThreadProfilerView) view).addThread(tid, data[1]);
}
-
}
if (changed) view.update();
} catch (NumberFormatException e) {
diff --git a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java
index 2dbaaf7..40b7460 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java
@@ -1,265 +1,297 @@
-package org.eclipse.linuxtools.threadprofiler;
-
-import java.util.ArrayList;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.linuxtools.callgraph.core.SystemTapView;
-import org.eclipse.linuxtools.threadprofiler.graphs.GraphModel;
-import org.eclipse.linuxtools.threadprofiler.graphs.MultiGraph;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-
-public class ThreadProfilerView extends SystemTapView {
- private static final int CPU_BUFFER = 0;
- private static final int MEM_BUFFER = 1;
- private static final int DISK_BUFFER = 2;
- private ArrayList<GraphModel> graphs;
- private ArrayList<ThreadGraph> threads;
-
- private Composite graphCanvas;
- private Canvas threadCanvas;
- private final long REFRESH_TIME_MS = 700;
- private final static int GRAPH_SEPARATION = 40;
- private long time;
- private int segments;
-
- /*
- * We have two frames of reference:
- *
- * 1. Pixel frame (absolute frame)
- * 2. Axis frame (relative frame)
- *
- * The transformation from 1 to 2 is a coordinate shift and scale
- *
- */
-
-
- @Override
- protected boolean createOpenAction() {
- return false;
- }
-
- @Override
- protected boolean createOpenDefaultAction() {
- return false;
- }
-
- @Override
- public IStatus initializeView(Display targetDisplay,
- IProgressMonitor monitor) {
- if (graphs == null)
- graphs = new ArrayList<GraphModel>();
- if (threads == null)
- threads = new ArrayList<ThreadGraph>();
- graphs.clear();
- threads.clear();
- segments = 0;
-
- //Create dataSet for CPU
- createNewDataSet("CPU", GraphModel.CONSTANT_Y, "%");
- ((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
- ((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "IO Block");
-
- //Create dataSet for memory
- createNewDataSet("Memory", GraphModel.FLEXIBLE_Y, "bytes");
- ((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
- ((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Data");
-
- //Create dataSet for disk usage
- createNewDataSet("Disk", GraphModel.FLEXIBLE_Y, "bytes");
- ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
- ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Read");
- ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Write");
- ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_FILL);
- ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
- ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
-
- time = System.currentTimeMillis();
-
- graphCanvas.addMouseListener(new MouseListener() {
-
- @Override
- public void mouseDoubleClick(MouseEvent e) {
- updateMethod();
- }
-
- @Override
- public void mouseDown(MouseEvent e) {
- System.out.println("LOCATION: " + e.x + "," + e.y);
- }
-
- @Override
- public void mouseUp(MouseEvent e) {
- // TODO Auto-generated method stub
-
- }
-
- });
-
- graphCanvas.addPaintListener(new PaintListener() {
- public void paintControl(PaintEvent e) {
-// if (!graphs.get(0).isChanged())
-// return;
-
-
- for (int i = 0; i < graphs.size(); i ++) {
- GraphModel graph = graphs.get(i);
- GC gc = new GC(graphCanvas);
- gc.setLineWidth(2);
- graph.setHeight((int) (graphCanvas.getSize().y/(2.5*graphs.size())));
- graph.setYAxisCoordinate((graph.getHeight() + GRAPH_SEPARATION) *(i + 1));
- graph.drawOn(gc, graphCanvas);
- gc.dispose();
- }
- }
- });
-
-
- threadCanvas.addPaintListener(new PaintListener() {
-
- @Override
- public void paintControl(PaintEvent e) {
- if (threads == null)
- return;
- int yOffset = 40;
-
- GC gc = new GC(threadCanvas);
- gc.setLineWidth(4);
- gc.setForeground(new Color(Display.getCurrent(), 0, 0, 200));
- int increment = (graphCanvas.getSize().x - 40)/GraphModel.BUFFER_SIZE;
-
- for (ThreadGraph tg : threads) {
- gc.drawText(tg.getName(), 40, yOffset);
- gc.drawLine(40, yOffset, 40 + increment*segments, yOffset);
- }
- }
-
- });
-
- return Status.OK_STATUS;
- }
-
- private void createNewDataSet(String name, int type, String units) {
- GraphModel graph = new MultiGraph(name, 50, (GraphModel.DEFAULT_HEIGHT + GRAPH_SEPARATION) *(graphs.size() + 1), type, units);
- graphs.add(graph);
- }
-
- @Override
- public void setViewID() {
- viewID = "org.eclipse.linuxtools.threadprofiler.ThreadProfilerView";
- }
-
- @Override
- public void updateMethod() {
- if (System.currentTimeMillis() - time < REFRESH_TIME_MS)
- return;
- time = System.currentTimeMillis();
- graphCanvas.redraw();
- }
-
- @Override
- public void createPartControl(Composite parent) {
- GridLayout gl = new GridLayout(1, true);
- parent.setLayout(gl);
- Color white = new Color(Display.getCurrent(), 255, 255, 255);
-
- graphCanvas = new Composite(parent, SWT.BORDER);
- graphCanvas.setBackground(white);
- GridData gd = new GridData(GridData.FILL_BOTH);
- gd.grabExcessHorizontalSpace = true;
- graphCanvas.setLayoutData(gd);
-
- threadCanvas = new Canvas(parent, SWT.BORDER);
- threadCanvas.setBackground(white);
- gd = new GridData(GridData.FILL_BOTH);
- gd.grabExcessHorizontalSpace = true;
- threadCanvas.setLayoutData(gd);
- }
-
- @Override
- public void setFocus() {
- //Do nothing
- }
-
-
- public void addNextCPUPoint(int counter, String[] blargh) {
- if (blargh.length < 2)
- return;
- this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[1]), 1), CPU_BUFFER, 0);
-
- if (blargh.length < 3)
- return;
- this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[2]), 1), CPU_BUFFER, 1);
- }
-
- public void addNextMemoryPoint(int counter, String[] blargh) {
- if (blargh.length < 4)
- return;
- this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[3]), 1), MEM_BUFFER, 0);
- if (blargh.length < 5)
- return;
- this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[4]), 1), MEM_BUFFER, 1);
- }
-
- public void addNextDiskPoint(int counter, String[] blargh) {
- if (blargh.length < 6)
- return;
- addPoint(new DataPoint(counter, Integer.parseInt(blargh[5]), 1), DISK_BUFFER, 0);
-
- if (blargh.length < 7)
- return;
- addPoint(new DataPoint(counter, Integer.parseInt(blargh[6]), 1), DISK_BUFFER, 1);
-
- if (blargh.length < 8)
- return;
- addPoint(new DataPoint(counter, Integer.parseInt(blargh[7]), 1), DISK_BUFFER, 2);
- }
-
- private void addPoint(DataPoint point, int dataSet, int subIndex) {
- if (graphs.size() < 1)
- return;
- if (segments < GraphModel.BUFFER_SIZE)
- segments++;
- graphs.get(dataSet).add(point, subIndex);
- }
-
- public void addThread(int tid, String line) {
- if (!threadExists(tid)) {
- ThreadGraph tg = new ThreadGraph(tid, line);
- threads.add(tg);
- }
- }
-
- /**
- * Returns true if a thread with the given tid exists
- *
- * @param tid
- * @return
- */
- private boolean threadExists(int tid) {
- boolean exists = false;
- for (ThreadGraph g : threads) {
- if (g.getTid() == tid) {
- exists = true;
- break;
- }
- }
- return exists;
- }
-
-
+package org.eclipse.linuxtools.threadprofiler;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.callgraph.core.SystemTapView;
+import org.eclipse.linuxtools.threadprofiler.graphs.GraphModel;
+import org.eclipse.linuxtools.threadprofiler.graphs.MultiGraph;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+public class ThreadProfilerView extends SystemTapView {
+ private static final int CPU_BUFFER = 0;
+ private static final int MEM_BUFFER = 1;
+ private static final int DISK_BUFFER = 2;
+
+ private static final int START_X_POS = 50;
+ private ArrayList<GraphModel> graphs;
+ private ArrayList<ThreadGraph> threads;
+
+ private Composite graphCanvas;
+ private Canvas threadCanvas;
+ private final static int GRAPH_SEPARATION = 40;
+ private int segments;
+
+ /*
+ * We have two frames of reference:
+ *
+ * 1. Pixel frame (absolute frame)
+ * 2. Axis frame (relative frame)
+ *
+ * The transformation from 1 to 2 is a coordinate shift and scale
+ *
+ */
+
+
+ @Override
+ protected boolean createOpenAction() {
+ return false;
+ }
+
+ @Override
+ protected boolean createOpenDefaultAction() {
+ return false;
+ }
+
+ @Override
+ public IStatus initializeView(Display targetDisplay,
+ IProgressMonitor monitor) {
+ if (graphs == null)
+ graphs = new ArrayList<GraphModel>();
+ if (threads == null)
+ threads = new ArrayList<ThreadGraph>();
+ graphs.clear();
+ threads.clear();
+ segments = 0;
+
+ //Create dataSet for CPU
+ createNewDataSet("CPU", GraphModel.CONSTANT_Y, "%");
+ ((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
+ ((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "IO Block");
+
+ //Create dataSet for memory
+ createNewDataSet("Memory", GraphModel.FLEXIBLE_Y, "bytes");
+ ((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
+ ((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Data");
+
+ //Create dataSet for disk usage
+ createNewDataSet("Disk", GraphModel.FLEXIBLE_Y, "bytes");
+ ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
+ ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Read");
+ ((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Write");
+ ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_FILL);
+ ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
+ ((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
+
+ graphCanvas.addMouseListener(new MouseListener() {
+
+ @Override
+ public void mouseDoubleClick(MouseEvent e) {
+ updateMethod();
+ }
+
+ @Override
+ public void mouseDown(MouseEvent e) {
+ System.out.println("LOCATION: " + e.x + "," + e.y);
+ }
+
+ @Override
+ public void mouseUp(MouseEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ });
+
+ graphCanvas.addPaintListener(new PaintListener() {
+ public void paintControl(PaintEvent e) {
+ //TODO: If the script is running and the graph is not changed,
+ //there is no need to update yet.
+ for (int i = 0; i < graphs.size(); i ++) {
+ GraphModel graph = graphs.get(i);
+ GC gc = new GC(graphCanvas);
+ gc.setLineWidth(2);
+ graph.setHeight((int) (graphCanvas.getSize().y/(2.5*graphs.size())));
+ graph.setYAxisCoordinate((graph.getHeight() + GRAPH_SEPARATION) *(i + 1));
+ graph.drawOn(gc, graphCanvas);
+ gc.dispose();
+ }
+ }
+ });
+
+
+ threadCanvas.addPaintListener(new PaintListener() {
+
+
+ @Override
+ public void paintControl(PaintEvent e) {
+ if (threads == null)
+ return;
+ int yOffset = GRAPH_SEPARATION;
+
+ GC gc = new GC(threadCanvas);
+ Color fg = new Color(Display.getCurrent(), 0, 0, 200);
+ gc.setForeground(fg);
+
+ int counter = 0;
+ ArrayList<ThreadGraph> toRemove = new ArrayList<ThreadGraph>();
+ for (ThreadGraph tg : threads) {
+ counter++;
+ tg.setYAxisCoordinate(counter*yOffset);
+ gc.setLineWidth(2);
+ tg.drawOn(gc, graphCanvas);
+ gc.setLineWidth(0);
+ gc.drawText(tg.getTitle(), START_X_POS, counter*yOffset, true);
+ if (tg.isEmpty())
+ toRemove.add(tg);
+ }
+ //TODO: O(N^2) operation
+ threads.removeAll(toRemove);
+ fg.dispose();
+ gc.dispose();
+ }
+ });
+
+ return Status.OK_STATUS;
+ }
+
+ private void createNewDataSet(String name, int type, String units) {
+ GraphModel graph = new MultiGraph(name, START_X_POS, (GraphModel.DEFAULT_HEIGHT + GRAPH_SEPARATION) *(graphs.size() + 1), type, units);
+ graphs.add(graph);
+ }
+
+ @Override
+ public void setViewID() {
+ viewID = "org.eclipse.linuxtools.threadprofiler.ThreadProfilerView";
+ }
+
+ @Override
+ public void updateMethod() {
+ graphCanvas.redraw();
+ threadCanvas.redraw();
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ GridLayout gl = new GridLayout(1, true);
+ parent.setLayout(gl);
+ Color white = new Color(Display.getCurrent(), 255, 255, 255);
+
+ ScrolledComposite graphComp =new ScrolledComposite(parent, SWT.BORDER | SWT.V_SCROLL);
+ graphComp.setLayout (new GridLayout(1, true));
+ graphComp.setBackground(white);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ gd.grabExcessHorizontalSpace = true;
+ graphComp.setLayoutData(gd);
+
+ graphCanvas = new Canvas(graphComp, SWT.BORDER | SWT.V_SCROLL);
+ graphCanvas.setBackground(white);
+ gd = new GridData(GridData.FILL_BOTH);
+ gd.grabExcessHorizontalSpace = true;
+ graphCanvas.setLayoutData(gd);
+
+ ScrolledComposite threadComp =new ScrolledComposite(parent, SWT.BORDER | SWT.V_SCROLL);
+ threadComp.setLayout (new GridLayout(1, true));
+ threadComp.setBackground(white);
+ gd = new GridData(GridData.FILL_BOTH);
+ gd.grabExcessHorizontalSpace = true;
+ threadComp.setLayoutData(gd);
+
+ threadCanvas = new Canvas(graphComp, SWT.BORDER | SWT.V_SCROLL);
+ threadCanvas.setBackground(white);
+ gd = new GridData(GridData.FILL_BOTH);
+ gd.grabExcessHorizontalSpace = true;
+ threadCanvas.setLayoutData(gd);
+ }
+
+ @Override
+ public void setFocus() {
+ //Do nothing
+ }
+
+
+
+ public void addDataPoints(int counter, String[] blargh) {
+ if (segments < GraphModel.BUFFER_SIZE)
+ segments++;
+ if (blargh.length < 2)
+ return;
+ this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[1]), 1), CPU_BUFFER, 0);
+
+ if (blargh.length < 3)
+ return;
+ this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[2]), 1), CPU_BUFFER, 1);
+
+ if (blargh.length < 4)
+ return;
+ this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[3]), 1), MEM_BUFFER, 0);
+
+ if (blargh.length < 5)
+ return;
+ this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[4]), 1), MEM_BUFFER, 1);
+
+ if (blargh.length < 6)
+ return;
+ addPoint(new DataPoint(counter, Integer.parseInt(blargh[5]), 1), DISK_BUFFER, 0);
+
+ if (blargh.length < 7)
+ return;
+ addPoint(new DataPoint(counter, Integer.parseInt(blargh[6]), 1), DISK_BUFFER, 1);
+
+ if (blargh.length < 8)
+ return;
+ addPoint(new DataPoint(counter, Integer.parseInt(blargh[7]), 1), DISK_BUFFER, 2);
+ }
+
+
+ private void addPoint(DataPoint point, int dataSet, int subIndex) {
+ if (graphs.size() < 1)
+ return;
+ graphs.get(dataSet).add(point, subIndex);
+ }
+
+ public void addThread(int tid, String line) {
+ int i = threadExists(tid);
+ if (i < 0) {
+ ThreadGraph tg = new ThreadGraph(line, START_X_POS, GRAPH_SEPARATION, 0, "", tid);
+ for (int j = 0; j < segments; j++) {
+ //Fill with empty segments
+ tg.add(new DataPoint(0, 0, DataPoint.INACTIVE), 0);
+ }
+ threads.add(tg);
+ i = threads.size() - 1;
+ }
+ threads.get(i).prep(new DataPoint(0, 0, DataPoint.ACTIVE), 0);
+ }
+
+
+ public void closeThreads() {
+ // TODO Auto-generated method stub
+ for (ThreadGraph tg : threads) {
+ tg.tick();
+ }
+ }
+
+ /**
+ * Returns true if a thread with the given tid exists
+ *
+ * @param tid
+ * @return
+ */
+ private int threadExists(int tid) {
+ for (int i = 0; i < threads.size(); i++) {
+ if (threads.get(i).getTid() == tid) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+
+
}
\ No newline at end of file
diff --git a/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java b/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java
index 5bf0531..1b07e18 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java
@@ -1,226 +1,229 @@
-package org.eclipse.linuxtools.threadprofiler.graphs;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.eclipse.linuxtools.threadprofiler.CircularPointBuffer;
-import org.eclipse.linuxtools.threadprofiler.CoordinateSystem;
-import org.eclipse.linuxtools.threadprofiler.DataPoint;
-import org.eclipse.linuxtools.threadprofiler.GraphAxis;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-
-public abstract class GraphModel {
-
- //Constant Y scale
- public static final int CONSTANT_Y = 0;
- //Change Y scale as the maximum y point increases
- public static final int FLEXIBLE_Y = 1;
- //Maximum buffer size
- public static final int BUFFER_SIZE = 30;
- //Default height
- public static final int DEFAULT_HEIGHT = 100;
-
- private final CoordinateSystem coordinates;
- private final DataPoint startPoint;
- private final int graphType;
- private final String title;
- private final String units;
- private boolean changed;
- protected final ArrayList<CircularPointBuffer> data;
-
- private int height;
-
- private int maxY;
- //Height in pixels
-
- public GraphModel(String name, int x, int y, int type, String units) {
- graphType = type;
- changed = false;
- data = new ArrayList<CircularPointBuffer>();
- title = name;
- this.units = units;
- height = DEFAULT_HEIGHT;
- maxY = 100;
- coordinates = new CoordinateSystem(x, y);
- coordinates.setYScale(0.2);
- coordinates.getAxis().setTopLabel(DEFAULT_HEIGHT + units);
-
- startPoint = new DataPoint(coordinates.getXOffset(), coordinates.getYOffset(), 1);
- }
-
- public void setMaxY(int max) {
- maxY = max;
- }
-
- public int getXOffset() {
- return (int) coordinates.getAxisToPixel().entries[0][2];
- }
-
- public int getYOffset() {
- return (int) coordinates.getAxisToPixel().entries[1][2];
- }
-
-
- /**
- *
- * @return
- * First available point buffer if any is available, else null
- */
- public Iterator<DataPoint> getPointBuffer() {
- if (data.size() > 1)
- return getPointBuffer(0);
- return null;
- }
-
- public Iterator<DataPoint> getPointBuffer(int index) {
- return data.get(index).getIterator();
- }
-
- public GraphAxis getAxis() {
- return coordinates.getAxis();
- }
-
- public DataPoint getStartPoint() {
- return startPoint;
- }
-
- public void add(DataPoint point, int subIndex) {
- if (subIndex >= data.size()) {
- data.add(new CircularPointBuffer(BUFFER_SIZE));
- }
- if (graphType == FLEXIBLE_Y) {
- if (point.getY() > maxY ) {
- maxY = point.getY();
- coordinates.getAxis().setTopLabel(maxY + " " + units);
- if ( point.getY() > height) {
- double newScale = (double) height/maxY;
- coordinates.setYScale(newScale);
- }
- }
- }
- data.get(subIndex).add(point);
- setChanged(true);
- }
-
- public DataPoint transform(DataPoint toTransform) {
- return coordinates.dataToPixel(toTransform);
- }
-
- public boolean isChanged() {
- return changed;
- }
-
- public void setChanged(boolean val) {
- changed = val;
- }
-
- public String getTitle() {
- return title;
- }
-
- public int getHeight() {
- return height;
- }
-
- public void setHeight(int value) {
- if (height == value)
- return;
- height = value;
- double newScale = (double) height/maxY;
- coordinates.setYScale(newScale);
- }
-
-
- public void setYAxisCoordinate(int value) {
- coordinates.setYAxisCoordinate(value);
- startPoint.setY(value);
- }
-
- public void setXAxisCoordinate(int value) {
- coordinates.setXAxisCoordinate(value);
- startPoint.setX(value);
- }
-
-
- public CoordinateSystem getCoordinates() {
- return coordinates;
- }
-
- /**
- * The main draw function -- implement this method to change
- * the way things are graphed
- *
- * @param gc
- * @param graphCanvas
- */
- public abstract void drawOn(GC gc, Composite graphCanvas);
-
-
- protected void drawLine(GC gc, DataPoint p1, DataPoint p2) {
- gc.drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
- }
-
- /**
- *
- * @return
- * Number of data buffers in this model
- */
- public int getBufferCount() {
- return data.size();
- }
-
- /**
- * Draws the x-axis and sets up the graph's title.
- * Also draws graduations for the x-axis
- *
- * @param gc
- * @param width
- */
- protected void drawAxis(GC gc, int width) {
- gc.setLineWidth(2);
- gc.drawLine(getXOffset(), getYOffset(), width, getYOffset());
- int xSeg = getXOffset();
- int increment = width/BUFFER_SIZE;
- while (xSeg < width) {
- gc.drawLine(xSeg, getYOffset(), xSeg, getYOffset() - getHeight());
- xSeg += increment;
- }
- gc.setForeground(new Color(Display.getCurrent(), 10, 10, 10));
- gc.drawText(getTitle(), getXOffset(), getYOffset() + 5, true);
-// gc.drawText(this.getCoordinates().getAxis().getTopLabel(), this.getXOffset(), this.getYOffset() - this.getHeight(), true);
- }
-
- protected void drawFillPolygons(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
- DataPoint pp = this.getStartPoint();
- int xSeg = this.getXOffset();
- int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
-
- gc.setLineWidth(0);
- while (nextPointBuffer.hasNext()) {
- gc.setAlpha(170);
- DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
- //Use old point, new point, and the corresponding intersections with the x-axis to fill
- gc.fillPolygon(new int[] {pp.getX(), pp.getY(), nextPoint.getX(), nextPoint.getY(), nextPoint.getX(), getStartPoint().getY(), pp.getX(), getStartPoint().getY()});
- xSeg += increment;
- pp = nextPoint;
- }
- }
-
- protected void drawLines(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
- DataPoint pp = this.getStartPoint();
- int xSeg = this.getXOffset();
- int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
-
- while (nextPointBuffer.hasNext()) {
- DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
- xSeg += increment;
- drawLine(gc, pp, nextPoint);
- pp = nextPoint;
- }
- }
-
-}
+package org.eclipse.linuxtools.threadprofiler.graphs;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.linuxtools.threadprofiler.CircularPointBuffer;
+import org.eclipse.linuxtools.threadprofiler.CoordinateSystem;
+import org.eclipse.linuxtools.threadprofiler.DataPoint;
+import org.eclipse.linuxtools.threadprofiler.GraphAxis;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+public abstract class GraphModel {
+
+ //Constant Y scale
+ public static final int CONSTANT_Y = 0;
+ //Change Y scale as the maximum y point increases
+ public static final int FLEXIBLE_Y = 1;
+ /** Maximum buffer size. This affects the number of data points*/
+ public static final int BUFFER_SIZE = 100;
+ //Default height
+ public static final int DEFAULT_HEIGHT = 100;
+
+ /** Number of spaces between graduations on the axis */
+ private static final int GRADUATION_SEPARATION = 5;
+
+ private final CoordinateSystem coordinates;
+ private final DataPoint startPoint;
+ private final int graphType;
+ private final String title;
+ private final String units;
+ private boolean changed;
+ protected final ArrayList<CircularPointBuffer> data;
+
+ private int height;
+
+ private int maxY;
+ //Height in pixels
+
+ public GraphModel(String name, int x, int y, int type, String units) {
+ graphType = type;
+ changed = false;
+ data = new ArrayList<CircularPointBuffer>();
+ title = name;
+ this.units = units;
+ height = DEFAULT_HEIGHT;
+ maxY = 100;
+ coordinates = new CoordinateSystem(x, y);
+ coordinates.setYScale(0.2);
+ coordinates.getAxis().setTopLabel(DEFAULT_HEIGHT + units);
+
+ startPoint = new DataPoint(coordinates.getXOffset(), coordinates.getYOffset(), 1);
+ }
+
+ public void setMaxY(int max) {
+ maxY = max;
+ }
+
+ public int getXOffset() {
+ return (int) coordinates.getAxisToPixel().entries[0][2];
+ }
+
+ public int getYOffset() {
+ return (int) coordinates.getAxisToPixel().entries[1][2];
+ }
+
+
+ /**
+ *
+ * @return
+ * First available point buffer if any is available, else null
+ */
+ public Iterator<DataPoint> getPointBuffer() {
+ if (data.size() > 1)
+ return getPointBuffer(0);
+ return null;
+ }
+
+ public Iterator<DataPoint> getPointBuffer(int index) {
+ return data.get(index).getIterator();
+ }
+
+ public GraphAxis getAxis() {
+ return coordinates.getAxis();
+ }
+
+ public DataPoint getStartPoint() {
+ return startPoint;
+ }
+
+ public void add(DataPoint point, int subIndex) {
+ if (subIndex >= data.size()) {
+ data.add(new CircularPointBuffer(BUFFER_SIZE));
+ }
+ if (graphType == FLEXIBLE_Y) {
+ if (point.getY() > maxY ) {
+ maxY = point.getY();
+ coordinates.getAxis().setTopLabel(maxY + " " + units);
+ if ( point.getY() > height) {
+ double newScale = (double) height/maxY;
+ coordinates.setYScale(newScale);
+ }
+ }
+ }
+ data.get(subIndex).add(point);
+ setChanged(true);
+ }
+
+ public DataPoint transform(DataPoint toTransform) {
+ return coordinates.dataToPixel(toTransform);
+ }
+
+ public boolean isChanged() {
+ return changed;
+ }
+
+ public void setChanged(boolean val) {
+ changed = val;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void setHeight(int value) {
+ if (height == value)
+ return;
+ height = value;
+ double newScale = (double) height/maxY;
+ coordinates.setYScale(newScale);
+ }
+
+
+ public void setYAxisCoordinate(int value) {
+ coordinates.setYAxisCoordinate(value);
+ startPoint.setY(value);
+ }
+
+ public void setXAxisCoordinate(int value) {
+ coordinates.setXAxisCoordinate(value);
+ startPoint.setX(value);
+ }
+
+
+ public CoordinateSystem getCoordinates() {
+ return coordinates;
+ }
+
+ /**
+ * The main draw function -- implement this method to change
+ * the way things are graphed
+ *
+ * @param gc
+ * @param graphCanvas
+ */
+ public abstract void drawOn(GC gc, Composite graphCanvas);
+
+
+ protected void drawLine(GC gc, DataPoint p1, DataPoint p2) {
+ gc.drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+ }
+
+ /**
+ *
+ * @return
+ * Number of data buffers in this model
+ */
+ public int getBufferCount() {
+ return data.size();
+ }
+
+ /**
+ * Draws the x-axis and sets up the graph's title.
+ * Also draws graduations for the x-axis
+ *
+ * @param gc
+ * @param width
+ */
+ protected void drawAxis(GC gc, int width) {
+ gc.setLineWidth(2);
+ gc.drawLine(getXOffset(), getYOffset(), width, getYOffset());
+ int xSeg = getXOffset();
+ int increment = width/BUFFER_SIZE;
+ while (xSeg < width) {
+ gc.drawLine(xSeg, getYOffset(), xSeg, getYOffset() - getHeight());
+ xSeg += GRADUATION_SEPARATION * increment;
+ }
+ gc.setForeground(new Color(Display.getCurrent(), 10, 10, 10));
+ gc.drawText(getTitle(), getXOffset(), getYOffset() + 5, true);
+// gc.drawText(this.getCoordinates().getAxis().getTopLabel(), this.getXOffset(), this.getYOffset() - this.getHeight(), true);
+ }
+
+ protected void drawFillPolygons(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
+ DataPoint pp = this.getStartPoint();
+ int xSeg = this.getXOffset();
+ int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
+
+ gc.setLineWidth(0);
+ while (nextPointBuffer.hasNext()) {
+ gc.setAlpha(170);
+ DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
+ //Use old point, new point, and the corresponding intersections with the x-axis to fill
+ gc.fillPolygon(new int[] {pp.getX(), pp.getY(), nextPoint.getX(), nextPoint.getY(), nextPoint.getX(), getStartPoint().getY(), pp.getX(), getStartPoint().getY()});
+ xSeg += increment;
+ pp = nextPoint;
+ }
+ }
+
+ protected void drawLines(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
+ DataPoint pp = this.getStartPoint();
+ int xSeg = this.getXOffset();
+ int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
+
+ while (nextPointBuffer.hasNext()) {
+ DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
+ xSeg += increment;
+ drawLine(gc, pp, nextPoint);
+ pp = nextPoint;
+ }
+ }
+
+}
diff --git a/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java b/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java
index ee3565e..5d958b2 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java
@@ -80,6 +80,7 @@ public class MultiGraph extends GraphModel {
gc.setBackground(oldBg);
}
+ gc.setLineWidth(0);
gc.drawText(getPointBuffer(i).toString(), xPos, yPos);
prev = getPointBuffer(i).toString();
xPos = xPos + separation(prev);