2 * Copyright (C) 2008-2009 Nokia Corporation.
4 * Author: Felipe Contreras <felipe.contreras@nokia.com>
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.
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.
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
23 #include "async_queue.h"
26 #define PROCESS_COUNT 0x1000
27 #define DISABLE_AT PROCESS_COUNT / 2
29 typedef struct CustomData CustomData;
40 custom_data_new (void)
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 ();
51 custom_data_free (CustomData * custom_data)
53 g_sem_free (custom_data->pop_sem);
54 g_sem_free (custom_data->push_sem);
55 async_queue_free (custom_data->queue);
59 START_TEST (test_async_queue_create)
62 queue = async_queue_new ();
63 fail_if (!queue, "Construction failed");
64 async_queue_free (queue);
68 START_TEST (test_async_queue_pop)
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);
83 START_TEST (test_async_queue_process)
89 queue = async_queue_new ();
90 fail_if (!queue, "Construction failed");
92 foo = GINT_TO_POINTER (1);
93 for (i = 0; i < PROCESS_COUNT; i++, foo++) {
94 async_queue_push (queue, foo);
96 foo = GINT_TO_POINTER (1);
97 for (i = 0; i < PROCESS_COUNT; i++, foo++) {
99 tmp = async_queue_pop (queue);
100 fail_if (tmp != foo, "Pop failed");
103 async_queue_free (queue);
106 END_TEST static gpointer
107 push_func (gpointer data)
114 foo = GINT_TO_POINTER (1);
115 for (i = 0; i < PROCESS_COUNT; i++, foo++) {
116 async_queue_push (queue, foo);
123 pop_func (gpointer data)
130 foo = GINT_TO_POINTER (1);
131 for (i = 0; i < PROCESS_COUNT; i++, foo++) {
133 tmp = async_queue_pop (queue);
134 fail_if (tmp != foo, "Pop failed");
140 START_TEST (test_async_queue_threads)
143 GThread *push_thread;
146 queue = async_queue_new ();
147 fail_if (!queue, "Construction failed");
149 pop_thread = g_thread_create (pop_func, queue, TRUE, NULL);
150 push_thread = g_thread_create (push_func, queue, TRUE, NULL);
152 g_thread_join (pop_thread);
153 g_thread_join (push_thread);
155 async_queue_free (queue);
158 END_TEST static gpointer
159 push_and_disable_func (gpointer data)
166 foo = GINT_TO_POINTER (1);
167 for (i = 0; i < DISABLE_AT; i++, foo++) {
168 async_queue_push (queue, foo);
171 async_queue_disable (queue);
177 pop_with_disable_func (gpointer data)
185 foo = GINT_TO_POINTER (1);
186 for (i = 0; i < PROCESS_COUNT; i++, foo++) {
188 tmp = async_queue_pop (queue);
192 fail_if (tmp != foo, "Pop failed");
195 return GINT_TO_POINTER (count);
199 pop_stress (gpointer data)
201 CustomData *custom_data;
206 queue = custom_data->queue;
207 while (!custom_data->done) {
208 for (i = 0; i < 10; i++) {
210 tmp = async_queue_pop (queue);
215 g_sem_up (custom_data->pop_sem);
216 g_sem_down (custom_data->push_sem);
223 push_stress (gpointer data)
225 CustomData *custom_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);
238 async_queue_disable (queue);
240 g_sem_down (custom_data->pop_sem);
244 g_debug ("flusihng %i elements", queue->length);
247 async_queue_flush (queue);
249 async_queue_enable (queue);
251 g_sem_up (custom_data->push_sem);
254 custom_data->done = TRUE;
255 async_queue_disable (queue);
256 g_sem_up (custom_data->push_sem);
261 START_TEST (test_async_queue_disable_simple)
267 queue = async_queue_new ();
268 fail_if (!queue, "Construction failed");
270 pop_thread = g_thread_create (pop_with_disable_func, queue, TRUE, NULL);
272 async_queue_disable (queue);
274 count = GPOINTER_TO_INT (g_thread_join (pop_thread));
276 fail_if (count != 0, "Disable failed");
278 async_queue_free (queue);
282 START_TEST (test_async_queue_disable)
285 GThread *push_thread;
289 queue = async_queue_new ();
290 fail_if (!queue, "Construction failed");
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);
295 count = GPOINTER_TO_INT (g_thread_join (pop_thread));
296 g_thread_join (push_thread);
298 fail_if (count > DISABLE_AT, "Disable failed");
300 async_queue_free (queue);
304 START_TEST (test_async_queue_enable)
307 GThread *push_thread;
311 queue = async_queue_new ();
312 fail_if (!queue, "Construction failed");
314 pop_thread = g_thread_create (pop_with_disable_func, queue, TRUE, NULL);
316 async_queue_disable (queue);
318 count = GPOINTER_TO_INT (g_thread_join (pop_thread));
320 fail_if (count != 0, "Disable failed");
322 async_queue_enable (queue);
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);
327 count = GPOINTER_TO_INT (g_thread_join (pop_thread));
328 g_thread_join (push_thread);
330 fail_if (count > DISABLE_AT, "Disable failed");
332 async_queue_free (queue);
336 START_TEST (test_async_queue_stress)
338 GThread *push_thread;
340 CustomData *custom_data;
342 custom_data = custom_data_new ();
344 pop_thread = g_thread_create (pop_stress, custom_data, TRUE, NULL);
345 push_thread = g_thread_create (push_stress, custom_data, TRUE, NULL);
347 g_thread_join (pop_thread);
348 g_thread_join (push_thread);
350 custom_data_free (custom_data);
353 END_TEST static Suite *
356 Suite *s = suite_create ("util");
358 if (!g_thread_supported ())
359 g_thread_init (NULL);
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);
384 sr = srunner_create (s);
385 srunner_run_all (sr, CK_NORMAL);
386 number_failed = srunner_ntests_failed (sr);
389 return (number_failed == 0) ? 0 : 1;