Commits

Anonymous committed 1493de2

improved history file format, now includes summary and header

Comments (0)

Files changed (1)

+/*
+ * TraceVis log file processor.
+ *
+ * Default action is to print a text summary. The |-h| option instead writes the history to
+ * stdout in a binary format.
+ *
+ * Binary history format:
+ *
+ *       length            contents
+ *
+ *       12                literal text |TraceVis-History|
+ *        4                text format-version-id (e.g. |0001|).
+ *
+ *        8                uint64 rdtsc time elapsed for entire log
+ *        4                uint32 count of following records = M (= S_COUNT)
+ *       8M              M uint64 rdtsc time totals by state, from 0 to S_COUNT-1
+ *       9N              N 9-byte packed records (X = 17+9N)
+ *             0                 byte VM state transitioned to
+ *             8                 uint64 rdtsc timestamp, starting from 0
+ */
+
 #include <stdio.h>
+#include <sys/stat.h>
 #include <vector>
 #include <algorithm>
 
 #include "tracevis.h"
 #include "tracevis_gen.h"
 
+const char* FORMAT_ID = "TraceVis-History";
+const int FORMAT_ID_LEN = strlen(FORMAT_ID);
+const int VERSION_ID = 1;
+
+const size_t BODY_POS = 20;
+
 const double CPU_SPEED = 2.2e9;
 typedef unsigned long long uint64;
+typedef unsigned uint32;
 
 const char* filename = "/tmp/jsacts";
 const size_t pagesize = 4096;
 // options
 bool print_summary = true;
 bool print_history = false;
+const char* history_filename = 0;
+
+FILE* history_file = 0;
 
 static void rep(char ch, int n)
 {
     state_summary[rec0.s] += dt;
 
     if (print_history) {
-      putc(rec0.s, stdout);
+      putc(rec0.s, history_file);
       uint64 t = rec1.t - t0;
-      fwrite(&t, 1, sizeof(rec1.t), stdout);
+      fwrite(&t, 1, sizeof(rec1.t), history_file);
     }
 
     // Transition to interpreter
   return !strcmp(s1, s2);
 }
 
+void open_history_file()
+{
+  struct stat st;
+  int rc = stat(history_filename, &st);
+  if (rc == 0) {
+    FILE* f = fopen(history_filename, "rb");
+    char buf[FORMAT_ID_LEN];
+    fread(buf, 1, FORMAT_ID_LEN, f);
+    if (memcmp(buf, FORMAT_ID, FORMAT_ID_LEN) != 0) {
+      printf("file exists and is not a history file: %s\n", history_filename);
+      exit(1);
+    }
+    fclose(f);
+  }
+  history_file = fopen(history_filename, "wb");
+  if (!history_file) {
+    printf("cannot open output file: %s\n", history_filename);
+    exit(1);
+  }
+  fprintf(history_file, "TraceVis-History%04d", VERSION_ID);
+  assert(ftell(history_file) == BODY_POS);
+}
+
 int main(int argc, char **argv)
 {
   int i = 1;
   for (; i < argc; ++i) {
     const char* arg = argv[i];
     if (streq(arg, "-h")) {
-      print_summary = false;
       print_history = true;
+      history_filename = argv[++i];
     }
   }
 
   FILE* f = fopen(filename, "rb");
   uint64 recs[page_records];
   History h;
+
+  if (print_history) {
+    open_history_file();
+    fseek(history_file, 8 + 4 + 8 * S_COUNT, SEEK_CUR);
+  }
+
   while (true) {
     size_t nread = fread(recs, sizeof(uint64), page_records, f);
     if (nread == 0)
       process_record(h, recs[i]);
     }
   }
+
   if (print_history) {
     uint64 dt = h.t1 - h.t0;
-    fwrite(&dt, 1, sizeof(dt), stdout);
-    fprintf(stderr, "dt = %llu %12.3f\n", dt, dt/CPU_SPEED);
+    fseek(history_file, BODY_POS, SEEK_SET);
+    fwrite(&dt, sizeof(dt), 1, history_file);
+    
+    uint32 n = S_COUNT;
+    fwrite(&n, sizeof(n), 1, history_file);
+    fwrite(h.state_summary, sizeof(h.state_summary[0]), S_COUNT, history_file);
+
+    fclose(history_file);    
   }
+
   if (print_summary) {
     h.list_state_summary();
     printf("\n");