about summary refs log tree commit diff
path: root/nptl/cond-perf.c
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/cond-perf.c')
-rw-r--r--nptl/cond-perf.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/nptl/cond-perf.c b/nptl/cond-perf.c
new file mode 100644
index 0000000000..c3305b391d
--- /dev/null
+++ b/nptl/cond-perf.c
@@ -0,0 +1,100 @@
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t mut1 = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t mut2 = PTHREAD_MUTEX_INITIALIZER;
+
+static bool last_round;
+static int ntogo;
+static bool alldone;
+
+
+static void *
+cons (void *arg)
+{
+  pthread_mutex_lock (&mut1);
+
+  do
+    {
+      if (--ntogo == 0)
+	{
+	  alldone = true;
+	  pthread_cond_signal (&cond2);
+	}
+
+      pthread_cond_wait (&cond1, &mut1);
+    }
+  while (! last_round);
+
+  pthread_mutex_unlock (&mut1);
+
+  return NULL;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  int opt;
+  int err;
+  int nthreads = 10;
+  int nrounds = 100;
+  bool keeplock = false;
+
+  while ((opt = getopt (argc, argv, "n:r:k")) != -1)
+    switch (opt)
+      {
+      case 'n':
+	nthreads = atol (optarg);
+	break;
+      case 'r':
+	nrounds = atol (optarg);
+	break;
+      case 'k':
+	keeplock = true;
+	break;
+      }
+
+  ntogo = nthreads;
+
+  pthread_t th[nthreads];
+  int i;
+  for (i = 0; i < nthreads; ++i)
+    if ((err = pthread_create (&th[i], NULL, cons, (void *) (long) i)) != 0)
+      printf ("pthread_create: %s\n", strerror (err));
+
+  for (i = 0; i < nrounds; ++i)
+    {
+      pthread_mutex_lock (&mut2);
+      while (! alldone)
+	pthread_cond_wait (&cond2, &mut2);
+      pthread_mutex_unlock (&mut2);
+
+      pthread_mutex_lock (&mut1);
+      if (! keeplock)
+	pthread_mutex_unlock (&mut1);
+
+      ntogo = nthreads;
+      alldone = false;
+      if (i + 1 >= nrounds)
+	last_round = true;
+
+      pthread_cond_broadcast (&cond1);
+
+      if (keeplock)
+	pthread_mutex_unlock (&mut1);
+    }
+
+  for (i = 0; i < nthreads; ++i)
+    if ((err = pthread_join (th[i], NULL)) != 0)
+      printf ("pthread_create: %s\n", strerror (err));
+
+  return 0;
+}