From a6742020d03049e42c6f910cc35e4b04ace74df2 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Tue, 18 Oct 2016 18:17:11 +0200
Subject: [PATCH] T: add some hack programs

- time_meas to measure time spent in scheduling
- timeplot to show nice histograms in realtim of above measurement
---
 common/utils/T/tracer/hacks/Makefile    |  11 ++-
 common/utils/T/tracer/hacks/time_meas.c | 112 ++++++++++++++++++++++++
 common/utils/T/tracer/hacks/timeplot.c  |  84 ++++++++++++++++++
 3 files changed, 205 insertions(+), 2 deletions(-)
 create mode 100644 common/utils/T/tracer/hacks/time_meas.c
 create mode 100644 common/utils/T/tracer/hacks/timeplot.c

diff --git a/common/utils/T/tracer/hacks/Makefile b/common/utils/T/tracer/hacks/Makefile
index ab10305c0..f49e437bf 100644
--- a/common/utils/T/tracer/hacks/Makefile
+++ b/common/utils/T/tracer/hacks/Makefile
@@ -3,16 +3,23 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. -I..
 
 LIBS=-lX11 -lm -lpng -lXft
 
-all: dump_nack_signal
+all: dump_nack_signal time_meas timeplot
 
 dump_nack_signal: ../utils.o ../database.o ../config.o ../event.o \
                   dump_nack_signal.o
 	$(CC) $(CFLAGS) -o dump_nack_signal $^ $(LIBS)
 
+time_meas: ../utils.o ../database.o ../config.o ../event.o \
+                  time_meas.o
+	$(CC) $(CFLAGS) -o time_meas $^ $(LIBS)
+
+timplot: timeplot.o
+	$(CC) $(CFLAGS) -o timeplot $^ $(LIBS)
+
 .PHONY: all
 
 %.o: %.c
 	$(CC) $(CFLAGS) -c -o $@ $<
 
 clean:
