benchmark silo added
[c11concurrency-benchmarks.git] / silo / stats_client.cc
diff --git a/silo/stats_client.cc b/silo/stats_client.cc
new file mode 100644 (file)
index 0000000..d35799c
--- /dev/null
@@ -0,0 +1,90 @@
+/**
+ * stats_client.cc
+ *
+ * stand-alone client to poll a stats server
+ *
+ */
+
+#include <iostream>
+#include <string>
+#include <system_error>
+#include <thread>
+
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "counter.h"
+#include "stats_common.h"
+#include "util.h"
+
+using namespace std;
+using namespace util;
+
+int
+main(int argc, char **argv)
+{
+  if (argc != 3) {
+    cerr << "[usage] " << argv[0] << " sockfile counterspec" << endl;
+    return 1;
+  }
+
+  const string sockfile(argv[1]);
+  const vector<string> counter_names = split(argv[2], ':');
+
+  int fd = socket(AF_UNIX, SOCK_STREAM, 0);
+  if (fd < 0)
+    throw system_error(errno, system_category(),
+        "creating UNIX domain socket");
+  struct sockaddr_un addr;
+  memset(&addr, 0, sizeof addr);
+  addr.sun_family = AF_UNIX;
+  if (sockfile.length() + 1 >= sizeof addr.sun_path)
+    throw range_error("UNIX domain socket path too long");
+  strcpy(addr.sun_path, sockfile.c_str());
+  size_t len = strlen(addr.sun_path) + sizeof(addr.sun_family);
+  if (connect(fd, (struct sockaddr *) &addr, len) < 0)
+    throw system_error(errno, system_category(),
+        "connecting to socket");
+
+  packet pkt;
+  int r;
+  timer loop_timer;
+  for (;;) {
+    for (auto &name : counter_names) {
+      uint8_t buf[1 + name.size()];
+      buf[0] = (uint8_t) stats_command::GET_COUNTER_VALUE;
+      memcpy(&buf[1], name.data(), name.size());
+      pkt.assign((const char *) &buf[0], sizeof(buf));
+      if ((r = pkt.sendpkt(fd))) {
+        perror("send - disconnecting");
+        return 1;
+      }
+      if ((r = pkt.recvpkt(fd))) {
+        if (r == EOF)
+          return 0;
+        perror("recv - disconnecting");
+        return 1;
+      }
+      const get_counter_value_t *resp = (const get_counter_value_t *) pkt.data();
+      cout << name                << " "
+           << resp->timestamp_us_ << " "
+           << resp->d_.count_     << " "
+           << resp->d_.sum_       << " "
+           << resp->d_.max_       << endl;
+    }
+
+    const uint64_t last_loop_usec  = loop_timer.lap();
+    //const uint64_t delay_time_usec = 1000000;
+    const uint64_t delay_time_usec = 1000000/1000;
+    if (last_loop_usec < delay_time_usec) {
+      const uint64_t sleep_ns = (delay_time_usec - last_loop_usec) * 1000;
+      struct timespec t;
+      t.tv_sec  = sleep_ns / ONE_SECOND_NS;
+      t.tv_nsec = sleep_ns % ONE_SECOND_NS;
+      nanosleep(&t, nullptr);
+    }
+  }
+
+  return 0;
+}