00001 package org.hfbk.vis.visnode;
00002
00003 import java.io.BufferedReader;
00004 import java.io.IOException;
00005 import java.io.InputStream;
00006 import java.io.InputStreamReader;
00007 import java.util.ArrayList;
00008 import java.util.HashMap;
00009 import java.util.List;
00010 import java.util.Map;
00011
00012 import org.dronus.gl.GLFont;
00013 import org.dronus.gl.GLSphereRenderer;
00014 import org.dronus.gl.GLTextPanel;
00015 import org.dronus.gl.GLUtil;
00016 import org.dronus.graph.Edge;
00017 import org.dronus.graph.Graph;
00018 import org.dronus.graph.Node;
00019 import org.hfbk.util.Counter;
00020 import org.hfbk.util.Sleeper;
00021 import org.lwjgl.opengl.GL11;
00022 import org.lwjgl.util.vector.Vector3f;
00023
00036 public class VisPs extends VisSet {
00037
00039
00040 final int DELAY=1000;
00041
00043 Graph profile=new Graph();
00044
00046 Counter<Integer> callCounter=new Counter<Integer>();
00047
00048
00049 boolean dirty=true;
00050
00052 class VisCallBall extends VisNodeDraggable {
00053 int dl;
00054 GLTextPanel helpText;
00055 Node node;
00056 boolean isTriggered=true;
00057
00058 VisCallBall(Node n, Vector3f position) {
00059 super(n, position);
00060 this.node=n;
00061 w=h=radius=1.6f;
00062 helpText=new GLTextPanel(n.text,0,0);
00063 }
00064
00065 void renderSelf() {
00066 Integer count=callCounter.get(node.id);
00067 if (count!=null){
00068 radius=.3f+10*(float)Math.sqrt(count/(float)callCounter.total);
00069 w=h=2*radius;
00070 }
00071 if (isHoovered || isTriggered)
00072 GL11.glColor3f(1,1,1);
00073 else if (node.type.equals("Process")){
00074 boolean isOur=!node.text.startsWith("root:");
00075 GL11.glColor3f(1,1,(isOur ? 1 : .5f ));
00076 }
00077 else if (node.type.equals("Call")){
00078 boolean isOur=!node.text.startsWith("root:");
00079 GL11.glColor4f(1,0,0,(isOur ? 1 : .5f ));
00080 }
00081
00082 GLSphereRenderer.renderSphere(radius);
00083
00084
00085 if (isHoovered) {
00086 GL11.glTranslatef(radius,radius,0);
00087 GLUtil.billboardCylinder();
00088 GL11.glScalef(1,2,1);
00089 GLFont.getDefault().render();
00090 helpText.render();
00091 GL11.glDisable(GL11.GL_TEXTURE_2D);
00092 }
00093
00094 isTriggered=false;
00095 }
00096 }
00097
00099 VisNode create(Node node, Vector3f pos) {
00100 return new VisCallBall(node, pos);
00101 }
00102
00104 public VisPs(Node dummy, Vector3f position) {
00105 super(null, position);
00106
00107 profile.addNode(new Node("0","Vis/Client","Set"));
00108
00109 Thread profiler=new Thread(){
00110 public void run() {
00111 setName("VisProfiler");
00112 while(true){
00113 synchronized(VisPs.this){ profile(); };
00114 Sleeper.sleep(DELAY);
00115 }
00116 }
00117 };
00118 profiler.start();
00119 }
00120
00125 void profile(){
00126 Node rootset=profile.getRoot();
00127
00128 List<Node> activeNodes=new ArrayList<Node>();
00129 List<Edge> activeEdges=new ArrayList<Edge>();
00130
00131 Runtime rt = Runtime.getRuntime();
00132 Process ps;
00133 InputStream is=null;
00134
00135 HashMap<String,String[]> procs=new HashMap<String,String[]>();
00136
00137
00138 try {
00139 ps = rt.exec("ps -ef");
00140 is = ps.getInputStream();
00141 try {
00142 ps.waitFor();
00143 } catch (InterruptedException e) {
00144
00145 e.printStackTrace();
00146 }
00147
00148
00149
00150 BufferedReader result = new BufferedReader(new InputStreamReader(is));
00151 String ln=result.readLine();
00152 while (ln!=null)
00153 {
00154
00155 ln=result.readLine();
00156
00157 if (ln!=null)
00158 {
00159 String[] parts=ln.split(" +");
00160 String powner=parts[0];
00161 String PID=parts[1];
00162 String PPID=parts[2];
00163 String pname=parts[7];
00164
00165 String[] procinfo={PPID,pname,powner};
00166
00167 procs.put(PID,procinfo);
00168
00169 }
00170 }
00171
00172
00173 } catch (IOException e) {
00174
00175 e.printStackTrace();
00176 }
00177
00178 activeNodes.clear();
00179 activeEdges.clear();
00180
00181 for(Map.Entry<String,String[]> proc : procs.entrySet()){
00182
00183 int procId= Integer.valueOf(proc.getKey() ).intValue();
00184 String[] procInfo=proc.getValue();
00185 Node procNode=profile.findNode(procId);
00186 if(procNode==null) {
00187 procNode=new Node(procId, procInfo[2]+":"+procInfo[1], "Process");
00188 profile.addNode(procNode);
00189 activeNodes.add(procNode);
00190
00191 profile.addEdge(new Edge(procNode,rootset, null, "in"));
00192 }
00193
00194
00195 Node last=null;
00196 int parentid=Integer.valueOf(proc.getValue()[0] ).intValue();
00197
00198 callCounter.add(parentid);
00199
00200 Node n=profile.findNode(parentid);
00201
00202 if (n==null){
00203 n=new Node(parentid, procInfo[2]+":"+procInfo[1],"Call");
00204 profile.addNode(n);
00205 activeNodes.add(n);
00206 dirty=true;
00207 }
00208 Edge edgeNode =new Edge(n,rootset, null, "in");
00209 profile.addEdge(edgeNode);
00210 activeEdges.add(edgeNode);
00211
00212 if (last!=null)
00213 profile.addEdge(new Edge(last,n, null, ""));
00214 else
00215 profile.addEdge(new Edge(n,procNode, null, "in"));
00216 last=n;
00217 }
00218
00219 profile.nodes.retainAll(activeNodes);
00220 profile.edges.retainAll(activeEdges);
00221 }
00222
00223 void renderSelf() {
00224 super.renderSelf();
00225
00226
00227 if (dirty) synchronized(this){
00228 Node root=profile.getRoot();
00229 update(root);
00230
00231 dirty=false;
00232 }
00233 }
00234 }