Initialize Tizen 2.3
[framework/multimedia/gst-openmax.git] / wearable / tests / check_async_queue.c
1 /*
2  * Copyright (C) 2008-2009 Nokia Corporation.
3  *
4  * Author: Felipe Contreras <felipe.contreras@nokia.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation
9  * version 2.1 of the License.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #include <check.h>
23 #include "async_queue.h"
24 #include "sem.h"
25
26 #define PROCESS_COUNT 0x1000
27 #define DISABLE_AT PROCESS_COUNT / 2
28
29 typedef struct CustomData CustomData;
30
31 struct CustomData
32 {
33   AsyncQueue *queue;
34   GSem *push_sem;
35   GSem *pop_sem;
36   gboolean done;
37 };
38
39 static CustomData *
40 custom_data_new (void)
41 {
42   CustomData *custom_data;
43   custom_data = g_new0 (CustomData, 1);
44   custom_data->queue = async_queue_new ();
45   custom_data->push_sem = g_sem_new ();
46   custom_data->pop_sem = g_sem_new ();
47   return custom_data;
48 }
49
50 static void
51 custom_data_free (CustomData * custom_data)
52 {
53   g_sem_free (custom_data->pop_sem);
54   g_sem_free (custom_data->push_sem);
55   async_queue_free (custom_data->queue);
56   g_free (custom_data);
57 }
58
59 START_TEST (test_async_queue_create)
60 {
61   AsyncQueue *queue;
62   queue = async_queue_new ();
63   fail_if (!queue, "Construction failed");
64   async_queue_free (queue);
65 }
66
67 END_TEST
68 START_TEST (test_async_queue_pop)
69 {
70   AsyncQueue *queue;
71   gpointer foo;
72   gpointer tmp;
73   queue = async_queue_new ();
74   fail_if (!queue, "Construction failed");
75   foo = GINT_TO_POINTER (1);
76   async_queue_push (queue, foo);
77   tmp = async_queue_pop (queue);
78   fail_if (tmp != foo, "Pop failed");
79   async_queue_free (queue);
80 }
81
82 END_TEST
83 START_TEST (test_async_queue_process)
84 {
85   AsyncQueue *queue;
86   gpointer foo;
87   guint i;
88
89   queue = async_queue_new ();
90   fail_if (!queue, "Construction failed");
91
92   foo = GINT_TO_POINTER (1);
93   for (i = 0; i < PROCESS_COUNT; i++, foo++) {
94     async_queue_push (queue, foo);
95   }
96   foo = GINT_TO_POINTER (1);
97   for (i = 0; i < PROCESS_COUNT; i++, foo++) {
98     gpointer tmp;
99     tmp = async_queue_pop (queue);
100     fail_if (tmp != foo, "Pop failed");
101   }
102
103   async_queue_free (queue);
104 }
105
106 END_TEST static gpointer
107 push_func (gpointer data)
108 {
109   AsyncQueue *queue;
110   gpointer foo;
111   guint i;
112
113   queue = data;
114   foo = GINT_TO_POINTER (1);
115   for (i = 0; i < PROCESS_COUNT; i++, foo++) {
116     async_queue_push (queue, foo);
117   }
118
119   return NULL;
120 }
121
122 static gpointer
123 pop_func (gpointer data)
124 {
125   AsyncQueue *queue;
126   gpointer foo;
127   guint i;
128
129   queue = data;
130   foo = GINT_TO_POINTER (1);
131   for (i = 0; i < PROCESS_COUNT; i++, foo++) {
132     gpointer tmp;
133     tmp = async_queue_pop (queue);
134     fail_if (tmp != foo, "Pop failed");
135   }
136
137   return NULL;
138 }
139
140 START_TEST (test_async_queue_threads)
141 {
142   AsyncQueue *queue;
143   GThread *push_thread;
144   GThread *pop_thread;
145
146   queue = async_queue_new ();
147   fail_if (!queue, "Construction failed");
148
149   pop_thread = g_thread_create (pop_func, queue, TRUE, NULL);
150   push_thread = g_thread_create (push_func, queue, TRUE, NULL);
151
152   g_thread_join (pop_thread);
153   g_thread_join (push_thread);
154
155   async_queue_free (queue);
156 }
157
158 END_TEST static gpointer
159 push_and_disable_func (gpointer data)
160 {
161   AsyncQueue *queue;
162   gpointer foo;
163   guint i;
164
165   queue = data;
166   foo = GINT_TO_POINTER (1);
167   for (i = 0; i < DISABLE_AT; i++, foo++) {
168     async_queue_push (queue, foo);
169   }
170
171   async_queue_disable (queue);
172
173   return NULL;
174 }
175
176 static gpointer
177 pop_with_disable_func (gpointer data)
178 {
179   AsyncQueue *queue;
180   gpointer foo;
181   guint i;
182   guint count = 0;
183
184   queue = data;
185   foo = GINT_TO_POINTER (1);
186   for (i = 0; i < PROCESS_COUNT; i++, foo++) {
187     gpointer tmp;
188     tmp = async_queue_pop (queue);
189     if (!tmp)
190       continue;
191     count++;
192     fail_if (tmp != foo, "Pop failed");
193   }
194
195   return GINT_TO_POINTER (count);
196 }
197
198 static gpointer
199 pop_stress (gpointer data)
200 {
201   CustomData *custom_data;
202   AsyncQueue *queue;
203   guint i;
204
205   custom_data = data;
206   queue = custom_data->queue;
207   while (!custom_data->done) {
208     for (i = 0; i < 10; i++) {
209       gpointer tmp;
210       tmp = async_queue_pop (queue);
211       if (!tmp)
212         break;
213     }
214
215     g_sem_up (custom_data->pop_sem);
216     g_sem_down (custom_data->push_sem);
217   }
218
219   return NULL;
220 }
221
222 static gpointer
223 push_stress (gpointer data)
224 {
225   CustomData *custom_data;
226   AsyncQueue *queue;
227   gpointer foo;
228   guint i, j;
229
230   custom_data = data;
231   queue = custom_data->queue;
232   foo = GINT_TO_POINTER (1);
233   for (j = 0; j < 10; j++) {
234     for (i = 0; i < 10; i++, foo++) {
235       async_queue_push (queue, foo);
236     }
237
238     async_queue_disable (queue);
239
240     g_sem_down (custom_data->pop_sem);
241
242 #if 0
243     if (queue->length)
244       g_debug ("flusihng %i elements", queue->length);
245 #endif
246
247     async_queue_flush (queue);
248
249     async_queue_enable (queue);
250
251     g_sem_up (custom_data->push_sem);
252   }
253
254   custom_data->done = TRUE;
255   async_queue_disable (queue);
256   g_sem_up (custom_data->push_sem);
257
258   return NULL;
259 }
260
261 START_TEST (test_async_queue_disable_simple)
262 {
263   AsyncQueue *queue;
264   GThread *pop_thread;
265   guint count;
266
267   queue = async_queue_new ();
268   fail_if (!queue, "Construction failed");
269
270   pop_thread = g_thread_create (pop_with_disable_func, queue, TRUE, NULL);
271
272   async_queue_disable (queue);
273
274   count = GPOINTER_TO_INT (g_thread_join (pop_thread));
275
276   fail_if (count != 0, "Disable failed");
277
278   async_queue_free (queue);
279 }
280
281 END_TEST
282 START_TEST (test_async_queue_disable)
283 {
284   AsyncQueue *queue;
285   GThread *push_thread;
286   GThread *pop_thread;
287   guint count;
288
289   queue = async_queue_new ();
290   fail_if (!queue, "Construction failed");
291
292   pop_thread = g_thread_create (pop_with_disable_func, queue, TRUE, NULL);
293   push_thread = g_thread_create (push_and_disable_func, queue, TRUE, NULL);
294
295   count = GPOINTER_TO_INT (g_thread_join (pop_thread));
296   g_thread_join (push_thread);
297
298   fail_if (count > DISABLE_AT, "Disable failed");
299
300   async_queue_free (queue);
301 }
302
303 END_TEST
304 START_TEST (test_async_queue_enable)
305 {
306   AsyncQueue *queue;
307   GThread *push_thread;
308   GThread *pop_thread;
309   guint count;
310
311   queue = async_queue_new ();
312   fail_if (!queue, "Construction failed");
313
314   pop_thread = g_thread_create (pop_with_disable_func, queue, TRUE, NULL);
315
316   async_queue_disable (queue);
317
318   count = GPOINTER_TO_INT (g_thread_join (pop_thread));
319
320   fail_if (count != 0, "Disable failed");
321
322   async_queue_enable (queue);
323
324   pop_thread = g_thread_create (pop_with_disable_func, queue, TRUE, NULL);
325   push_thread = g_thread_create (push_and_disable_func, queue, TRUE, NULL);
326
327   count = GPOINTER_TO_INT (g_thread_join (pop_thread));
328   g_thread_join (push_thread);
329
330   fail_if (count > DISABLE_AT, "Disable failed");
331
332   async_queue_free (queue);
333 }
334
335 END_TEST
336 START_TEST (test_async_queue_stress)
337 {
338   GThread *push_thread;
339   GThread *pop_thread;
340   CustomData *custom_data;
341
342   custom_data = custom_data_new ();
343
344   pop_thread = g_thread_create (pop_stress, custom_data, TRUE, NULL);
345   push_thread = g_thread_create (push_stress, custom_data, TRUE, NULL);
346
347   g_thread_join (pop_thread);
348   g_thread_join (push_thread);
349
350   custom_data_free (custom_data);
351 }
352
353 END_TEST static Suite *
354 util_suite (void)
355 {
356   Suite *s = suite_create ("util");
357
358   if (!g_thread_supported ())
359     g_thread_init (NULL);
360
361   /* Core test case */
362   TCase *tc_core = tcase_create ("Core");
363   tcase_add_test (tc_core, test_async_queue_create);
364   tcase_add_test (tc_core, test_async_queue_pop);
365   tcase_add_test (tc_core, test_async_queue_process);
366   tcase_add_test (tc_core, test_async_queue_threads);
367   tcase_add_test (tc_core, test_async_queue_disable_simple);
368   tcase_add_test (tc_core, test_async_queue_disable);
369   tcase_add_test (tc_core, test_async_queue_enable);
370   tcase_add_test (tc_core, test_async_queue_stress);
371   suite_add_tcase (s, tc_core);
372
373   return s;
374 }
375
376 int
377 main (void)
378 {
379   int number_failed;
380   Suite *s;
381   SRunner *sr;
382
383   s = util_suite ();
384   sr = srunner_create (s);
385   srunner_run_all (sr, CK_NORMAL);
386   number_failed = srunner_ntests_failed (sr);
387   srunner_free (sr);
388
389   return (number_failed == 0) ? 0 : 1;
390 }