Back to index

glibc  2.9
cond-perf.c
Go to the documentation of this file.
00001 #include <pthread.h>
00002 #include <stdbool.h>
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include <unistd.h>
00007 #include <atomic.h>
00008 
00009 static pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
00010 static pthread_mutex_t mut1 = PTHREAD_MUTEX_INITIALIZER;
00011 
00012 static pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
00013 static pthread_mutex_t mut2 = PTHREAD_MUTEX_INITIALIZER;
00014 
00015 static bool last_round;
00016 static int ntogo;
00017 static bool alldone;
00018 
00019 
00020 static void *
00021 cons (void *arg)
00022 {
00023   pthread_mutex_lock (&mut1);
00024 
00025   do
00026     {
00027       if (atomic_decrement_and_test (&ntogo))
00028        {
00029          pthread_mutex_lock (&mut2);
00030          alldone = true;
00031          pthread_cond_signal (&cond2);
00032          pthread_mutex_unlock (&mut2);
00033        }
00034 
00035       pthread_cond_wait (&cond1, &mut1);
00036     }
00037   while (! last_round);
00038 
00039   pthread_mutex_unlock (&mut1);
00040 
00041   return NULL;
00042 }
00043 
00044 
00045 int
00046 main (int argc, char *argv[])
00047 {
00048   int opt;
00049   int err;
00050   int nthreads = 10;
00051   int nrounds = 100;
00052   bool keeplock = false;
00053 
00054   while ((opt = getopt (argc, argv, "n:r:k")) != -1)
00055     switch (opt)
00056       {
00057       case 'n':
00058        nthreads = atol (optarg);
00059        break;
00060       case 'r':
00061        nrounds = atol (optarg);
00062        break;
00063       case 'k':
00064        keeplock = true;
00065        break;
00066       }
00067 
00068   ntogo = nthreads;
00069 
00070   pthread_t th[nthreads];
00071   int i;
00072   for (i = 0; __builtin_expect (i < nthreads, 1); ++i)
00073     if (__builtin_expect ((err = pthread_create (&th[i], NULL, cons, (void *) (long) i)) != 0, 0))
00074       printf ("pthread_create: %s\n", strerror (err));
00075 
00076   for (i = 0; __builtin_expect (i < nrounds, 1); ++i)
00077     {
00078       pthread_mutex_lock (&mut2);
00079       while (! alldone)
00080        pthread_cond_wait (&cond2, &mut2);
00081       pthread_mutex_unlock (&mut2);
00082 
00083       pthread_mutex_lock (&mut1);
00084       if (! keeplock)
00085        pthread_mutex_unlock (&mut1);
00086 
00087       ntogo = nthreads;
00088       alldone = false;
00089       if (i + 1 >= nrounds)
00090        last_round = true;
00091 
00092       pthread_cond_broadcast (&cond1);
00093 
00094       if (keeplock)
00095        pthread_mutex_unlock (&mut1);
00096     }
00097 
00098   for (i = 0; i < nthreads; ++i)
00099     if ((err = pthread_join (th[i], NULL)) != 0)
00100       printf ("pthread_create: %s\n", strerror (err));
00101 
00102   return 0;
00103 }