Initial revision. master
authorEmil Mikulic <emikulic@gmail.com>
Tue, 19 Feb 2013 12:02:44 +0000 (23:02 +1100)
committerEmil Mikulic <emikulic@gmail.com>
Tue, 19 Feb 2013 12:02:44 +0000 (23:02 +1100)
diskpinger.c [new file with mode: 0644]

diff --git a/diskpinger.c b/diskpinger.c
new file mode 100644 (file)
index 0000000..eab3b69
--- /dev/null
@@ -0,0 +1,76 @@
+/* emikulic@gmail.com was here 2013 */
+#define  _GNU_SOURCE  /* for O_NOATIME and O_DIRECT */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <time.h>
+
+static const char scratch_file_name[] = "scratch";
+/* also block and fragment size of root fs: */
+static const size_t buf_size = 4096;
+/* write at most this often: */
+static const int period_usec = 500000;
+
+int main() {
+  int fd;
+  char *buf;
+
+  if (posix_memalign((void**)(&buf), buf_size, buf_size) != 0)
+    errx(1, "posix_memalign() failed");
+
+  if ((fd = open(scratch_file_name,
+                 O_CREAT | O_TRUNC | O_NOATIME | O_RDWR | O_DIRECT,
+                 0600)) == -1)
+    err(1, "open() failed");
+  /* O_SYNC doesn't seem to be needed here. */
+
+  for (;;) {
+    ssize_t ret;
+    struct timespec t1, t2, tr;
+    int diff_sec, diff_nsec, sleep_len;
+
+    if (clock_gettime(CLOCK_REALTIME, &tr) == -1)
+      err(1, "clock_gettime() failed");
+    if (clock_gettime(CLOCK_MONOTONIC, &t1) == -1)
+      err(1, "clock_gettime() failed");
+
+    ret = pwrite(fd, buf, buf_size, 0);
+    if (ret == -1)
+      err(1, "pwrite() failed (errno=%d)", errno);
+    if (ret != buf_size)
+      warn("pwrite() returned %d, expected %d", (int)ret, (int)buf_size);
+
+    if (clock_gettime(CLOCK_MONOTONIC, &t2) == -1)
+      err(1, "clock_gettime() failed");
+
+    diff_sec = t2.tv_sec - t1.tv_sec;
+    diff_nsec = t2.tv_nsec - t1.tv_nsec;
+    if (diff_nsec < 0) {
+      diff_sec--;
+      diff_nsec += 1000000000;
+    }
+
+    printf("r %d.%09d m %d.%09d wr %d.%09d\n",
+           (int)tr.tv_sec, (int)tr.tv_nsec,
+           (int)t1.tv_sec, (int)t1.tv_nsec,
+           diff_sec, diff_nsec);
+    fflush(stdout);
+
+    if (diff_sec > 0) {
+      sleep_len = 1;
+    } else {
+      sleep_len = period_usec - diff_nsec / 1000;
+      if (sleep_len < 0)
+        sleep_len = 1;
+    }
+    usleep(sleep_len);
+  }
+  return 0;
+}
+/* vim:set ts=2 sw=2 et tw=80: */