Back to index

glibc  2.9
tst-cond20.c
Go to the documentation of this file.
00001 /* Copyright (C) 2004 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <pthread.h>
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <unistd.h>
00025 
00026 #define N 10
00027 #define ROUNDS 1000
00028 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
00029 static pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
00030 static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
00031 static pthread_barrier_t b;
00032 static int count;
00033 
00034 static void *
00035 tf (void *p)
00036 {
00037   int i;
00038   for (i = 0; i < ROUNDS; ++i)
00039     {
00040       pthread_mutex_lock (&mut);
00041 
00042       if (++count == N)
00043        pthread_cond_signal (&cond2);
00044 
00045 #ifdef TIMED
00046       struct timeval tv;
00047       gettimeofday (&tv, NULL);
00048       struct timespec ts;
00049       /* Wait three seconds.  */
00050       ts.tv_sec = tv.tv_sec + 3;
00051       ts.tv_nsec = tv.tv_usec * 1000;
00052       pthread_cond_timedwait (&cond, &mut, &ts);
00053 #else
00054       pthread_cond_wait (&cond, &mut);
00055 #endif
00056 
00057       pthread_mutex_unlock (&mut);
00058 
00059       int err = pthread_barrier_wait (&b);
00060       if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
00061        {
00062          puts ("child: barrier_wait failed");
00063          exit (1);
00064        }
00065 
00066       err = pthread_barrier_wait (&b);
00067       if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
00068        {
00069          puts ("child: barrier_wait failed");
00070          exit (1);
00071        }
00072     }
00073 
00074   return NULL;
00075 }
00076 
00077 
00078 static int
00079 do_test (void)
00080 {
00081   if (pthread_barrier_init (&b, NULL, N + 1) != 0)
00082     {
00083       puts ("barrier_init failed");
00084       return 1;
00085     }
00086 
00087   pthread_mutex_lock (&mut);
00088 
00089   int i, j, err;
00090   pthread_t th[N];
00091   for (i = 0; i < N; ++i)
00092     if ((err = pthread_create (&th[i], NULL, tf, NULL)) != 0)
00093       {
00094        printf ("cannot create thread %d: %s\n", i, strerror (err));
00095        return 1;
00096       }
00097 
00098   for (i = 0; i < ROUNDS; ++i)
00099     {
00100       pthread_cond_wait (&cond2, &mut);
00101 
00102       if (i & 1)
00103         pthread_mutex_unlock (&mut);
00104 
00105       if (i & 2)
00106        pthread_cond_broadcast (&cond);
00107       else if (i & 4)
00108        for (j = 0; j < N; ++j)
00109          pthread_cond_signal (&cond);
00110       else
00111        {
00112          for (j = 0; j < (i / 8) % N; ++j)
00113            pthread_cond_signal (&cond);
00114          pthread_cond_broadcast (&cond);
00115        }
00116 
00117       if ((i & 1) == 0)
00118         pthread_mutex_unlock (&mut);
00119 
00120       err = pthread_cond_destroy (&cond);
00121       if (err)
00122        {
00123          printf ("pthread_cond_destroy failed: %s\n", strerror (err));
00124          return 1;
00125        }
00126 
00127       /* Now clobber the cond variable which has been successfully
00128          destroyed above.  */
00129       memset (&cond, (char) i, sizeof (cond));
00130 
00131       err = pthread_barrier_wait (&b);
00132       if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
00133        {
00134          puts ("parent: barrier_wait failed");
00135          return 1;
00136        }
00137 
00138       pthread_mutex_lock (&mut);
00139 
00140       err = pthread_barrier_wait (&b);
00141       if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
00142        {
00143          puts ("parent: barrier_wait failed");
00144          return 1;
00145        }
00146 
00147       count = 0;
00148       err = pthread_cond_init (&cond, NULL);
00149       if (err)
00150        {
00151          printf ("pthread_cond_init failed: %s\n", strerror (err));
00152          return 1;
00153        }
00154     }
00155 
00156   for (i = 0; i < N; ++i)
00157     if ((err = pthread_join (th[i], NULL)) != 0)
00158       {
00159        printf ("failed to join thread %d: %s\n", i, strerror (err));
00160        return 1;
00161       }
00162 
00163   puts ("done");
00164 
00165   return 0;
00166 }
00167 
00168 
00169 #define TEST_FUNCTION do_test ()
00170 #include "../test-skeleton.c"