---
 .gitignore                   |   1 +
 examples/Makefile.am         |  16 +++++
 examples/connect-benchmark.c | 112 +++++++++++++++++++++++++++++++++++
 3 files changed, 129 insertions(+)

diff --git a/.gitignore b/.gitignore
index 0d4bef92c..7bc0a6778 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,6 +70,7 @@ Makefile.in
 /dump/nbddump.1
 /examples/aio-connect-read
 /examples/batched-read-write
+/examples/connect-benchmark
 /examples/connect-command
 /examples/connect-uri
 /examples/copy-libev
diff --git a/examples/Makefile.am b/examples/Makefile.am
index bad22cb11..b52996a24 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -22,6 +22,7 @@ EXTRA_DIST = LICENSE-FOR-EXAMPLES
 noinst_PROGRAMS = \
        aio-connect-read \
        batched-read-write \
+       connect-benchmark \
        connect-command \
        connect-uri \
        encryption \
@@ -62,6 +63,21 @@ batched_read_write_LDADD = \
        $(top_builddir)/lib/libnbd.la \
        $(NULL)
 
+connect_benchmark_SOURCES = \
+       connect-benchmark.c \
+       $(NULL)
+connect_benchmark_CPPFLAGS = \
+       -I$(top_srcdir)/include \
+       $(NULL)
+connect_benchmark_CFLAGS = \
+       $(WARNINGS_CFLAGS) \
+       $(PTHREAD_CFLAGS) \
+       $(NULL)
+connect_benchmark_LDADD = \
+       $(top_builddir)/lib/libnbd.la \
+       $(PTHREAD_LIBS) \
+       $(NULL)
+
 connect_command_SOURCES = \
        connect-command.c \
        $(NULL)
diff --git a/examples/connect-benchmark.c b/examples/connect-benchmark.c
new file mode 100644
index 000000000..1e153b915
--- /dev/null
+++ b/examples/connect-benchmark.c
@@ -0,0 +1,112 @@
+/* The example benchmarks multiple parallel connections to an NBD
+ * server.  You can use it to time how long it takes to connect under
+ * various circumstances (eg. TLS vs no TLS, old vs newstyle, with or
+ * without TCP fastopen).  It only does the NBD handshake and then
+ * immediately disconnects.
+ *
+ * Typical usage:
+ *   ./examples/connect-benchmark nbd://localhost 16 1000
+ * where the parameters are:
+ *   URI of the server
+ *   number of threads
+ *   total number of connections to make (across all threads)
+ *
+ * Or:
+ *   nbdkit null --run './examples/connect-benchmark "$uri" 16 1000'
+ *
+ * Use 'hyperfine' to time multiple runs.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <errno.h>
+
+#include <pthread.h>
+
+#include <libnbd.h>
+
+static const char *uri;
+static unsigned nr_threads, nr_connections;
+static _Atomic unsigned count = 0;
+
+static void *start_thread (void *arg);
+
+int
+main (int argc, char *argv[])
+{
+  pthread_t *threads;
+  unsigned i;
+  int err;
+
+  if (argc != 4) {
+    fprintf (stderr, "%s URI threads connections\n", argv[0]);
+    exit (EXIT_FAILURE);
+  }
+  uri = argv[1];
+  if (sscanf (argv[2], "%u", &nr_threads) != 1 ||
+      sscanf (argv[3], "%u", &nr_connections) != 1) {
+    fprintf (stderr, "%s: cannot read number of threads or connections\n",
+             argv[0]);
+    exit (EXIT_FAILURE);
+  }
+
+  threads = calloc (nr_threads, sizeof threads[0]);
+  if (threads == NULL) {
+    perror ("calloc");
+    exit (EXIT_FAILURE);
+  }
+
+  /* Start the worker threads, one per connection. */
+  for (i = 0; i < nr_threads; ++i) {
+    err = pthread_create (&threads[i], NULL, start_thread, NULL);
+    if (err != 0) {
+      errno = err;
+      perror ("pthread_create");
+      exit (EXIT_FAILURE);
+    }
+  }
+
+  /* Wait for the threads to exit. */
+  for (i = 0; i < nr_threads; ++i) {
+    err = pthread_join (threads[i], NULL);
+    if (err != 0) {
+      errno = err;
+      perror ("pthread_join");
+      exit (EXIT_FAILURE);
+    }
+  }
+
+  exit (EXIT_SUCCESS);
+}
+
+static void *
+start_thread (void *arg)
+{
+  struct nbd_handle *nbd;
+  unsigned i;
+
+  for (;;) {
+    i = count++;
+    if (i >= nr_connections) break;
+
+    nbd = nbd_create ();
+    if (nbd == NULL) {
+      fprintf (stderr, "%s\n", nbd_get_error ());
+      exit (EXIT_FAILURE);
+    }
+
+    if (nbd_connect_uri (nbd, uri) == -1) {
+      fprintf (stderr, "%s\n", nbd_get_error ());
+      exit (EXIT_FAILURE);
+    }
+
+    nbd_close (nbd);
+  }
+
+  pthread_exit (NULL);
+}
-- 
2.46.0
_______________________________________________
Libguestfs mailing list -- guestfs@lists.libguestfs.org
To unsubscribe send an email to guestfs-le...@lists.libguestfs.org

Reply via email to