diff options
author | Ryan Lortie <desrt@desrt.ca> | 2010-01-28 18:41:19 -0500 |
---|---|---|
committer | Ryan Lortie <desrt@desrt.ca> | 2010-01-28 18:41:20 -0500 |
commit | 40eae351b1a95626f49ea042e5f5e9824c171c50 (patch) | |
tree | de0febf4f0ecfb47a1fbc4e7f7d5639ab7aea45f /gthread | |
parent | 669b0f2d6b5ef3a4924a1402d569c4e38e4fb41c (diff) |
Bug 548967 - 1 bit mutex lock: add tests
Add a test case for the new API.
Always check the emulated futex(2) implementation, even on systems with
futex support.
Diffstat (limited to 'gthread')
-rw-r--r-- | gthread/Makefile.am | 3 | ||||
-rw-r--r-- | gthread/tests/.gitignore | 2 | ||||
-rw-r--r-- | gthread/tests/1bit-mutex.c | 127 | ||||
-rw-r--r-- | gthread/tests/Makefile.am | 15 |
4 files changed, 147 insertions, 0 deletions
diff --git a/gthread/Makefile.am b/gthread/Makefile.am index de630e7aa..8252260de 100644 --- a/gthread/Makefile.am +++ b/gthread/Makefile.am @@ -1,6 +1,9 @@ ## Process this file with automake to produce Makefile.in include $(top_srcdir)/Makefile.decl +SUBDIRS = . tests +DIST_SUBDIRS = tests + AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/glib \ diff --git a/gthread/tests/.gitignore b/gthread/tests/.gitignore new file mode 100644 index 000000000..ad7fa1037 --- /dev/null +++ b/gthread/tests/.gitignore @@ -0,0 +1,2 @@ +1bit-mutex +1bit-emufutex diff --git a/gthread/tests/1bit-mutex.c b/gthread/tests/1bit-mutex.c new file mode 100644 index 000000000..dff095ca9 --- /dev/null +++ b/gthread/tests/1bit-mutex.c @@ -0,0 +1,127 @@ +/* + * Copyright © 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * See the included COPYING file for more information. + */ + +/* LOCKS should be more than the number of contention + * counters in gthread.c in order to ensure we exercise + * the case where they overlap. + */ +#define LOCKS 48 +#define ITERATIONS 10000 +#define THREADS 100 + + +#if TEST_EMULATED_FUTEX + /* this is defined for the 1bit-mutex-emufutex test. + * + * we want to test the emulated futex even if futex(2) is available. + */ + + /* side-step some glib build stuff */ + #define DISABLE_VISIBILITY + #define GLIB_COMPILATION + + /* rebuild gbitlock.c without futex support, + defining our own version of the g_bit_*lock symbols + */ + #define g_bit_lock _emufutex_g_bit_lock + #define g_bit_trylock _emufutex_g_bit_trylock + #define g_bit_unlock _emufutex_g_bit_unlock + #define _g_futex_thread_init _emufutex_g_futex_thread_init + + #define G_BIT_LOCK_FORCE_FUTEX_EMULATION + + #include <glib/gbitlock.c> +#endif + +#include <glib.h> + +volatile GThread *owners[LOCKS]; +volatile gint locks[LOCKS]; +volatile gint bits[LOCKS]; + +static void +acquire (int nr) +{ + GThread *self; + + self = g_thread_self (); + + g_bit_lock (&locks[nr], bits[nr]); + g_assert (owners[nr] == NULL); /* hopefully nobody else is here */ + owners[nr] = self; + + /* let some other threads try to ruin our day */ + g_thread_yield (); + g_thread_yield (); + g_thread_yield (); + + g_assert (owners[nr] == self); /* hopefully this is still us... */ + owners[nr] = NULL; /* make way for the next guy */ + g_bit_unlock (&locks[nr], bits[nr]); +} + +static gpointer +thread_func (gpointer data) +{ + gint i; + + for (i = 0; i < ITERATIONS; i++) + acquire (g_random_int () % LOCKS); + + return NULL; +} + +static void +testcase (void) +{ + GThread *threads[THREADS]; + int i; + + g_thread_init (NULL); + +#ifdef TEST_EMULATED_FUTEX + _g_futex_thread_init (); + #define SUFFIX "-emufutex" + + /* ensure that we are using the emulated futex by checking + * (at compile-time) for the existance of 'g_futex_mutex' + */ + g_assert (g_futex_mutex != NULL); +#else + #define SUFFIX "" +#endif + + for (i = 0; i < LOCKS; i++) + bits[i] = g_random_int () % 32; + + for (i = 0; i < THREADS; i++) + threads[i] = g_thread_create (thread_func, NULL, TRUE, NULL); + + for (i = 0; i < THREADS; i++) + g_thread_join (threads[i]); + + for (i = 0; i < LOCKS; i++) + { + g_assert (owners[i] == NULL); + g_assert (locks[i] == 0); + } +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/glib/1bit-mutex" SUFFIX, testcase); + + return g_test_run (); +} diff --git a/gthread/tests/Makefile.am b/gthread/tests/Makefile.am new file mode 100644 index 000000000..c5fb65335 --- /dev/null +++ b/gthread/tests/Makefile.am @@ -0,0 +1,15 @@ +include $(top_srcdir)/Makefile.decl + +INCLUDES = -g -I$(top_srcdir) -I$(top_srcdir)/glib $(GLIB_DEBUG_FLAGS) + +noinst_PROGRAMS = $(TEST_PROGS) +progs_ldadd = $(top_builddir)/glib/libglib-2.0.la \ + $(top_builddir)/gthread/libgthread-2.0.la + +TEST_PROGS += 1bit-mutex +1bit_mutex_LDADD = $(progs_ldadd) $(top_builddir)/gthread/libgthread-2.0.la + +TEST_PROGS += 1bit-emufutex +1bit_emufutex_SOURCES = 1bit-mutex.c +1bit_emufutex_CFLAGS = -DTEST_EMULATED_FUTEX +1bit_emufutex_LDADD = $(progs_ldadd) $(top_builddir)/gthread/libgthread-2.0.la |