2 * Copyright © 2008 Ryan Lortie
3 * Copyright © 2010 Codethink Limited
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * See the included COPYING file for more information.
13 /* LOCKS should be more than the number of contention
14 * counters in gthread.c in order to ensure we exercise
15 * the case where they overlap.
18 #define ITERATIONS 10000
22 #if TEST_EMULATED_FUTEX
23 /* this is defined for the 1bit-mutex-emufutex test.
25 * we want to test the emulated futex even if futex(2) is available.
28 /* side-step some glib build stuff */
29 #ifndef DISABLE_VISIBILITY
30 #define DISABLE_VISIBILITY
32 #define GLIB_COMPILATION
34 /* rebuild gbitlock.c without futex support,
35 defining our own version of the g_bit_*lock symbols
37 #define g_bit_lock _emufutex_g_bit_lock
38 #define g_bit_trylock _emufutex_g_bit_trylock
39 #define g_bit_unlock _emufutex_g_bit_unlock
40 #define _g_futex_thread_init _emufutex_g_futex_thread_init
42 #define G_BIT_LOCK_FORCE_FUTEX_EMULATION
44 #include <glib/gbitlock.c>
49 volatile GThread *owners[LOCKS];
50 volatile gint locks[LOCKS];
51 volatile gint bits[LOCKS];
58 self = g_thread_self ();
60 g_bit_lock (&locks[nr], bits[nr]);
61 g_assert (owners[nr] == NULL); /* hopefully nobody else is here */
64 /* let some other threads try to ruin our day */
69 g_assert (owners[nr] == self); /* hopefully this is still us... */
70 owners[nr] = NULL; /* make way for the next guy */
71 g_bit_unlock (&locks[nr], bits[nr]);
75 thread_func (gpointer data)
79 for (i = 0; i < ITERATIONS; i++)
80 acquire (g_random_int () % LOCKS);
88 GThread *threads[THREADS];
93 #ifdef TEST_EMULATED_FUTEX
94 _g_futex_thread_init ();
95 #define SUFFIX "-emufutex"
97 /* ensure that we are using the emulated futex by checking
98 * (at compile-time) for the existance of 'g_futex_mutex'
100 g_assert (g_futex_mutex != NULL);
105 for (i = 0; i < LOCKS; i++)
106 bits[i] = g_random_int () % 32;
108 for (i = 0; i < THREADS; i++)
109 threads[i] = g_thread_create (thread_func, NULL, TRUE, NULL);
111 for (i = 0; i < THREADS; i++)
112 g_thread_join (threads[i]);
114 for (i = 0; i < LOCKS; i++)
116 g_assert (owners[i] == NULL);
117 g_assert (locks[i] == 0);
122 main (int argc, char **argv)
124 g_test_init (&argc, &argv, NULL);
126 g_test_add_func ("/glib/1bit-mutex" SUFFIX, testcase);
128 return g_test_run ();