-	rm -f *.o core dump_nack_signal
+	rm -f *.o core dump_nack_signal time_meas timeplot
diff --git a/common/utils/T/tracer/hacks/time_meas.c b/common/utils/T/tracer/hacks/time_meas.c
new file mode 100644
index 000000000..04d4fa5ac
--- /dev/null
+++ b/common/utils/T/tracer/hacks/time_meas.c
@@ -0,0 +1,112 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "utils.h"
+#include "event.h"
+#include "database.h"
+#include "config.h"
+#include "../T_defs.h"
+
+void usage(void)
+{
+  printf(
+"options:\n"
+"    -d <database file>        this option is mandatory\n"
+"    -ip <host>                connect to given IP address (default %s)\n"
+"    -p <port>                 connect to given port (default %d)\n",
+  DEFAULT_REMOTE_IP,
+  DEFAULT_REMOTE_PORT
+  );
+  exit(1);
+}
+
+struct timespec time_sub(struct timespec a, struct timespec b)
+{
+  struct timespec ret;
+  if (a.tv_nsec < b.tv_nsec) {
+    ret.tv_nsec = (int64_t)a.tv_nsec - (int64_t)b.tv_nsec + 1000000000;
+    ret.tv_sec = a.tv_sec - b.tv_sec - 1;
+  } else {
+    ret.tv_nsec = a.tv_nsec - b.tv_nsec;
+    ret.tv_sec = a.tv_sec - b.tv_sec;
+  }
+  return ret;
+}
+
+int main(int n, char **v)
+{
+  char *database_filename = NULL;
+  void *database;
+  char *ip = DEFAULT_REMOTE_IP;
+  int port = DEFAULT_REMOTE_PORT;
+  int i;
+  char t;
+  int number_of_events;
+  int socket;
+  int *is_on;
+  int ev_fun;
+  int start_valid = 0;
+  struct timespec start_time, stop_time, delta_time;
+
+  for (i = 1; i < n; i++) {
+    if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
+    if (!strcmp(v[i], "-d"))
+      { if (i > n-2) usage(); database_filename = v[++i]; continue; }
+    if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
+    if (!strcmp(v[i], "-p"))
+      { if (i > n-2) usage(); port = atoi(v[++i]); continue; }
+    usage();
+  }
+
+  if (database_filename == NULL) {
+    printf("ERROR: provide a database file (-d)\n");
+    exit(1);
+  }
+
+  database = parse_database(database_filename);
+
+  load_config_file(database_filename);
+
+  number_of_events = number_of_ids(database);
+  is_on = calloc(number_of_events, sizeof(int));
+  if (is_on == NULL) abort();
+
+  on_off(database, "VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER", is_on, 1);
+
+  ev_fun = event_id_from_name(database,
+      "VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER");
+
+  socket = connect_to(ip, port);
+
+  t = 1;
+  if (socket_send(socket, &t, 1) == -1 ||
+      socket_send(socket, &number_of_events, sizeof(int)) == -1 ||
+      socket_send(socket, is_on, number_of_events * sizeof(int)) == -1)
+    abort();
+
+  while (1) {
+    char v[T_BUFFER_MAX];
+    event e;
+    int on_off;
+    e = get_event(socket, v, database);
+    if (e.type == -1) break;
+    if (e.type != ev_fun)
+      { printf("unhandled event %d\n", e.type); continue; }
+    on_off = e.e[0].i;
+printf("yo %d\n", on_off);
+    if (on_off == 1) {
+      start_time = e.sending_time;
+      start_valid = 1;
+      continue;
+    }
+    if (on_off != 0) { printf("fatal!\n"); abort(); }
+    if (!start_valid) continue;
+    stop_time = e.sending_time;
+    delta_time = time_sub(stop_time, start_time);
+    fprintf(stderr, "%ld\n",
+        delta_time.tv_sec * 1000000000UL + delta_time.tv_nsec);
+    fflush(stderr);
+  }
+
+  return 0;
+}
diff --git a/common/utils/T/tracer/hacks/timeplot.c b/common/utils/T/tracer/hacks/timeplot.c
new file mode 100644
index 000000000..79905d16f
--- /dev/null
+++ b/common/utils/T/tracer/hacks/timeplot.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+
+void RESET(void)
+{ printf("\x1b""c"); fflush(stdout); }
+
+void GOTO(int x, int y)
+{ char s[64];sprintf(s,"\x1b[%d;%dH",y,x);printf("%s",s);fflush(stdout); }
+
+void HIDE_CURSOR(void)
+{ printf("\x1b[?25l"); fflush(stdout); }
+
+void sig(int x)
+{
+  RESET();
+  exit(0);
+}
+
+/* 0: [0-2[
+ * ...
+ * 48: [96-98[
+ * 49: [98-infinity]
+ */
+int bins[50];
+
+#define N 1000
+int data[N];
+
+void plot(void)
+{
+  int i;
+  int max = 0;
+  int vmin = data[0];
+  int vmax = 0;
+  long vavg;
+  memset(bins, 0, sizeof(bins));
+  int binsize_ns = 500;
+
+  vavg = 0;
+
+  for (i = 0; i < N; i++) {
+    if (data[i] < vmin) vmin = data[i];
+    if (data[i] > vmax) vmax = data[i];
+    vavg += data[i];
+    int ms2 = data[i]/binsize_ns;
+    if (ms2 > 49) ms2 = 49;
+    bins[ms2]++;
+    if (bins[ms2] > max) max = bins[ms2];
+  }
+
+  vavg /= N;
+
+  GOTO(1,1);
+  for (i = 0; i < 50; i++) {
+    double binend = (i+1) * binsize_ns / 1000.;
+    int k;
+    int width = bins[i] * 70 / max;
+    /* force at least width of 1 if some point is there */
+    if (bins[i] && width == 0) width = 1;
+    printf("%#5.1f ", binend);
+    for (k = 0; k < width; k++) putchar('#');
+    for (; k < 70; k++) putchar(' ');
+    putchar('\n');
+  }
+  printf("min %d ns    max %d ns    avg %ld ns\n", vmin, vmax, vavg);
+}
+
+int main(void)
+{
+  int i;
+  int pos = 0;
+  signal(SIGINT, sig);
+  RESET();
+  HIDE_CURSOR();
+  while (!feof(stdin)) {
+    for (i=0; i<100; i++) { scanf("%d", &data[pos]); pos++; pos%=N; }
+    plot();
+  }
+  RESET();
+  return 0;
+}
-- 
GitLab