Back to index

glibc  2.9
tst-mutex2.c
Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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 <errno.h>
00021 #include <pthread.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 
00025 
00026 static pthread_mutex_t m;
00027 static pthread_barrier_t b;
00028 
00029 
00030 static void *
00031 tf (void *arg)
00032 {
00033   int e = pthread_mutex_unlock (&m);
00034   if (e == 0)
00035     {
00036       puts ("child: 1st mutex_unlock succeeded");
00037       exit (1);
00038     }
00039   else if (e != EPERM)
00040     {
00041       puts ("child: 1st mutex_unlock error != EPERM");
00042       exit (1);
00043     }
00044 
00045   e = pthread_mutex_trylock (&m);
00046   if (e == 0)
00047     {
00048       puts ("child: 1st trylock suceeded");
00049       exit (1);
00050     }
00051   if (e != EBUSY)
00052     {
00053       puts ("child: 1st trylock didn't return EBUSY");
00054       exit (1);
00055     }
00056 
00057   e = pthread_barrier_wait (&b);
00058   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00059     {
00060       puts ("child: 1st barrier_wait failed");
00061       exit (1);
00062     }
00063 
00064   e = pthread_barrier_wait (&b);
00065   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00066     {
00067       puts ("child: 2nd barrier_wait failed");
00068       exit (1);
00069     }
00070 
00071   e = pthread_mutex_unlock (&m);
00072   if (e == 0)
00073     {
00074       puts ("child: 2nd mutex_unlock succeeded");
00075       exit (1);
00076     }
00077   else if (e != EPERM)
00078     {
00079       puts ("child: 2nd mutex_unlock error != EPERM");
00080       exit (1);
00081     }
00082 
00083   if (pthread_mutex_trylock (&m) != 0)
00084     {
00085       puts ("child: 2nd trylock failed");
00086       exit (1);
00087     }
00088 
00089   if (pthread_mutex_unlock (&m) != 0)
00090     {
00091       puts ("child: 3rd mutex_unlock failed");
00092       exit (1);
00093     }
00094 
00095   return NULL;
00096 }
00097 
00098 
00099 static int
00100 do_test (void)
00101 {
00102   pthread_mutexattr_t a;
00103   int e;
00104 
00105   if (pthread_mutexattr_init (&a) != 0)
00106     {
00107       puts ("mutexattr_init failed");
00108       return 1;
00109     }
00110 
00111   if (pthread_mutexattr_settype (&a, PTHREAD_MUTEX_ERRORCHECK) != 0)
00112     {
00113       puts ("mutexattr_settype failed");
00114       return 1;
00115     }
00116 
00117 #ifdef ENABLE_PI
00118   if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
00119     {
00120       puts ("pthread_mutexattr_setprotocol failed");
00121       return 1;
00122     }
00123 #endif
00124 
00125   e = pthread_mutex_init (&m, &a);
00126   if (e != 0)
00127     {
00128 #ifdef ENABLE_PI
00129       if (e == ENOTSUP)
00130        {
00131          puts ("PI mutexes unsupported");
00132          return 0;
00133        }
00134 #endif
00135       puts ("mutex_init failed");
00136       return 1;
00137     }
00138 
00139   if (pthread_barrier_init (&b, NULL, 2) != 0)
00140     {
00141       puts ("barrier_init failed");
00142       return 1;
00143     }
00144 
00145   e = pthread_mutex_unlock (&m);
00146   if (e == 0)
00147     {
00148       puts ("1st mutex_unlock succeeded");
00149       return 1;
00150     }
00151   else if (e != EPERM)
00152     {
00153       puts ("1st mutex_unlock error != EPERM");
00154       return 1;
00155     }
00156 
00157   if (pthread_mutex_lock (&m) != 0)
00158     {
00159       puts ("mutex_lock failed");
00160       return 1;
00161     }
00162 
00163   e = pthread_mutex_lock (&m);
00164   if (e == 0)
00165     {
00166       puts ("2nd mutex_lock succeeded");
00167       return 1;
00168     }
00169   else if (e != EDEADLK)
00170     {
00171       puts ("2nd mutex_lock error != EDEADLK");
00172       return 1;
00173     }
00174 
00175   pthread_t th;
00176   if (pthread_create (&th, NULL, tf, NULL) != 0)
00177     {
00178       puts ("create failed");
00179       return 1;
00180     }
00181 
00182   e = pthread_barrier_wait (&b);
00183   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00184     {
00185       puts ("1st barrier_wait failed");
00186       return 1;
00187     }
00188 
00189   if (pthread_mutex_unlock (&m) != 0)
00190     {
00191       puts ("2nd mutex_unlock failed");
00192       return 1;
00193     }
00194 
00195   e = pthread_mutex_unlock (&m);
00196   if (e == 0)
00197     {
00198       puts ("3rd mutex_unlock succeeded");
00199       return 1;
00200     }
00201   else if (e != EPERM)
00202     {
00203       puts ("3rd mutex_unlock error != EPERM");
00204       return 1;
00205     }
00206 
00207   e = pthread_barrier_wait (&b);
00208   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00209     {
00210       puts ("2nd barrier_wait failed");
00211       return 1;
00212     }
00213 
00214   if (pthread_join (th, NULL) != 0)
00215     {
00216       puts ("join failed");
00217       return 1;
00218     }
00219 
00220   if (pthread_mutex_destroy (&m) != 0)
00221     {
00222       puts ("mutex_destroy failed");
00223       return 1;
00224     }
00225 
00226   if (pthread_barrier_destroy (&b) != 0)
00227     {
00228       puts ("barrier_destroy failed");
00229       return 1;
00230     }
00231 
00232   if (pthread_mutexattr_destroy (&a) != 0)
00233     {
00234       puts ("mutexattr_destroy failed");
00235       return 1;
00236     }
00237 
00238   return 0;
00239 }
00240 
00241 #define TEST_FUNCTION do_test ()
00242 #include "../test-skeleton.c"