Update.
[glibc.git] / linuxthreads / ecmutex.c
blobce54ddf3319845249f69d7ea110e3b395b063614
1 /* Test of the error checking mutex and incidently also barriers. */
3 #include <errno.h>
4 #include <pthread.h>
5 #include <stdio.h>
6 #include <stdlib.h>
9 static pthread_mutex_t locks[] =
11 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP,
12 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP,
13 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP,
14 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP,
15 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
17 #define nlocks ((int) (sizeof (locks) / sizeof (locks[0])))
19 static pthread_barrier_t barrier;
20 #define SYNC pthread_barrier_wait (&barrier)
22 #define NTHREADS nlocks
24 #define ROUNDS 20
27 static void *
28 worker (void *arg)
30 /* We are locking the and unlocked the locks and check the errors.
31 Since we are using the error-checking variant the implementation
32 should report them. */
33 int nr = (long int) arg;
34 int i;
35 void *result = NULL;
36 int retval;
38 for (i = 0; i < ROUNDS; ++i)
40 /* Skip the rounds which would make other == own. */
41 if (i % nlocks == 0)
42 continue;
44 /* Get the "own" mutex. */
45 if (pthread_mutex_trylock (&locks[nr]) != 0)
47 printf ("thread %d failed getting own mutex\n", nr);
48 result = (void *) 1;
51 /* Try locking "own" mutex again. */
52 retval = pthread_mutex_lock (&locks[nr]);
53 if (retval != EDEADLK)
55 printf ("thread %d failed getting own mutex\n", nr);
56 result = (void *) 1;
59 /* Try to get a different semaphore. */
60 SYNC;
61 retval = pthread_mutex_trylock (&locks[(nr + i) % nlocks]);
62 if (retval != EBUSY)
64 printf ("thread %d didn't deadlock on getting %d's lock\n",
65 nr, (nr + i) % nlocks);
66 result = (void *) 1;
69 /* Try unlocking other's lock. */
70 retval = pthread_mutex_unlock (&locks[(nr + i) % nlocks]);
71 if (retval != EPERM)
73 printf ("thread %d managed releasing mutex %d\n",
74 nr, (nr + i) % nlocks);
75 result = (void *) 1;
78 /* All lock one mutex now. */
79 SYNC;
80 retval = pthread_mutex_lock (&locks[i % nlocks]);
81 if (nr == (i % nlocks))
83 if (retval != EDEADLK)
85 printf ("thread %d didn't deadlock on getting %d's lock\n",
86 nr, (nr + i) % nlocks);
87 result = (void *) 1;
89 if (pthread_mutex_unlock (&locks[i % nlocks]) != 0)
91 printf ("thread %d failed releasing own mutex\n", nr);
92 result = (void *) 1;
95 else
97 if (retval != 0)
99 printf ("thread %d failed acquiring mutex %d\n",
100 nr, i % nlocks);
101 result = (void *) 1;
103 else if (pthread_mutex_unlock (&locks[i % nlocks]) != 0)
105 printf ("thread %d failed releasing mutex %d\n",
106 nr, i % nlocks);
107 result = (void *) 1;
111 /* Unlock the own lock. */
112 SYNC;
113 if (nr != (i % nlocks) && pthread_mutex_unlock (&locks[nr]) != 0)
115 printf ("thread %d failed releasing own mutex\n", nr);
116 result = (void *) 1;
119 /* Try unlocking again. */
120 retval = pthread_mutex_unlock (&locks[nr]);
121 if (retval == 0)
123 printf ("thread %d managed releasing own mutex twice\n", nr);
124 result = (void *) 1;
128 return result;
132 #define TEST_FUNCTION do_test ()
133 static int
134 do_test (void)
136 pthread_t threads[NTHREADS];
137 int i;
138 void *res;
139 int result = 0;
141 pthread_barrier_init (&barrier, NULL, NTHREADS);
143 for (i = 0; i < NTHREADS; ++i)
144 if (pthread_create (&threads[i], NULL, worker, (void *) (long int) i) != 0)
146 printf ("failed to create thread %d: %m\n", i);
147 exit (1);
150 for (i = 0; i < NTHREADS; ++i)
151 if (pthread_join (threads[i], &res) != 0 || res != NULL)
152 result = 1;
154 return result;
157 #include "../test-skeleton.c"