Use POSIX-specified <poll.h> over <sys/poll.h>
[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, write to the
13  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
14  * Boston, MA 02111-1307, USA.
15  *
16  * Copyright 2012 Red Hat, Inc
17  */
18
19 #undef G_DISABLE_ASSERT
20 #undef G_LOG_DOMAIN
21
22 #include <glib.h>
23
24 #define NSOURCES 50000
25
26 static gboolean
27 callback (gpointer user_data)
28 {
29   g_assert_not_reached ();
30   return FALSE;
31 }
32
33 static void
34 shuffle (GSource **sources, int num)
35 {
36   int i, a, b;
37   GSource *tmp;
38
39   for (i = 0; i < num * 10; i++)
40     {
41       a = g_random_int_range (0, num);
42       b = g_random_int_range (0, num);
43       tmp = sources[a];
44       sources[a] = sources[b];
45       sources[b] = tmp;
46     }
47 }
48
49 static void
50 thread_pool_attach_func (gpointer data,
51                          gpointer user_data)
52 {
53   GMainContext *context = user_data;
54   GSource *source = data;
55
56   g_source_attach (source, context);
57   g_source_unref (source);
58 }
59
60 static void
61 thread_pool_destroy_func (gpointer data,
62                           gpointer user_data)
63 {
64   GSource *source = data;
65
66   g_source_destroy (source);
67 }
68
69 int
70 main (int argc, char **argv)
71 {
72   int i;
73   gint64 start;
74   gint64 end;
75   GMainContext *context;
76   GSource **sources;
77   GThreadPool *pool;
78   GError *error = NULL;
79
80   context = g_main_context_default ();
81   sources = g_new0 (GSource *, NSOURCES);
82
83   start = g_get_monotonic_time ();
84   for (i = 0; i < NSOURCES; i++)
85     {
86       sources[i] = g_idle_source_new ();
87       g_source_set_callback (sources[i], callback, NULL, NULL);
88       g_source_attach (sources[i], context);
89     }
90   end = g_get_monotonic_time ();
91   g_print ("Add same-priority sources: %" G_GINT64_FORMAT "\n",
92            (end - start) / 1000);
93
94 #ifdef SLOW
95   start = g_get_monotonic_time ();
96   for (i = 0; i < NSOURCES; i++)
97     g_assert (sources[i] == g_main_context_find_source_by_id (context, g_source_get_id (sources[i])));
98   end = g_get_monotonic_time ();
99   g_print ("Find each source: %" G_GINT64_FORMAT "\n",
100            (end - start) / 1000);
101 #endif
102
103   shuffle (sources, NSOURCES);
104
105   start = g_get_monotonic_time ();
106   for (i = 0; i < NSOURCES; i++)
107     {
108       g_source_destroy (sources[i]);
109       g_source_unref (sources[i]);
110     }
111   end = g_get_monotonic_time ();
112   g_print ("Remove in random order: %" G_GINT64_FORMAT "\n",
113            (end - start) / 1000);
114
115   /* Make sure they really did get removed */
116   g_main_context_iteration (context, FALSE);
117
118   start = g_get_monotonic_time ();
119   for (i = 0; i < NSOURCES; i++)
120     {
121       sources[i] = g_idle_source_new ();
122       g_source_set_callback (sources[i], callback, NULL, NULL);
123       g_source_set_priority (sources[i], i % 100);
124       g_source_attach (sources[i], context);
125     }
126   end = g_get_monotonic_time ();
127   g_print ("Add different-priority sources: %" G_GINT64_FORMAT "\n",
128            (end - start) / 1000);
129
130 #ifdef SLOW
131   start = g_get_monotonic_time ();
132   for (i = 0; i < NSOURCES; i++)
133     g_assert (sources[i] == g_main_context_find_source_by_id (context, g_source_get_id (sources[i])));
134   end = g_get_monotonic_time ();
135   g_print ("Find each source: %" G_GINT64_FORMAT "\n",
136            (end - start) / 1000);
137 #endif
138
139   shuffle (sources, NSOURCES);
140
141   start = g_get_monotonic_time ();
142   for (i = 0; i < NSOURCES; i++)
143     {
144       g_source_destroy (sources[i]);
145       g_source_unref (sources[i]);
146     }
147   end = g_get_monotonic_time ();
148   g_print ("Remove in random order: %" G_GINT64_FORMAT "\n",
149            (end - start) / 1000);
150
151   /* Make sure they really did get removed */
152   g_main_context_iteration (context, FALSE);
153
154   pool = g_thread_pool_new (thread_pool_attach_func, context,
155                             20, TRUE, NULL);
156   start = g_get_monotonic_time ();
157   for (i = 0; i < NSOURCES; i++)
158     {
159       sources[i] = g_idle_source_new ();
160       g_source_set_callback (sources[i], callback, NULL, NULL);
161       g_thread_pool_push (pool, sources[i], &error);
162       g_assert_no_error (error);
163     }
164   g_thread_pool_free (pool, FALSE, TRUE);
165   end = g_get_monotonic_time ();
166   g_print ("Add sources from threads: %" G_GINT64_FORMAT "\n",
167            (end - start) / 1000);
168
169   pool = g_thread_pool_new (thread_pool_destroy_func, context,
170                             20, TRUE, NULL);
171   start = g_get_monotonic_time ();
172   for (i = 0; i < NSOURCES; i++)
173     {
174       g_thread_pool_push (pool, sources[i], &error);
175       g_assert_no_error (error);
176     }
177   g_thread_pool_free (pool, FALSE, TRUE);
178   end = g_get_monotonic_time ();
179   g_print ("Remove sources from threads: %" G_GINT64_FORMAT "\n",
180            (end - start) / 1000);
181
182   /* Make sure they really did get removed */
183   g_main_context_iteration (context, FALSE);
184
185   g_free (sources);
186   return 0;
187 }