Back to index

glibc  2.9
tst-robust1.c
Go to the documentation of this file.
00001 /* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
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 m1;
00027 static pthread_mutex_t m2;
00028 static pthread_barrier_t b;
00029 
00030 
00031 #ifndef LOCK
00032 # define LOCK(m) pthread_mutex_lock (m)
00033 #endif
00034 
00035 
00036 static void *
00037 tf (void *arg)
00038 {
00039   long int round = (long int) arg;
00040 
00041   if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0)
00042     {
00043       printf ("%ld: setcancelstate failed\n", round);
00044       exit (1);
00045     }
00046 
00047   int e = LOCK (&m1);
00048   if (e != 0)
00049     {
00050       printf ("%ld: child: mutex_lock m1 failed with error %d\n", round, e);
00051       exit (1);
00052     }
00053 
00054   e = LOCK (&m2);
00055   if (e != 0)
00056     {
00057       printf ("%ld: child: mutex_lock m2 failed with error %d\n", round, e);
00058       exit (1);
00059     }
00060 
00061   e = pthread_barrier_wait (&b);
00062   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00063     {
00064       printf ("%ld: child: 1st barrier_wait failed\n", round);
00065       exit (1);
00066     }
00067 
00068   e = pthread_barrier_wait (&b);
00069   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00070     {
00071       printf ("%ld: child: 2nd barrier_wait failed\n", round);
00072       exit (1);
00073     }
00074 
00075   pthread_testcancel ();
00076 
00077   printf ("%ld: testcancel returned\n", round);
00078   exit (1);
00079 }
00080 
00081 
00082 static int
00083 do_test (void)
00084 {
00085 #ifdef PREPARE_TMO
00086   PREPARE_TMO;
00087 #endif
00088 
00089   pthread_mutexattr_t a;
00090   if (pthread_mutexattr_init (&a) != 0)
00091     {
00092       puts ("mutexattr_init failed");
00093       return 1;
00094     }
00095   if (pthread_mutexattr_setrobust_np (&a, PTHREAD_MUTEX_ROBUST_NP) != 0)
00096     {
00097       puts ("mutexattr_setrobust failed");
00098       return 1;
00099     }
00100 
00101 #ifdef ENABLE_PI
00102   if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
00103     {
00104       puts ("pthread_mutexattr_setprotocol failed");
00105       return 1;
00106     }
00107   else
00108     {
00109       int e = pthread_mutex_init (&m1, &a);
00110       if (e == ENOTSUP)
00111        {
00112          puts ("PI robust mutexes not supported");
00113          return 0;
00114        }
00115       else if (e != 0)
00116        {
00117          puts ("mutex_init m1 failed");
00118          return 1;
00119        }
00120       pthread_mutex_destroy (&m1);
00121     }
00122 #endif
00123 
00124 #ifndef NOT_CONSISTENT
00125   if (pthread_mutex_init (&m1, &a) != 0)
00126     {
00127       puts ("mutex_init m1 failed");
00128       return 1;
00129     }
00130 
00131   if (pthread_mutex_init (&m2, &a) != 0)
00132     {
00133       puts ("mutex_init m2 failed");
00134       return 1;
00135     }
00136 #endif
00137 
00138   if (pthread_barrier_init (&b, NULL, 2) != 0)
00139     {
00140       puts ("barrier_init failed");
00141       return 1;
00142     }
00143 
00144   for (long int round = 1; round < 5; ++round)
00145     {
00146 #ifdef NOT_CONSISTENT
00147       if (pthread_mutex_init (&m1 , &a) != 0)
00148        {
00149          puts ("mutex_init m1 failed");
00150          return 1;
00151        }
00152       if (pthread_mutex_init (&m2 , &a) != 0)
00153        {
00154          puts ("mutex_init m2 failed");
00155          return 1;
00156        }
00157 #endif
00158 
00159       pthread_t th;
00160       if (pthread_create (&th, NULL, tf, (void *) round) != 0)
00161        {
00162          printf ("%ld: create failed\n", round);
00163          return 1;
00164        }
00165 
00166       int e = pthread_barrier_wait (&b);
00167       if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00168        {
00169          printf ("%ld: parent: 1st barrier_wait failed\n", round);
00170          return 1;
00171        }
00172 
00173       if (pthread_cancel (th) != 0)
00174        {
00175          printf ("%ld: cancel failed\n", round);
00176          return 1;
00177        }
00178 
00179       e = pthread_barrier_wait (&b);
00180       if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00181        {
00182          printf ("%ld: parent: 2nd barrier_wait failed\n", round);
00183          return 1;
00184        }
00185 
00186 #ifndef AFTER_JOIN
00187       if (round & 1)
00188 #endif
00189        {
00190          void *res;
00191          if (pthread_join (th, &res) != 0)
00192            {
00193              printf ("%ld: join failed\n", round);
00194              return 1;
00195            }
00196          if (res != PTHREAD_CANCELED)
00197            {
00198              printf ("%ld: thread not canceled\n", round);
00199              return 1;
00200            }
00201        }
00202 
00203       e = LOCK (&m1);
00204       if (e == 0)
00205        {
00206          printf ("%ld: parent: mutex_lock m1 succeeded\n", round);
00207          return 1;
00208        }
00209       if (e != EOWNERDEAD)
00210        {
00211          printf ("%ld: parent: mutex_lock m1 returned wrong code\n", round);
00212          return 1;
00213        }
00214 
00215       e = LOCK (&m2);
00216       if (e == 0)
00217        {
00218          printf ("%ld: parent: mutex_lock m2 succeeded\n", round);
00219          return 1;
00220        }
00221       if (e != EOWNERDEAD)
00222        {
00223          printf ("%ld: parent: mutex_lock m2 returned wrong code\n", round);
00224          return 1;
00225        }
00226 
00227 #ifndef AFTER_JOIN
00228       if ((round & 1) == 0)
00229        {
00230          void *res;
00231          if (pthread_join (th, &res) != 0)
00232            {
00233              printf ("%ld: join failed\n", round);
00234              return 1;
00235            }
00236          if (res != PTHREAD_CANCELED)
00237            {
00238              printf ("%ld: thread not canceled\n", round);
00239              return 1;
00240            }
00241        }
00242 #endif
00243 
00244 #ifndef NOT_CONSISTENT
00245       e = pthread_mutex_consistent_np (&m1);
00246       if (e != 0)
00247        {
00248          printf ("%ld: mutex_consistent m1 failed with error %d\n", round, e);
00249          return 1;
00250        }
00251 
00252       e = pthread_mutex_consistent_np (&m2);
00253       if (e != 0)
00254        {
00255          printf ("%ld: mutex_consistent m2 failed with error %d\n", round, e);
00256          return 1;
00257        }
00258 #endif
00259 
00260       e = pthread_mutex_unlock (&m1);
00261       if (e != 0)
00262        {
00263          printf ("%ld: mutex_unlock m1 failed with %d\n", round, e);
00264          return 1;
00265        }
00266 
00267       e = pthread_mutex_unlock (&m2);
00268       if (e != 0)
00269        {
00270          printf ("%ld: mutex_unlock m2 failed with %d\n", round, e);
00271          return 1;
00272        }
00273 
00274 #ifdef NOT_CONSISTENT
00275       e = LOCK (&m1);
00276       if (e == 0)
00277        {
00278          printf ("%ld: locking inconsistent mutex m1 succeeded\n", round);
00279          return 1;
00280        }
00281       if (e != ENOTRECOVERABLE)
00282        {
00283          printf ("%ld: locking inconsistent mutex m1 failed with error %d\n",
00284                 round, e);
00285          return 1;
00286        }
00287 
00288       if (pthread_mutex_destroy (&m1) != 0)
00289        {
00290          puts ("mutex_destroy m1 failed");
00291          return 1;
00292        }
00293 
00294       e = LOCK (&m2);
00295       if (e == 0)
00296        {
00297          printf ("%ld: locking inconsistent mutex m2 succeeded\n", round);
00298          return 1;
00299        }
00300       if (e != ENOTRECOVERABLE)
00301        {
00302          printf ("%ld: locking inconsistent mutex m2 failed with error %d\n",
00303                 round, e);
00304          return 1;
00305        }
00306 
00307       if (pthread_mutex_destroy (&m2) != 0)
00308        {
00309          puts ("mutex_destroy m2 failed");
00310          return 1;
00311        }
00312 #endif
00313     }
00314 
00315 #ifndef NOT_CONSISTENT
00316   if (pthread_mutex_destroy (&m1) != 0)
00317     {
00318       puts ("mutex_destroy m1 failed");
00319       return 1;
00320     }
00321 
00322   if (pthread_mutex_destroy (&m2) != 0)
00323     {
00324       puts ("mutex_destroy m2 failed");
00325       return 1;
00326     }
00327 #endif
00328 
00329   if (pthread_mutexattr_destroy (&a) != 0)
00330     {
00331       puts ("mutexattr_destroy failed");
00332       return 1;
00333     }
00334 
00335   return 0;
00336 }
00337 
00338 #define TEST_FUNCTION do_test ()
00339 #include "../test-skeleton.c"