Use non-deprecated api in tests
[platform/upstream/glib.git] / glib / tests / rwlock.c
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_print ("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 }