--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.threadlog;\r
+\r
+import gnu.trove.TDoubleArrayList;\r
+import gnu.trove.TLongArrayList;\r
+\r
+import java.io.BufferedInputStream;\r
+import java.io.BufferedOutputStream;\r
+import java.io.DataInput;\r
+import java.io.DataInputStream;\r
+import java.io.DataOutput;\r
+import java.io.DataOutputStream;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.StreamCorruptedException;\r
+import java.util.ArrayList;\r
+\r
+public class ThreadLog {\r
+\r
+ private static final transient String HDR = "TLOG";\r
+ private static final transient int CURRENT_VERSION = 1;\r
+\r
+ static ThreadLog defaultLog;\r
+\r
+ ArrayList<String> tasks = new ArrayList<String>();\r
+ TDoubleArrayList times = new TDoubleArrayList();\r
+ TLongArrayList threads = new TLongArrayList();\r
+\r
+ public double[] getTimes() {\r
+ return times.toNativeArray();\r
+ }\r
+\r
+ public String[] getTasks() {\r
+ return tasks.toArray(new String[tasks.size()]);\r
+ }\r
+\r
+ public long[] getThreads() {\r
+ return threads.toNativeArray();\r
+ }\r
+\r
+ private class TaskImpl implements Task {\r
+ public String name;\r
+ public long thread;\r
+ public long beginTime;\r
+\r
+ public TaskImpl(String name) {\r
+ this.name = name;\r
+ this.thread = Thread.currentThread().getId();\r
+ this.beginTime = System.nanoTime();\r
+ }\r
+\r
+ @Override\r
+ public void end() {\r
+ long endTime = System.nanoTime();\r
+ synchronized(tasks) {\r
+ tasks.add(name);\r
+ times.add(beginTime*1e-9);\r
+ times.add(endTime*1e-9);\r
+ threads.add(thread);\r
+ }\r
+ }\r
+ }\r
+\r
+ private static enum DummyTask implements Task {\r
+ INSTANCE;\r
+\r
+ @Override\r
+ public void end() {\r
+ }\r
+ }\r
+\r
+ public Task begin(String name) {\r
+ return new TaskImpl(name);\r
+ }\r
+\r
+ public static Task BEGIN(String name) {\r
+ try {\r
+ if(defaultLog != null)\r
+ return defaultLog.begin(name);\r
+ } catch(NullPointerException e) {\r
+ }\r
+ return DummyTask.INSTANCE;\r
+ }\r
+\r
+ public static ThreadLog setDefaultThreadLog(ThreadLog log) {\r
+ ThreadLog currentLog = defaultLog;\r
+ defaultLog = log;\r
+ return currentLog;\r
+ }\r
+\r
+ // ------------------------------------------------------------------------\r
+ // SERIALIZATION\r
+ // ------------------------------------------------------------------------\r
+\r
+ public static ThreadLog deserialize(File file) throws IOException {\r
+ DataInputStream in = null;\r
+ try {\r
+ in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));\r
+ ThreadLog log = new ThreadLog();\r
+ log.doDeserialize(in);\r
+ return log;\r
+ } finally {\r
+ if (in != null) {\r
+ in.close();\r
+ }\r
+ }\r
+ }\r
+\r
+ public static ThreadLog deserialize(DataInput in) throws IOException {\r
+ ThreadLog log = new ThreadLog();\r
+ log.doDeserialize(in);\r
+ return log;\r
+ }\r
+\r
+ private void doDeserialize(DataInput in) throws IOException {\r
+ String hdr = in.readUTF();\r
+ if (!HDR.equals(hdr)) {\r
+ throw new StreamCorruptedException("invalid header '" + hdr + "', expected " + HDR);\r
+ }\r
+ int ver = in.readInt();\r
+ if (ver == CURRENT_VERSION) {\r
+ int taskCount = in.readInt();\r
+ for (int i = 0; i < taskCount; ++i) {\r
+ String task = in.readUTF();\r
+ double beginTime = in.readDouble();\r
+ double endTime = in.readDouble();\r
+ long threadId = in.readLong();\r
+ tasks.add(task);\r
+ times.add(beginTime);\r
+ times.add(endTime);\r
+ threads.add(threadId);\r
+ }\r
+ } else {\r
+ throw new StreamCorruptedException("unrecognized log version: " + ver);\r
+ }\r
+ }\r
+\r
+ public void serialize(File file) throws IOException {\r
+ DataOutputStream out = null;\r
+ try {\r
+ out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));\r
+ serialize(out);\r
+ } finally {\r
+ if (out != null) {\r
+ out.close();\r
+ }\r
+ }\r
+ }\r
+\r
+ public void serialize(DataOutput out) throws IOException {\r
+ out.writeUTF(HDR);\r
+ out.writeInt(CURRENT_VERSION);\r
+ int len = tasks.size();\r
+ out.writeInt(len);\r
+ for (int i = 0; i < len; ++i) {\r
+ out.writeUTF(tasks.get(i));\r
+ out.writeDouble(times.getQuick(i*2));\r
+ out.writeDouble(times.getQuick(i*2+1));\r
+ out.writeLong(threads.getQuick(i));\r
+ }\r
+ }\r
+\r
+}\r