|
1 /* Portion Copyright © 2008-09 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. */ |
|
2 #undef G_DISABLE_ASSERT |
|
3 #undef G_LOG_DOMAIN |
|
4 |
|
5 #include <time.h> |
|
6 #include <stdlib.h> |
|
7 |
|
8 #include <glib.h> |
|
9 #include <glib/gthread.h> |
|
10 |
|
11 #define DEBUG_MSG(args) |
|
12 /* #define DEBUG_MSG(args) g_printerr args ; g_printerr ("\n"); */ |
|
13 #define PRINT_MSG(args) |
|
14 /* #define PRINT_MSG(args) g_print args ; g_print ("\n"); */ |
|
15 |
|
16 #define MAX_THREADS 50 |
|
17 #define MAX_SORTS 5 /* only applies if |
|
18 ASYC_QUEUE_DO_SORT is set to 1 */ |
|
19 #define MAX_TIME 20 /* seconds */ |
|
20 #define MIN_TIME 5 /* seconds */ |
|
21 |
|
22 #define SORT_QUEUE_AFTER 1 |
|
23 #define SORT_QUEUE_ON_PUSH 1 /* if this is done, the |
|
24 SORT_QUEUE_AFTER is ignored */ |
|
25 #define QUIT_WHEN_DONE 1 |
|
26 |
|
27 |
|
28 #if SORT_QUEUE_ON_PUSH == 1 |
|
29 # undef SORT_QUEUE_AFTER |
|
30 # define SORT_QUEUE_AFTER 0 |
|
31 #endif |
|
32 |
|
33 #ifdef SYMBIAN |
|
34 #include "mrt2_glib2_test.h" |
|
35 #endif /*SYMBIAN*/ |
|
36 |
|
37 |
|
38 static GMainLoop *main_loop = NULL; |
|
39 static GThreadPool *thread_pool = NULL; |
|
40 static GAsyncQueue *async_queue = NULL; |
|
41 |
|
42 |
|
43 static gint |
|
44 sort_compare (gconstpointer p1, gconstpointer p2, gpointer user_data) |
|
45 { |
|
46 gint32 id1; |
|
47 gint32 id2; |
|
48 |
|
49 id1 = GPOINTER_TO_INT (p1); |
|
50 id2 = GPOINTER_TO_INT (p2); |
|
51 |
|
52 DEBUG_MSG (("comparing #1:%d and #2:%d, returning %d", |
|
53 id1, id2, (id1 > id2 ? +1 : id1 == id2 ? 0 : -1))); |
|
54 |
|
55 return (id1 > id2 ? +1 : id1 == id2 ? 0 : -1); |
|
56 } |
|
57 |
|
58 static gboolean |
|
59 sort_queue (gpointer user_data) |
|
60 { |
|
61 static gint sorts = 0; |
|
62 static gpointer last_p = NULL; |
|
63 gpointer p; |
|
64 gboolean can_quit = FALSE; |
|
65 gint sort_multiplier; |
|
66 gint len; |
|
67 gint i; |
|
68 |
|
69 sort_multiplier = GPOINTER_TO_INT (user_data); |
|
70 |
|
71 if (SORT_QUEUE_AFTER) { |
|
72 PRINT_MSG (("sorting async queue...")); |
|
73 g_async_queue_sort (async_queue, sort_compare, NULL); |
|
74 |
|
75 sorts++; |
|
76 |
|
77 if (sorts >= sort_multiplier) { |
|
78 can_quit = TRUE; |
|
79 } |
|
80 |
|
81 g_async_queue_sort (async_queue, sort_compare, NULL); |
|
82 len = g_async_queue_length (async_queue); |
|
83 |
|
84 PRINT_MSG (("sorted queue (for %d/%d times, size:%d)...", sorts, MAX_SORTS, len)); |
|
85 } else { |
|
86 can_quit = TRUE; |
|
87 len = g_async_queue_length (async_queue); |
|
88 DEBUG_MSG (("printing queue (size:%d)...", len)); |
|
89 } |
|
90 |
|
91 for (i = 0, last_p = NULL; i < len; i++) { |
|
92 p = g_async_queue_pop (async_queue); |
|
93 DEBUG_MSG (("item %d ---> %d", i, GPOINTER_TO_INT (p))); |
|
94 |
|
95 if (last_p) { |
|
96 g_assert (GPOINTER_TO_INT (last_p) <= GPOINTER_TO_INT (p)); |
|
97 } |
|
98 |
|
99 last_p = p; |
|
100 } |
|
101 |
|
102 if (can_quit && QUIT_WHEN_DONE) { |
|
103 g_main_loop_quit (main_loop); |
|
104 } |
|
105 |
|
106 return !can_quit; |
|
107 } |
|
108 |
|
109 static void |
|
110 enter_thread (gpointer data, gpointer user_data) |
|
111 { |
|
112 gint len; |
|
113 gint id; |
|
114 gulong ms; |
|
115 |
|
116 id = GPOINTER_TO_INT (data); |
|
117 |
|
118 ms = g_random_int_range (MIN_TIME * 1000, MAX_TIME * 1000); |
|
119 DEBUG_MSG (("entered thread with id:%d, adding to queue in:%ld ms", id, ms)); |
|
120 |
|
121 g_usleep (ms * 1000); |
|
122 |
|
123 if (SORT_QUEUE_ON_PUSH) { |
|
124 g_async_queue_push_sorted (async_queue, GINT_TO_POINTER (id), sort_compare, NULL); |
|
125 } else { |
|
126 g_async_queue_push (async_queue, GINT_TO_POINTER (id)); |
|
127 } |
|
128 |
|
129 len = g_async_queue_length (async_queue); |
|
130 |
|
131 DEBUG_MSG (("thread id:%d added to async queue (size:%d)", |
|
132 id, len)); |
|
133 } |
|
134 |
|
135 int |
|
136 main (int argc, char *argv[]) |
|
137 { |
|
138 |
|
139 gint i; |
|
140 gint max_threads = MAX_THREADS; |
|
141 gint max_unused_threads = MAX_THREADS; |
|
142 gint sort_multiplier = MAX_SORTS; |
|
143 gint sort_interval; |
|
144 gchar *msg; |
|
145 |
|
146 #ifdef SYMBIAN |
|
147 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); |
|
148 #endif /*SYMBIAN*/ |
|
149 g_thread_init (NULL); |
|
150 |
|
151 PRINT_MSG (("creating async queue...")); |
|
152 async_queue = g_async_queue_new (); |
|
153 g_assert(async_queue != NULL); |
|
154 |
|
155 g_return_val_if_fail (async_queue != NULL, EXIT_FAILURE); |
|
156 |
|
157 PRINT_MSG (("creating thread pool with max threads:%d, max unused threads:%d...", |
|
158 max_threads, max_unused_threads)); |
|
159 thread_pool = g_thread_pool_new (enter_thread, |
|
160 async_queue, |
|
161 max_threads, |
|
162 FALSE, |
|
163 NULL); |
|
164 |
|
165 g_return_val_if_fail (thread_pool != NULL, EXIT_FAILURE); |
|
166 |
|
167 g_thread_pool_set_max_unused_threads (max_unused_threads); |
|
168 |
|
169 PRINT_MSG (("creating threads...")); |
|
170 for (i = 1; i <= max_threads; i++) { |
|
171 GError *error = NULL; |
|
172 |
|
173 g_thread_pool_push (thread_pool, GINT_TO_POINTER (i), &error); |
|
174 |
|
175 g_assert (error == NULL); |
|
176 } |
|
177 |
|
178 if (!SORT_QUEUE_AFTER) { |
|
179 sort_multiplier = 1; |
|
180 } |
|
181 |
|
182 sort_interval = ((MAX_TIME / sort_multiplier) + 2) * 1000; |
|
183 g_timeout_add (sort_interval, sort_queue, GINT_TO_POINTER (sort_multiplier)); |
|
184 |
|
185 if (SORT_QUEUE_ON_PUSH) { |
|
186 msg = "sorting when pushing into the queue, checking queue is sorted"; |
|
187 } else { |
|
188 msg = "sorting"; |
|
189 } |
|
190 |
|
191 PRINT_MSG (("%s %d %s %d ms", |
|
192 msg, |
|
193 sort_multiplier, |
|
194 sort_multiplier == 1 ? "time in" : "times, once every", |
|
195 sort_interval)); |
|
196 |
|
197 DEBUG_MSG (("entering main event loop")); |
|
198 |
|
199 main_loop = g_main_loop_new (NULL, FALSE); |
|
200 g_main_loop_run (main_loop); |
|
201 |
|
202 |
|
203 #if SYMBIAN |
|
204 testResultXml("asyncqueue-test"); |
|
205 #endif /* EMULATOR */ |
|
206 |
|
207 return EXIT_SUCCESS; |
|
208 } |