Back to index

glibc  2.9
tst-cond10.c
Go to the documentation of this file.
00001 /* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
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 <error.h>
00021 #include <pthread.h>
00022 #include <stdbool.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 
00026 
00027 #define N 10
00028 #define ROUNDS 100
00029 
00030 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
00031 static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
00032 static pthread_barrier_t bN1;
00033 static pthread_barrier_t b2;
00034 
00035 
00036 static void *
00037 tf (void *p)
00038 {
00039   if (pthread_mutex_lock (&mut) != 0)
00040     {
00041       puts ("child: 1st mutex_lock failed");
00042       exit (1);
00043     }
00044 
00045   int e = pthread_barrier_wait (&b2);
00046   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00047     {
00048       puts ("child: 1st barrier_wait failed");
00049       exit (1);
00050     }
00051 
00052   if (pthread_cond_wait (&cond, &mut) != 0)
00053     {
00054       puts ("child: cond_wait failed");
00055       exit (1);
00056     }
00057 
00058   if (pthread_mutex_unlock (&mut) != 0)
00059     {
00060       puts ("child: mutex_unlock failed");
00061       exit (1);
00062     }
00063 
00064   e = pthread_barrier_wait (&bN1);
00065   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00066     {
00067       puts ("child: 2nd barrier_wait failed");
00068       exit (1);
00069     }
00070 
00071   return NULL;
00072 }
00073 
00074 
00075 static int
00076 do_test (void)
00077 {
00078   if (pthread_barrier_init (&bN1, NULL, N + 1) != 0)
00079     {
00080       puts ("barrier_init failed");
00081       exit (1);
00082     }
00083 
00084   if (pthread_barrier_init (&b2, NULL, 2) != 0)
00085     {
00086       puts ("barrier_init failed");
00087       exit (1);
00088     }
00089 
00090   pthread_attr_t at;
00091 
00092   if (pthread_attr_init (&at) != 0)
00093     {
00094       puts ("attr_init failed");
00095       return 1;
00096     }
00097 
00098   if (pthread_attr_setstacksize (&at, 1 * 1024 * 1024) != 0)
00099     {
00100       puts ("attr_setstacksize failed");
00101       return 1;
00102     }
00103 
00104   int r;
00105   for (r = 0; r < ROUNDS; ++r)
00106     {
00107       printf ("round %d\n", r + 1);
00108 
00109       int i;
00110       pthread_t th[N];
00111       for (i = 0; i < N; ++i)
00112        {
00113          if (pthread_create (&th[i], &at, tf, NULL) != 0)
00114            {
00115              puts ("create failed");
00116              exit (1);
00117            }
00118 
00119          int e = pthread_barrier_wait (&b2);
00120          if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00121            {
00122              puts ("parent: 1st barrier_wait failed");
00123              exit (1);
00124            }
00125        }
00126 
00127       if (pthread_mutex_lock (&mut) != 0)
00128        {
00129          puts ("parent: mutex_lock failed");
00130          exit (1);
00131        }
00132       if (pthread_mutex_unlock (&mut) != 0)
00133        {
00134          puts ("parent: mutex_unlock failed");
00135          exit (1);
00136        }
00137 
00138       /* N single signal calls.  Without locking.  This tests that no
00139         signal gets lost.  */
00140       for (i = 0; i < N; ++i)
00141        if (pthread_cond_signal (&cond) != 0)
00142          {
00143            puts ("cond_signal failed");
00144            exit (1);
00145          }
00146 
00147       int e = pthread_barrier_wait (&bN1);
00148       if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00149        {
00150          puts ("parent: 2nd barrier_wait failed");
00151          exit (1);
00152        }
00153 
00154       for (i = 0; i < N; ++i)
00155        if (pthread_join (th[i], NULL) != 0)
00156          {
00157            puts ("join failed");
00158            exit (1);
00159          }
00160     }
00161 
00162   if (pthread_attr_destroy (&at) != 0)
00163     {
00164       puts ("attr_destroy failed");
00165       return 1;
00166     }
00167 
00168   return 0;
00169 }
00170 
00171 
00172 #define TEST_FUNCTION do_test ()
00173 #include "../test-skeleton.c"