summaryrefslogtreecommitdiff
path: root/libpthread/nptl/cond-perf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread/nptl/cond-perf.c')
-rw-r--r--libpthread/nptl/cond-perf.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/libpthread/nptl/cond-perf.c b/libpthread/nptl/cond-perf.c
new file mode 100644
index 000000000..e37914e6b
--- /dev/null
+++ b/libpthread/nptl/cond-perf.c
@@ -0,0 +1,103 @@
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <atomic.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 (atomic_decrement_and_test (&ntogo))
+ {
+ pthread_mutex_lock (&mut2);
+ alldone = true;
+ pthread_cond_signal (&cond2);
+ pthread_mutex_unlock (&mut2);
+ }
+
+ 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; __builtin_expect (i < nthreads, 1); ++i)
+ if (__builtin_expect ((err = pthread_create (&th[i], NULL, cons, (void *) (long) i)) != 0, 0))
+ printf ("pthread_create: %s\n", strerror (err));
+
+ for (i = 0; __builtin_expect (i < nrounds, 1); ++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;
+}