[kdbus] KDBUS_ITEM_PAYLOAD_OFF items are (once again) relative to msg header
[platform/upstream/glib.git] / tests / sources.c
1 /* This library is free software; you can redistribute it and/or
2  * modify it under the terms of the GNU Lesser General Public
3  * License as published by the Free Software Foundation; either
4  * version 2 of the License, or (at your option) any later version.
5  *
6  * This library is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9  * Lesser General Public License for more details.
10  *
11  * You should have received a copy of the GNU Lesser General Public
12  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
13  *
14  * Copyright 2012 Red Hat, Inc
15  */
16
17 #undef G_DISABLE_ASSERT
18 #undef G_LOG_DOMAIN
19
20 #include <glib.h>
21
22 #define NSOURCES 50000
23
24 static gboolean
25 callback (gpointer user_data)
26 {
27   g_assert_not_reached ();
28   return FALSE;
29 }
30
31 static void
32 shuffle (GSource **sources, int num)
33 {
34   int i, a, b;
35   GSource *tmp;
36
37   for (i = 0; i < num * 10; i++)
38     {
39       a = g_random_int_range (0, num);
40       b = g_random_int_range (0, num);
41       tmp = sources[a];
42       sources[a] = sources[b];
43       sources[b] = tmp;
44     }
45 }
46
47 static void
48 thread_pool_attach_func (gpointer data,
49                          gpointer user_data)
50 {
51   GMainContext *context = user_data;
52   GSource *source = data;
53
54   g_source_attach (source, context);
55   g_source_unref (source);
56 }
57
58 static void
59 thread_pool_destroy_func (gpointer data,
60                           gpointer user_data)
61 {
62   GSource *source = data;
63
64   g_source_destroy (source);
65 }
66
67 int
68 main (int argc, char **argv)
69 {
70   int i;
71   gint64 start;
72   gint64 end;
73   GMainContext *context;
74   GSource **sources;
75   GThreadPool *pool;
76   GError *error = NULL;
77
78   context = g_main_context_default ();
79   sources = g_new0 (GSource *, NSOURCES);
80
81   start = g_get_monotonic_time ();
82   for (i = 0; i < NSOURCES; i++)
83     {
84       sources[i] = g_idle_source_new ();
85       g_source_set_callback (sources[i], callback, NULL, NULL);
86       g_source_attach (sources[i], context);
87     }
88   end = g_get_monotonic_time ();
89   g_print ("Add same-priority sources: %" G_GINT64_FORMAT "\n",
90            (end - start) / 1000);
91
92 #ifdef SLOW
93   start = g_get_monotonic_time ();
94   for (i = 0; i < NSOURCES; i++)
95     g_assert (sources[i] == g_main_context_find_source_by_id (context, g_source_get_id (sources[i])));
96   end = g_get_monotonic_time ();
97   g_print ("Find each source: %" G_GINT64_FORMAT "\n",
98            (end - start) / 1000);
99 #endif
100
101   shuffle (sources, NSOURCES);
102
103   start = g_get_monotonic_time ();
104   for (i = 0; i < NSOURCES; i++)
105     {
106       g_source_destroy (sources[i]);
107       g_source_unref (sources[i]);
108     }
109   end = g_get_monotonic_time ();
110   g_print ("Remove in random order: %" G_GINT64_FORMAT "\n",
111            (end - start) / 1000);
112
113   /* Make sure they really did get removed */
114   g_main_context_iteration (context, FALSE);
115
116   start = g_get_monotonic_time ();
117   for (i = 0; i < NSOURCES; i++)
118     {
119       sources[i] = g_idle_source_new ();
120       g_source_set_callback (sources[i], callback, NULL, NULL);
121       g_source_set_priority (sources[i], i % 100);
122       g_source_attach (sources[i], context);
123     }
124   end = g_get_monotonic_time ();
125   g_print ("Add different-priority sources: %" G_GINT64_FORMAT "\n",
126            (end - start) / 1000);
127
128 #ifdef SLOW
129   start = g_get_monotonic_time ();
130   for (i = 0; i < NSOURCES; i++)
131     g_assert (sources[i] == g_main_context_find_source_by_id (context, g_source_get_id (sources[i])));
132   end = g_get_monotonic_time ();
133   g_print ("Find each source: %" G_GINT64_FORMAT "\n",
134            (end - start) / 1000);
135 #endif
136
137   shuffle (sources, NSOURCES);
138
139   start = g_get_monotonic_time ();
140   for (i = 0; i < NSOURCES; i++)
141     {
142       g_source_destroy (sources[i]);
143       g_source_unref (sources[i]);
144     }
145   end = g_get_monotonic_time ();
146   g_print ("Remove in random order: %" G_GINT64_FORMAT "\n",
147            (end - start) / 1000);
148
149   /* Make sure they really did get removed */
150   g_main_context_iteration (context, FALSE);
151
152   pool = g_thread_pool_new (thread_pool_attach_func, context,
153                             20, TRUE, NULL);
154   start = g_get_monotonic_time ();
155   for (i = 0; i < NSOURCES; i++)
156     {
157       sources[i] = g_idle_source_new ();
158       g_source_set_callback (sources[i], callback, NULL, NULL);
159       g_thread_pool_push (pool, sources[i], &error);
160       g_assert_no_error (error);
161     }
162   g_thread_pool_free (pool, FALSE, TRUE);
163   end = g_get_monotonic_time ();
164   g_print ("Add sources from threads: %" G_GINT64_FORMAT "\n",
165            (end - start) / 1000);
166
167   pool = g_thread_pool_new (thread_pool_destroy_func, context,
168                             20, TRUE, NULL);
169   start = g_get_monotonic_time ();
170   for (i = 0; i < NSOURCES; i++)
171     {
172       g_thread_pool_push (pool, sources[i], &error);
173       g_assert_no_error (error);
174     }
175   g_thread_pool_free (pool, FALSE, TRUE);
176   end = g_get_monotonic_time ();
177   g_print ("Remove sources from threads: %" G_GINT64_FORMAT "\n",
178            (end - start) / 1000);
179
180   /* Make sure they really did get removed */
181   g_main_context_iteration (context, FALSE);
182
183   g_free (sources);
184   return 0;
185 }