1 /* Unit tests for GRWLock
2 * Copyright (C) 2011 Red Hat, Inc
3 * Author: Matthias Clasen
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.
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.
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.
23 /* We are testing some deprecated APIs here */
24 #define GLIB_DISABLE_DEPRECATION_WARNINGS
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
);
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
);
58 ret
= g_rw_lock_writer_trylock (&lock
);
60 ret
= g_rw_lock_writer_trylock (&lock
);
63 g_rw_lock_writer_unlock (&lock
);
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
);
83 ret
= g_rw_lock_reader_trylock (&lock
);
85 ret
= g_rw_lock_reader_trylock (&lock
);
88 g_rw_lock_reader_unlock (&lock
);
89 g_rw_lock_reader_unlock (&lock
);
98 g_rw_lock_writer_lock (&lock
);
99 ret
= g_rw_lock_reader_trylock (&lock
);
101 g_rw_lock_writer_unlock (&lock
);
103 g_rw_lock_reader_lock (&lock
);
104 ret
= g_rw_lock_writer_trylock (&lock
);
106 g_rw_lock_reader_unlock (&lock
);
111 #define ITERATIONS 10000
115 GThread
*owners
[LOCKS
];
116 GRWLock locks
[LOCKS
];
123 self
= g_thread_self ();
125 if (!g_rw_lock_writer_trylock (&locks
[nr
]))
127 if (g_test_verbose ())
128 g_printerr ("thread %p going to block on lock %d\n", self
, nr
);
130 g_rw_lock_writer_lock (&locks
[nr
]);
133 g_assert (owners
[nr
] == NULL
); /* hopefully nobody else is here */
136 /* let some other threads try to ruin our day */
141 g_assert (owners
[nr
] == self
); /* hopefully this is still us... */
142 owners
[nr
] = NULL
; /* make way for the next guy */
144 g_rw_lock_writer_unlock (&locks
[nr
]);
148 thread_func (gpointer data
)
153 rand
= g_rand_new ();
155 for (i
= 0; i
< ITERATIONS
; i
++)
156 acquire (g_rand_int_range (rand
, 0, LOCKS
));
167 GThread
*threads
[THREADS
];
169 for (i
= 0; i
< LOCKS
; i
++)
170 g_rw_lock_init (&locks
[i
]);
172 for (i
= 0; i
< THREADS
; i
++)
173 threads
[i
] = g_thread_new ("test", thread_func
, NULL
);
175 for (i
= 0; i
< THREADS
; i
++)
176 g_thread_join (threads
[i
]);
178 for (i
= 0; i
< LOCKS
; i
++)
179 g_rw_lock_clear (&locks
[i
]);
181 for (i
= 0; i
< LOCKS
; i
++)
182 g_assert (owners
[i
] == NULL
);
186 static GRWLock even_lock
;
188 GThread
*readers
[10];
191 change_even (gpointer data
)
193 g_rw_lock_writer_lock (&even_lock
);
195 g_assert (even
% 2 == 0);
199 if (GPOINTER_TO_INT (data
) == 0)
204 g_assert (even
% 2 == 0);
206 g_rw_lock_writer_unlock (&even_lock
);
210 verify_even (gpointer data
)
212 g_rw_lock_reader_lock (&even_lock
);
214 g_assert (even
% 2 == 0);
216 g_rw_lock_reader_unlock (&even_lock
);
220 writer_func (gpointer data
)
224 for (i
= 0; i
< 100000; i
++)
231 reader_func (gpointer data
)
235 for (i
= 0; i
< 100000; i
++)
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
253 g_rw_lock_init (&even_lock
);
255 for (i
= 0; i
< 2; i
++)
256 writers
[i
] = g_thread_new ("a", writer_func
, GINT_TO_POINTER (i
));
258 for (i
= 0; i
< 10; i
++)
259 readers
[i
] = g_thread_new ("b", reader_func
, NULL
);
261 for (i
= 0; i
< 2; i
++)
262 g_thread_join (writers
[i
]);
264 for (i
= 0; i
< 10; i
++)
265 g_thread_join (readers
[i
]);
267 g_assert (even
% 2 == 0);
269 g_rw_lock_clear (&even_lock
);
273 main (int argc
, char *argv
[])
275 g_test_init (&argc
, &argv
, NULL
);
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
);
286 return g_test_run ();