]>
Commit | Line | Data |
---|---|---|
33574c17 ST |
1 | /* Test rwlocks. |
2 | Copyright (C) 2000-2018 Free Software Foundation, Inc. | |
3 | This file is part of the GNU C Library. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Library General Public License as | |
7 | published by the Free Software Foundation; either version 2 of the | |
8 | License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Library General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Library General Public | |
16 | License along with the GNU C Library; see the file COPYING.LIB. If | |
17 | not, see <http://www.gnu.org/licenses/>. */ | |
18 | ||
19 | #define _GNU_SOURCE | |
20 | ||
21 | #include <pthread.h> | |
22 | #include <assert.h> | |
23 | #include <error.h> | |
24 | #include <errno.h> | |
25 | ||
26 | #define THREADS 1 | |
27 | ||
28 | int a; | |
29 | int b; | |
30 | ||
31 | /* Get a read lock and assert that a == b. */ | |
32 | void * | |
33 | test1 (void *arg) | |
34 | { | |
35 | error_t err; | |
36 | pthread_rwlock_t *lock = arg; | |
37 | int i; | |
38 | ||
39 | for (i = 0; i < 200; i++) | |
40 | { | |
41 | err = pthread_rwlock_rdlock (lock); | |
42 | assert (err == 0); | |
43 | ||
44 | assert (a == b); | |
45 | ||
46 | sched_yield (); | |
47 | ||
48 | assert (a == b); | |
49 | ||
50 | err = pthread_rwlock_unlock (lock); | |
51 | assert (err == 0); | |
52 | } | |
53 | ||
54 | return 0; | |
55 | } | |
56 | ||
57 | int | |
58 | main (int argc, char **argv) | |
59 | { | |
60 | error_t err; | |
61 | pthread_rwlockattr_t attr; | |
62 | pthread_rwlock_t lock; | |
63 | int pshared; | |
64 | ||
65 | int i; | |
66 | pthread_t tid[THREADS]; | |
67 | void *ret; | |
68 | ||
69 | err = pthread_rwlockattr_init (&attr); | |
70 | if (err) | |
71 | error (1, err, "pthread_rwlockattr_init"); | |
72 | ||
73 | err = pthread_rwlockattr_getpshared (&attr, &pshared); | |
74 | if (err) | |
75 | error (1, err, "pthread_rwlockattr_getpshared"); | |
76 | ||
77 | /* Assert the default state as mandated by POSIX. */ | |
78 | assert (pshared == PTHREAD_PROCESS_PRIVATE); | |
79 | ||
80 | err = pthread_rwlockattr_setpshared (&attr, pshared); | |
81 | if (err) | |
82 | error (1, err, "pthread_rwlockattr_setpshared"); | |
83 | ||
84 | err = pthread_rwlock_init (&lock, &attr); | |
85 | if (err) | |
86 | error (1, err, "pthread_rwlock_init"); | |
87 | ||
88 | err = pthread_rwlockattr_destroy (&attr); | |
89 | if (err) | |
90 | error (1, err, "pthread_rwlockattr_destroy"); | |
91 | ||
92 | /* Now test the lock. */ | |
93 | ||
94 | for (i = 0; i < THREADS; i++) | |
95 | { | |
96 | err = pthread_create (&tid[i], 0, test1, &lock); | |
97 | if (err) | |
98 | error (1, err, "pthread_create"); | |
99 | } | |
100 | ||
101 | for (i = 0; i < 10; i++) | |
102 | { | |
103 | sched_yield (); | |
104 | ||
105 | /* Get a write lock. */ | |
106 | pthread_rwlock_wrlock (&lock); | |
107 | /* Increment a and b giving other threads a chance to run in | |
108 | between. */ | |
109 | sched_yield (); | |
110 | a++; | |
111 | sched_yield (); | |
112 | b++; | |
113 | sched_yield (); | |
114 | /* Unlock. */ | |
115 | pthread_rwlock_unlock (&lock); | |
116 | } | |
117 | ||
118 | for (i = 0; i < THREADS; i++) | |
119 | { | |
120 | err = pthread_join (tid[i], &ret); | |
121 | if (err) | |
122 | error (1, err, "pthread_join"); | |
123 | } | |
124 | ||
125 | /* Read lock it. */ | |
126 | err = pthread_rwlock_tryrdlock (&lock); | |
127 | assert (err == 0); | |
128 | ||
129 | /* Try to write lock it. It should fail with EBUSY. */ | |
130 | err = pthread_rwlock_trywrlock (&lock); | |
131 | assert (err == EBUSY); | |
132 | ||
133 | /* Drop the read lock. */ | |
134 | err = pthread_rwlock_unlock (&lock); | |
135 | assert (err == 0); | |
136 | ||
137 | /* Get a write lock. */ | |
138 | err = pthread_rwlock_trywrlock (&lock); | |
139 | assert (err == 0); | |
140 | ||
141 | /* Fail trying to acquire another write lock. */ | |
142 | err = pthread_rwlock_trywrlock (&lock); | |
143 | assert (err == EBUSY); | |
144 | ||
145 | /* Try to get a read lock which should also fail. */ | |
146 | err = pthread_rwlock_tryrdlock (&lock); | |
147 | assert (err == EBUSY); | |
148 | ||
149 | /* Unlock it. */ | |
150 | err = pthread_rwlock_unlock (&lock); | |
151 | assert (err == 0); | |
152 | ||
153 | ||
154 | err = pthread_rwlock_destroy (&lock); | |
155 | if (err) | |
156 | error (1, err, "pthread_rwlock_destroy"); | |
157 | ||
158 | return 0; | |
159 | } |