sl@0: /* sl@0: * Portions copyright (c) 2006-2009 Nokia Corporation. All rights reserved. sl@0: */ sl@0: #undef G_DISABLE_ASSERT sl@0: #undef G_LOG_DOMAIN sl@0: sl@0: #include sl@0: #include sl@0: sl@0: #include sl@0: sl@0: #define DEBUG_MSG(args) sl@0: /* #define DEBUG_MSG(args) g_printerr args ; g_printerr ("\n"); */ sl@0: #define PRINT_MSG(args) sl@0: /* #define PRINT_MSG(args) g_print args ; g_print ("\n"); */ sl@0: sl@0: #define MAX_THREADS 50 sl@0: #define MAX_SORTS 5 /* only applies if sl@0: ASYC_QUEUE_DO_SORT is set to 1 */ sl@0: #define MAX_TIME 20 /* seconds */ sl@0: #define MIN_TIME 5 /* seconds */ sl@0: sl@0: #define SORT_QUEUE_AFTER 1 sl@0: #define SORT_QUEUE_ON_PUSH 1 /* if this is done, the sl@0: SORT_QUEUE_AFTER is ignored */ sl@0: #define QUIT_WHEN_DONE 1 sl@0: sl@0: sl@0: #if SORT_QUEUE_ON_PUSH == 1 sl@0: # undef SORT_QUEUE_AFTER sl@0: # define SORT_QUEUE_AFTER 0 sl@0: #endif sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: #include "mrt2_glib2_test.h" sl@0: #endif /*__SYMBIAN32__*/ sl@0: sl@0: sl@0: static GMainLoop *main_loop = NULL; sl@0: static GThreadPool *thread_pool = NULL; sl@0: static GAsyncQueue *async_queue = NULL; sl@0: sl@0: sl@0: static gint sl@0: sort_compare (gconstpointer p1, gconstpointer p2, gpointer user_data) sl@0: { sl@0: gint32 id1; sl@0: gint32 id2; sl@0: sl@0: id1 = GPOINTER_TO_INT (p1); sl@0: id2 = GPOINTER_TO_INT (p2); sl@0: sl@0: DEBUG_MSG (("comparing #1:%d and #2:%d, returning %d", sl@0: id1, id2, (id1 > id2 ? +1 : id1 == id2 ? 0 : -1))); sl@0: sl@0: return (id1 > id2 ? +1 : id1 == id2 ? 0 : -1); sl@0: } sl@0: sl@0: static gboolean sl@0: sort_queue (gpointer user_data) sl@0: { sl@0: static gint sorts = 0; sl@0: static gpointer last_p = NULL; sl@0: gpointer p; sl@0: gboolean can_quit = FALSE; sl@0: gint sort_multiplier; sl@0: gint len; sl@0: gint i; sl@0: sl@0: sort_multiplier = GPOINTER_TO_INT (user_data); sl@0: sl@0: if (SORT_QUEUE_AFTER) { sl@0: PRINT_MSG (("sorting async queue...")); sl@0: g_async_queue_sort (async_queue, sort_compare, NULL); sl@0: sl@0: sorts++; sl@0: sl@0: if (sorts >= sort_multiplier) { sl@0: can_quit = TRUE; sl@0: } sl@0: sl@0: g_async_queue_sort (async_queue, sort_compare, NULL); sl@0: len = g_async_queue_length (async_queue); sl@0: sl@0: PRINT_MSG (("sorted queue (for %d/%d times, size:%d)...", sorts, MAX_SORTS, len)); sl@0: } else { sl@0: can_quit = TRUE; sl@0: len = g_async_queue_length (async_queue); sl@0: DEBUG_MSG (("printing queue (size:%d)...", len)); sl@0: } sl@0: sl@0: for (i = 0, last_p = NULL; i < len; i++) { sl@0: p = g_async_queue_pop (async_queue); sl@0: DEBUG_MSG (("item %d ---> %d", i, GPOINTER_TO_INT (p))); sl@0: sl@0: if (last_p) { sl@0: g_assert (GPOINTER_TO_INT (last_p) <= GPOINTER_TO_INT (p)); sl@0: } sl@0: sl@0: last_p = p; sl@0: } sl@0: sl@0: if (can_quit && QUIT_WHEN_DONE) { sl@0: g_main_loop_quit (main_loop); sl@0: } sl@0: sl@0: return !can_quit; sl@0: } sl@0: sl@0: static void sl@0: enter_thread (gpointer data, gpointer user_data) sl@0: { sl@0: gint len; sl@0: gint id; sl@0: gulong ms; sl@0: sl@0: id = GPOINTER_TO_INT (data); sl@0: sl@0: ms = g_random_int_range (MIN_TIME * 1000, MAX_TIME * 1000); sl@0: DEBUG_MSG (("entered thread with id:%d, adding to queue in:%ld ms", id, ms)); sl@0: sl@0: g_usleep (ms * 1000); sl@0: sl@0: if (SORT_QUEUE_ON_PUSH) { sl@0: g_async_queue_push_sorted (async_queue, GINT_TO_POINTER (id), sort_compare, NULL); sl@0: } else { sl@0: g_async_queue_push (async_queue, GINT_TO_POINTER (id)); sl@0: } sl@0: sl@0: len = g_async_queue_length (async_queue); sl@0: sl@0: DEBUG_MSG (("thread id:%d added to async queue (size:%d)", sl@0: id, len)); sl@0: } sl@0: sl@0: int sl@0: main (int argc, char *argv[]) sl@0: { sl@0: #if defined(G_THREADS_ENABLED) && ! defined(G_THREADS_IMPL_NONE) sl@0: gint i; sl@0: gint max_threads = MAX_THREADS; sl@0: gint max_unused_threads = MAX_THREADS; sl@0: gint sort_multiplier = MAX_SORTS; sl@0: gint sort_interval; sl@0: gchar *msg; sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: g_log_set_handler (NULL, G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL); sl@0: g_set_print_handler(mrtPrintHandler); sl@0: #endif /*__SYMBIAN32__*/ sl@0: g_thread_init (NULL); sl@0: sl@0: PRINT_MSG (("creating async queue...")); sl@0: async_queue = g_async_queue_new (); sl@0: sl@0: g_return_val_if_fail (async_queue != NULL, EXIT_FAILURE); sl@0: sl@0: PRINT_MSG (("creating thread pool with max threads:%d, max unused threads:%d...", sl@0: max_threads, max_unused_threads)); sl@0: thread_pool = g_thread_pool_new (enter_thread, sl@0: async_queue, sl@0: max_threads, sl@0: FALSE, sl@0: NULL); sl@0: sl@0: g_return_val_if_fail (thread_pool != NULL, EXIT_FAILURE); sl@0: sl@0: g_thread_pool_set_max_unused_threads (max_unused_threads); sl@0: sl@0: PRINT_MSG (("creating threads...")); sl@0: for (i = 1; i <= max_threads; i++) { sl@0: GError *error = NULL; sl@0: sl@0: g_thread_pool_push (thread_pool, GINT_TO_POINTER (i), &error); sl@0: sl@0: g_assert_no_error (error); sl@0: } sl@0: sl@0: if (!SORT_QUEUE_AFTER) { sl@0: sort_multiplier = 1; sl@0: } sl@0: sl@0: sort_interval = ((MAX_TIME / sort_multiplier) + 2) * 1000; sl@0: g_timeout_add (sort_interval, sort_queue, GINT_TO_POINTER (sort_multiplier)); sl@0: sl@0: if (SORT_QUEUE_ON_PUSH) { sl@0: msg = "sorting when pushing into the queue, checking queue is sorted"; sl@0: } else { sl@0: msg = "sorting"; sl@0: } sl@0: sl@0: PRINT_MSG (("%s %d %s %d ms", sl@0: msg, sl@0: sort_multiplier, sl@0: sort_multiplier == 1 ? "time in" : "times, once every", sl@0: sort_interval)); sl@0: sl@0: DEBUG_MSG (("entering main event loop")); sl@0: sl@0: main_loop = g_main_loop_new (NULL, FALSE); sl@0: g_main_loop_run (main_loop); sl@0: #endif sl@0: sl@0: #if __SYMBIAN32__ sl@0: testResultXml("asyncqueue-test"); sl@0: #endif /* EMULATOR */ sl@0: sl@0: return EXIT_SUCCESS; sl@0: }