nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /* Unit tests for GRWLock
2 * Copyright (C) 2011 Red Hat, Inc
3 * Author: Matthias Clasen
4 *
5 * This work is provided "as is"; redistribution and modification
6 * in whole or in part, in any medium, physical or electronic is
7 * permitted without restriction.
8 *
9 * This work 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.
12 *
13 * In no event shall the authors or contributors be liable for any
14 * direct, indirect, incidental, special, exemplary, or consequential
15 * damages (including, but not limited to, procurement of substitute
16 * goods or services; loss of use, data, or profits; or business
17 * interruption) however caused and on any theory of liability, whether
18 * in contract, strict liability, or tort (including negligence or
19 * otherwise) arising in any way out of the use of this software, even
20 * if advised of the possibility of such damage.
21 */
22  
23 /* We are testing some deprecated APIs here */
24 #define GLIB_DISABLE_DEPRECATION_WARNINGS
25  
26 #include <glib.h>
27  
28 static void
29 test_rwlock1 (void)
30 {
31 GRWLock lock;
32  
33 g_rw_lock_init (&lock);
34 g_rw_lock_writer_lock (&lock);
35 g_rw_lock_writer_unlock (&lock);
36 g_rw_lock_writer_lock (&lock);
37 g_rw_lock_writer_unlock (&lock);
38 g_rw_lock_clear (&lock);
39 }
40  
41 static void
42 test_rwlock2 (void)
43 {
44 static GRWLock lock;
45  
46 g_rw_lock_writer_lock (&lock);
47 g_rw_lock_writer_unlock (&lock);
48 g_rw_lock_writer_lock (&lock);
49 g_rw_lock_writer_unlock (&lock);
50 }
51  
52 static void
53 test_rwlock3 (void)
54 {
55 static GRWLock lock;
56 gboolean ret;
57  
58 ret = g_rw_lock_writer_trylock (&lock);
59 g_assert (ret);
60 ret = g_rw_lock_writer_trylock (&lock);
61 g_assert (!ret);
62  
63 g_rw_lock_writer_unlock (&lock);
64 }
65  
66 static void
67 test_rwlock4 (void)
68 {
69 static GRWLock lock;
70  
71 g_rw_lock_reader_lock (&lock);
72 g_rw_lock_reader_unlock (&lock);
73 g_rw_lock_reader_lock (&lock);
74 g_rw_lock_reader_unlock (&lock);
75 }
76  
77 static void
78 test_rwlock5 (void)
79 {
80 static GRWLock lock;
81 gboolean ret;
82  
83 ret = g_rw_lock_reader_trylock (&lock);
84 g_assert (ret);
85 ret = g_rw_lock_reader_trylock (&lock);
86 g_assert (ret);
87  
88 g_rw_lock_reader_unlock (&lock);
89 g_rw_lock_reader_unlock (&lock);
90 }
91  
92 static void
93 test_rwlock6 (void)
94 {
95 static GRWLock lock;
96 gboolean ret;
97  
98 g_rw_lock_writer_lock (&lock);
99 ret = g_rw_lock_reader_trylock (&lock);
100 g_assert (!ret);
101 g_rw_lock_writer_unlock (&lock);
102  
103 g_rw_lock_reader_lock (&lock);
104 ret = g_rw_lock_writer_trylock (&lock);
105 g_assert (!ret);
106 g_rw_lock_reader_unlock (&lock);
107 }
108  
109  
110 #define LOCKS 48
111 #define ITERATIONS 10000
112 #define THREADS 100
113  
114  
115 GThread *owners[LOCKS];
116 GRWLock locks[LOCKS];
117  
118 static void
119 acquire (gint nr)
120 {
121 GThread *self;
122  
123 self = g_thread_self ();
124  
125 if (!g_rw_lock_writer_trylock (&locks[nr]))
126 {
127 if (g_test_verbose ())
128 g_printerr ("thread %p going to block on lock %d\n", self, nr);
129  
130 g_rw_lock_writer_lock (&locks[nr]);
131 }
132  
133 g_assert (owners[nr] == NULL); /* hopefully nobody else is here */
134 owners[nr] = self;
135  
136 /* let some other threads try to ruin our day */
137 g_thread_yield ();
138 g_thread_yield ();
139 g_thread_yield ();
140  
141 g_assert (owners[nr] == self); /* hopefully this is still us... */
142 owners[nr] = NULL; /* make way for the next guy */
143  
144 g_rw_lock_writer_unlock (&locks[nr]);
145 }
146  
147 static gpointer
148 thread_func (gpointer data)
149 {
150 gint i;
151 GRand *rand;
152  
153 rand = g_rand_new ();
154  
155 for (i = 0; i < ITERATIONS; i++)
156 acquire (g_rand_int_range (rand, 0, LOCKS));
157  
158 g_rand_free (rand);
159  
160 return NULL;
161 }
162  
163 static void
164 test_rwlock7 (void)
165 {
166 gint i;
167 GThread *threads[THREADS];
168  
169 for (i = 0; i < LOCKS; i++)
170 g_rw_lock_init (&locks[i]);
171  
172 for (i = 0; i < THREADS; i++)
173 threads[i] = g_thread_new ("test", thread_func, NULL);
174  
175 for (i = 0; i < THREADS; i++)
176 g_thread_join (threads[i]);
177  
178 for (i = 0; i < LOCKS; i++)
179 g_rw_lock_clear (&locks[i]);
180  
181 for (i = 0; i < LOCKS; i++)
182 g_assert (owners[i] == NULL);
183 }
184  
185 static gint even;
186 static GRWLock even_lock;
187 GThread *writers[2];
188 GThread *readers[10];
189  
190 static void
191 change_even (gpointer data)
192 {
193 g_rw_lock_writer_lock (&even_lock);
194  
195 g_assert (even % 2 == 0);
196  
197 even += 1;
198  
199 if (GPOINTER_TO_INT (data) == 0)
200 even += 1;
201 else
202 even -= 1;
203  
204 g_assert (even % 2 == 0);
205  
206 g_rw_lock_writer_unlock (&even_lock);
207 }
208  
209 static void
210 verify_even (gpointer data)
211 {
212 g_rw_lock_reader_lock (&even_lock);
213  
214 g_assert (even % 2 == 0);
215  
216 g_rw_lock_reader_unlock (&even_lock);
217 }
218  
219 static gpointer
220 writer_func (gpointer data)
221 {
222 gint i;
223  
224 for (i = 0; i < 100000; i++)
225 change_even (data);
226  
227 return NULL;
228 }
229  
230 static gpointer
231 reader_func (gpointer data)
232 {
233 gint i;
234  
235 for (i = 0; i < 100000; i++)
236 verify_even (data);
237  
238 return NULL;
239 }
240  
241 /* This test has 2 writers and 10 readers.
242 * The writers modify an integer multiple times,
243 * but always leave it with an even value.
244 * The readers verify that they can only observe
245 * even values
246 */
247 static void
248 test_rwlock8 (void)
249 {
250 gint i;
251  
252 even = 0;
253 g_rw_lock_init (&even_lock);
254  
255 for (i = 0; i < 2; i++)
256 writers[i] = g_thread_new ("a", writer_func, GINT_TO_POINTER (i));
257  
258 for (i = 0; i < 10; i++)
259 readers[i] = g_thread_new ("b", reader_func, NULL);
260  
261 for (i = 0; i < 2; i++)
262 g_thread_join (writers[i]);
263  
264 for (i = 0; i < 10; i++)
265 g_thread_join (readers[i]);
266  
267 g_assert (even % 2 == 0);
268  
269 g_rw_lock_clear (&even_lock);
270 }
271  
272 int
273 main (int argc, char *argv[])
274 {
275 g_test_init (&argc, &argv, NULL);
276  
277 g_test_add_func ("/thread/rwlock1", test_rwlock1);
278 g_test_add_func ("/thread/rwlock2", test_rwlock2);
279 g_test_add_func ("/thread/rwlock3", test_rwlock3);
280 g_test_add_func ("/thread/rwlock4", test_rwlock4);
281 g_test_add_func ("/thread/rwlock5", test_rwlock5);
282 g_test_add_func ("/thread/rwlock6", test_rwlock6);
283 g_test_add_func ("/thread/rwlock7", test_rwlock7);
284 g_test_add_func ("/thread/rwlock8", test_rwlock8);
285  
286 return g_test_run ();
287 }