42957f101413fc832e3ed05f40a37fff765cb166
[libc-test] / src / functional / pthread_robust.c
1 #include <pthread.h>
2 #include <string.h>
3 #include <errno.h>
4 #include "test.h"
5
6 #define TEST(r, f, m) ( \
7         ((r) = (f)) == 0 || (t_error("%s failed: %s (" m ")\n", #f, strerror(r)), 0) )
8 #define TESTX(r, f, x, m) ( \
9         ((r) = (f)) == (x) || (t_error("%s failed: got %d \"%s\" want %d \"%s\" (" m ")\n", #f, r, strerror(r), x, strerror(x)), 0) )
10
11 static void *start_lock(void *arg)
12 {
13         pthread_mutex_lock(arg);
14         return 0;
15 }
16
17 static void *start_wait(void *arg)
18 {
19         void **args = arg;
20         pthread_mutex_lock(args[1]);
21         pthread_barrier_wait(args[0]);
22         nanosleep(&(struct timespec){ .tv_nsec = 10000000 }, 0);
23         return 0;
24 }
25
26 int main(void)
27 {
28         pthread_t td;
29         int r;
30         void *res;
31         pthread_barrier_t barrier2;
32         pthread_mutexattr_t mtx_a;
33         pthread_mutex_t mtx;
34
35         TEST(r, pthread_barrier_init(&barrier2, 0, 2), "creating barrier");
36
37         /* Robust mutexes */
38         TEST(r, pthread_mutexattr_init(&mtx_a), "initializing mutex attr");
39         TEST(r, pthread_mutexattr_setrobust(&mtx_a, PTHREAD_MUTEX_ROBUST), "setting robust attribute");
40         TEST(r, pthread_mutex_init(&mtx, &mtx_a), "initializing robust mutex");
41         TEST(r, pthread_mutex_lock(&mtx), "locking robust mutex");
42         TEST(r, pthread_mutex_unlock(&mtx), "unlocking robust mutex");
43         TEST(r, pthread_create(&td, 0, start_lock, &mtx), "failed to create thread");
44         TEST(r, pthread_join(td, &res), "joining thread");
45         TESTX(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "locking orphaned robust mutex");
46         TEST(r, pthread_mutex_unlock(&mtx), "unlocking orphaned robust mutex");
47         TESTX(r, pthread_mutex_lock(&mtx), ENOTRECOVERABLE, "re-locking orphaned robust mutex");
48         TEST(r, pthread_mutex_destroy(&mtx), "destroying unrecoverable mutex");
49
50         TEST(r, pthread_mutex_init(&mtx, &mtx_a), "initializing robust mutex");
51         TEST(r, pthread_create(&td, 0, start_lock, &mtx), "failed to create thread");
52         TEST(r, pthread_join(td, &res), "joining thread");
53         TESTX(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "locking orphaned robust mutex");
54         TEST(r, pthread_mutex_consistent(&mtx), "");
55         TEST(r, pthread_mutex_unlock(&mtx), "unlocking orphaned robust mutex");
56         TEST(r, pthread_mutex_lock(&mtx), "re-locking orphaned robust mutex");
57         TEST(r, pthread_mutex_destroy(&mtx), "destroying mutex");
58
59         TEST(r, pthread_mutex_init(&mtx, &mtx_a), "");
60         TEST(r, pthread_create(&td, 0, start_wait, (void *[]){ &barrier2, &mtx }), "");
61         r = pthread_barrier_wait(&barrier2);
62         if (r && r != PTHREAD_BARRIER_SERIAL_THREAD)
63                 t_error("pthread_barrier_wait failed: got %d \"%s\", wanted either 0 or %d\n",
64                         r, strerror(r), PTHREAD_BARRIER_SERIAL_THREAD);
65         TESTX(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "");
66         TEST(r, pthread_join(td, &res), "");
67         TEST(r, pthread_mutex_consistent(&mtx), "");
68         TEST(r, pthread_mutex_unlock(&mtx), "");
69         TEST(r, pthread_mutex_destroy(&mtx), "");
70
71         return t_status;
72 }