Back to index

glibc  2.9
ecmutex.c
Go to the documentation of this file.
00001 /* Test of the error checking mutex and incidently also barriers.  */
00002 
00003 #include <errno.h>
00004 #include <pthread.h>
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 
00008 
00009 static pthread_mutex_t locks[] =
00010 {
00011   PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP,
00012   PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP,
00013   PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP,
00014   PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP,
00015   PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
00016 };
00017 #define nlocks ((int) (sizeof (locks) / sizeof (locks[0])))
00018 
00019 static pthread_barrier_t barrier;
00020 #define SYNC pthread_barrier_wait (&barrier)
00021 
00022 #define NTHREADS nlocks
00023 
00024 #define ROUNDS 20
00025 
00026 
00027 static void *
00028 worker (void *arg)
00029 {
00030   /* We are locking the and unlocked the locks and check the errors.
00031      Since we are using the error-checking variant the implementation
00032      should report them.  */
00033   int nr = (long int) arg;
00034   int i;
00035   void *result = NULL;
00036   int retval;
00037 
00038   for (i = 0; i < ROUNDS; ++i)
00039     {
00040       /* Skip the rounds which would make other == own.  */
00041       if (i % nlocks == 0)
00042        continue;
00043 
00044       /* Get the "own" mutex.  */
00045       if (pthread_mutex_trylock (&locks[nr]) != 0)
00046        {
00047          printf ("thread %d failed getting own mutex\n", nr);
00048          result = (void *) 1;
00049        }
00050 
00051       /* Try locking "own" mutex again.  */
00052       retval = pthread_mutex_lock (&locks[nr]);
00053       if (retval != EDEADLK)
00054        {
00055          printf ("thread %d failed getting own mutex\n", nr);
00056          result = (void *) 1;
00057        }
00058 
00059       /* Try to get a different semaphore.  */
00060       SYNC;
00061       retval = pthread_mutex_trylock (&locks[(nr + i) % nlocks]);
00062       if (retval != EBUSY)
00063        {
00064          printf ("thread %d didn't deadlock on getting %d's lock\n",
00065                 nr, (nr + i) % nlocks);
00066          result = (void *) 1;
00067        }
00068 
00069       /* Try unlocking other's lock.  */
00070       retval = pthread_mutex_unlock (&locks[(nr + i) % nlocks]);
00071       if (retval != EPERM)
00072        {
00073          printf ("thread %d managed releasing mutex %d\n",
00074                 nr, (nr + i) % nlocks);
00075          result = (void *) 1;
00076        }
00077 
00078       /* All lock one mutex now.  */
00079       SYNC;
00080       retval = pthread_mutex_lock (&locks[i % nlocks]);
00081       if (nr == (i % nlocks))
00082        {
00083          if (retval != EDEADLK)
00084            {
00085              printf ("thread %d didn't deadlock on getting %d's lock\n",
00086                     nr, (nr + i) % nlocks);
00087              result = (void *) 1;
00088            }
00089          if (pthread_mutex_unlock (&locks[i % nlocks]) != 0)
00090            {
00091              printf ("thread %d failed releasing own mutex\n", nr);
00092              result = (void *) 1;
00093            }
00094        }
00095       else
00096        {
00097          if (retval != 0)
00098            {
00099              printf ("thread %d failed acquiring mutex %d\n",
00100                     nr, i % nlocks);
00101              result = (void *) 1;
00102            }
00103          else if (pthread_mutex_unlock (&locks[i % nlocks]) != 0)
00104            {
00105              printf ("thread %d failed releasing mutex %d\n",
00106                     nr, i % nlocks);
00107              result = (void *) 1;
00108            }
00109        }
00110 
00111       /* Unlock the own lock.  */
00112       SYNC;
00113       if (nr != (i % nlocks) && pthread_mutex_unlock (&locks[nr]) != 0)
00114        {
00115          printf ("thread %d failed releasing own mutex\n", nr);
00116          result = (void *) 1;
00117        }
00118 
00119       /* Try unlocking again.  */
00120       retval = pthread_mutex_unlock (&locks[nr]);
00121       if (retval == 0)
00122        {
00123          printf ("thread %d managed releasing own mutex twice\n", nr);
00124          result = (void *) 1;
00125        }
00126     }
00127 
00128   return result;
00129 }
00130 
00131 
00132 #define TEST_FUNCTION do_test ()
00133 static int
00134 do_test (void)
00135 {
00136   pthread_t threads[NTHREADS];
00137   int i;
00138   void *res;
00139   int result = 0;
00140 
00141   pthread_barrier_init (&barrier, NULL, NTHREADS);
00142 
00143   for (i = 0; i < NTHREADS; ++i)
00144     if (pthread_create (&threads[i], NULL, worker, (void *) (long int) i) != 0)
00145       {
00146        printf ("failed to create thread %d: %m\n", i);
00147        exit (1);
00148       }
00149 
00150   for (i = 0; i < NTHREADS; ++i)
00151     if (pthread_join (threads[i], &res) != 0 || res != NULL)
00152       result = 1;
00153 
00154   return result;
00155 }
00156 
00157 #include "../test-skeleton.c"