1 /* Copyright (C) 2015 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
18 /* This tests that with a reader-preferring rwlock, all readers are woken if
19 one reader "steals" lock ownership from a blocked writer. */
25 #include <semaphore.h>
28 /* If we strictly prefer writers over readers, a program must not expect
29 that, in the presence of concurrent writers, one reader will also acquire
30 the lock when another reader has already done so. Thus, use the
31 default rwlock type that does not strictly prefer writers. */
32 static pthread_rwlock_t r
= PTHREAD_RWLOCK_INITIALIZER
;
34 static pthread_mutex_t m
= PTHREAD_MUTEX_INITIALIZER
;
35 static pthread_cond_t cv
= PTHREAD_COND_INITIALIZER
;
37 /* Avoid using glibc-internal atomic operations. */
39 static int consumer_stop
= 0;
48 if (pthread_rwlock_wrlock (&r
) != 0)
50 puts ("wrlock failed");
53 if (pthread_rwlock_unlock (&r
) != 0)
55 puts ("unlock failed");
58 sem_getvalue (&stop
, &s
);
65 reader_producer (void *arg
)
71 if (pthread_rwlock_rdlock (&r
) != 0)
73 puts ("rdlock reader failed");
77 sem_getvalue (&stop
, &s
);
79 pthread_mutex_lock (&m
);
82 pthread_cond_signal (&cv
);
83 pthread_mutex_unlock (&m
);
85 if (pthread_rwlock_unlock (&r
) != 0)
87 puts ("unlock reader failed");
92 puts ("producer finished");
97 reader_consumer (void *arg
)
103 if (pthread_rwlock_rdlock (&r
) != 0)
105 puts ("rdlock reader failed");
109 pthread_mutex_lock (&m
);
112 pthread_cond_wait (&cv
, &m
);
113 pthread_mutex_unlock (&m
);
115 if (pthread_rwlock_unlock (&r
) != 0)
117 puts ("unlock reader failed");
122 puts ("consumer finished");
130 pthread_t w1
, w2
, rp
, rc
;
132 if (pthread_create (&w1
, NULL
, writer
, NULL
) != 0)
134 puts ("create failed");
137 if (pthread_create (&w2
, NULL
, writer
, NULL
) != 0)
139 puts ("create failed");
142 if (pthread_create (&rc
, NULL
, reader_consumer
, NULL
) != 0)
144 puts ("create failed");
147 if (pthread_create (&rp
, NULL
, reader_producer
, NULL
) != 0)
149 puts ("create failed");
156 if (pthread_join (w1
, NULL
) != 0)
158 puts ("w1 join failed");
161 if (pthread_join (w2
, NULL
) != 0)
163 puts ("w2 join failed");
166 if (pthread_join (rp
, NULL
) != 0)
168 puts ("reader_producer join failed");
171 if (pthread_join (rc
, NULL
) != 0)
173 puts ("reader_consumer join failed");
182 #define TEST_FUNCTION do_test ()
183 #include "../test-skeleton.c"