Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: tests/threads/rwlock_test.c

Issue 623863002: Implement pthread_rwlock functions for NaCl newlib. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: spellcheck Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/untrusted/pthread/pthread.h ('K') | « tests/threads/nacl.scons ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2014 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 #include <errno.h>
8 #include <pthread.h>
9 #include <stdio.h>
10 #include <time.h>
11
12 #include "native_client/src/include/nacl_assert.h"
13
14 static pthread_rwlock_t rwlock;
15 volatile int thread_has_lock = 0;
16 volatile int thread_should_acquire_lock = 0;
17 volatile int thread_should_release_lock = 0;
18
19 #define READ_LOCK 1
Mark Seaborn 2014/12/01 22:33:07 Nit: use an enum?
Sam Clegg 2014/12/10 19:17:43 Done.
20 #define WRITE_LOCK 2
21
22 void *locking_thread(void *unused) {
23 int rc;
24 for (;;) {
25 while (!thread_should_acquire_lock) { /* Spin. */ }
26
27 ASSERT_EQ(thread_has_lock, 0);
28 if (thread_should_acquire_lock == WRITE_LOCK)
29 rc = pthread_rwlock_wrlock(&rwlock);
30 else
31 rc = pthread_rwlock_rdlock(&rwlock);
32 ASSERT_EQ(rc, 0);
33 __sync_fetch_and_add(&thread_has_lock, 1);
34
35 while (!thread_should_release_lock) { /* Spin. */ }
36
37 ASSERT_EQ(thread_has_lock, 1);
38 rc = pthread_rwlock_unlock(&rwlock);
39 ASSERT_EQ(rc, 0);
40 __sync_fetch_and_sub(&thread_has_lock, 1);
41 }
42
43 return NULL;
44 }
45
46
47 void tell_thread_to_acquire_lock(int lock_type) {
48 fprintf(stderr, "Thread acquiring lock: %s\n",
49 lock_type == WRITE_LOCK ? "WRITE" : "READ" );
50
51 ASSERT_EQ(thread_has_lock, 0);
52 ASSERT_EQ(thread_should_acquire_lock, 0);
53 __sync_fetch_and_add(&thread_should_acquire_lock, lock_type);
54
55 while (!thread_has_lock) { /* Spin. */ }
56
57 __sync_fetch_and_sub(&thread_should_acquire_lock, lock_type);
58 ASSERT_EQ(thread_should_acquire_lock, 0);
59
60 fprintf(stderr, "Thread acquired lock.\n");
61 }
62
63 void tell_thread_to_release_lock(void) {
64 fprintf(stderr, "Thread releasing lock.\n");
65
66 ASSERT_EQ(thread_has_lock, 1);
67 ASSERT_EQ(thread_should_release_lock, 0);
68 __sync_fetch_and_add(&thread_should_release_lock, 1);
69
70 while (thread_has_lock) { /* Spin. */ }
71
72 __sync_fetch_and_sub(&thread_should_release_lock, 1);
73 ASSERT_EQ(thread_should_release_lock, 0);
74
75 fprintf(stderr, "Thread released lock.\n");
76 }
77
78 void test_reader_timedwait(void) {
79 fprintf(stderr, "test_reader_timedwait\n");
80 tell_thread_to_acquire_lock(WRITE_LOCK);
81
82 struct timespec t = { 0, 0 };
83 int rc = pthread_rwlock_timedrdlock(&rwlock, &t);
84 ASSERT_EQ(rc, ETIMEDOUT);
85
86 tell_thread_to_release_lock();
87 }
88
89 void test_writer_timedwait(void) {
90 fprintf(stderr, "test_writer_timedwait\n");
91 tell_thread_to_acquire_lock(READ_LOCK);
92
93 struct timespec t = { 0, 0 };
94 int rc = pthread_rwlock_timedwrlock(&rwlock, &t);
95 ASSERT_EQ(rc, ETIMEDOUT);
96
97 tell_thread_to_release_lock();
98 }
99
100 void test_multiple_writers(void) {
101 fprintf(stderr, "test_multiple_writers\n");
102 tell_thread_to_acquire_lock(WRITE_LOCK);
103
104 /*
105 * Attempt to acquire second write lock should fail.
106 */
107 int rc = pthread_rwlock_trywrlock(&rwlock);
108 ASSERT_EQ(rc, EBUSY);
109
110 tell_thread_to_release_lock();
111 }
112
113 void test_multiple_readers(void) {
114 fprintf(stderr, "test_multiple_readers\n");
115 tell_thread_to_acquire_lock(READ_LOCK);
116
117 /*
118 * Now attempt to acquire the lock on the main thread.
119 * Since they are both readers this should succeed.
120 * Try with tryrdlock, rdlock and timedrdlock.
121 */
122 int rc = pthread_rwlock_tryrdlock(&rwlock);
123 ASSERT_EQ(rc, 0);
124 rc = pthread_rwlock_unlock(&rwlock);
125 ASSERT_EQ(rc, 0);
126
127 struct timespec t = { 0, 0 };
128 rc = pthread_rwlock_timedrdlock(&rwlock, &t);
129 ASSERT_EQ(rc, 0);
130 rc = pthread_rwlock_unlock(&rwlock);
131 ASSERT_EQ(rc, 0);
132
133 rc = pthread_rwlock_rdlock(&rwlock);
134 ASSERT_EQ(rc, 0);
135 rc = pthread_rwlock_unlock(&rwlock);
136 ASSERT_EQ(rc, 0);
137
138 tell_thread_to_release_lock();
139 }
140
141 void test_reader_plus_writer(void) {
142 fprintf(stderr, "test_reader_plus_writer\n");
143 tell_thread_to_acquire_lock(READ_LOCK);
144
145 /*
146 * Now attempt to acquire the write lock on the main thread.
147 * This should fail.
148 */
149 int rc = pthread_rwlock_trywrlock(&rwlock);
150 ASSERT_EQ(rc, EBUSY);
151
152 tell_thread_to_release_lock();
153 }
154
155 void test_writer_plus_reader(void) {
156 fprintf(stderr, "test_writer_plus_reader\n");
157
158 /*
159 * First get the write lock.
160 */
161 int rc = pthread_rwlock_wrlock(&rwlock);
162 ASSERT_EQ(rc, 0);
163
164 /*
165 * Attempt to acquire read lock should now fail
166 */
167 rc = pthread_rwlock_tryrdlock(&rwlock);
168 ASSERT_EQ(rc, EBUSY);
169
170 rc = pthread_rwlock_unlock(&rwlock);
171 ASSERT_EQ(rc, 0);
172 }
173
174 void test_unlocked_with_zero_timestamp(void) {
175 fprintf(stderr, "test_unlocked_with_zero_timestamp\n");
176 int rc;
177 struct timespec abstime = { 0, 0 };
178 ASSERT_EQ(thread_has_lock, 0);
179 fprintf(stderr, "Trying to lock the unlocked rwlock with a valid "
180 "zero absolute timestamp. "
181 "Expected to succeed instantly since the lock is free.\n");
182 rc = pthread_rwlock_timedrdlock(&rwlock, &abstime);
183 ASSERT_EQ(rc, 0);
184 rc = pthread_rwlock_unlock(&rwlock);
185 ASSERT_EQ(rc, 0);
186 }
187
188 int main(int argc, char **argv) {
189 int rc;
190 fprintf(stderr, "Running...\n");
191
192 pthread_rwlockattr_t attrs;
193 rc = pthread_rwlockattr_init(&attrs);
194 ASSERT_EQ(rc, 0);
195 rc = pthread_rwlock_init(&rwlock, &attrs);
196 ASSERT_EQ(rc, 0);
197 rc = pthread_rwlockattr_destroy(&attrs);
198 ASSERT_EQ(rc, 0);
199
200 pthread_t thread;
201 rc = pthread_create(&thread, NULL, locking_thread, NULL);
202 ASSERT_EQ(rc, 0);
203 fprintf(stderr, "Thread started.\n");
204
205 test_unlocked_with_zero_timestamp();
206 test_multiple_readers();
207 test_multiple_writers();
208 test_reader_plus_writer();
209 test_writer_plus_reader();
210 test_reader_timedwait();
211 test_writer_timedwait();
212
Mark Seaborn 2014/12/01 22:33:07 Also test pthread_rwlock_destroy()?
Sam Clegg 2014/12/10 19:17:43 Done.
213 fprintf(stderr, "Done.\n");
214 return 0;
215 }
OLDNEW
« src/untrusted/pthread/pthread.h ('K') | « tests/threads/nacl.scons ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698