diff --git a/glib/tests/rwlock.c b/glib/tests/rwlock.c index 17869ca96..c69dd94b1 100644 --- a/glib/tests/rwlock.c +++ b/glib/tests/rwlock.c @@ -111,6 +111,82 @@ test_rwlock6 (void) g_rw_lock_clear (&lock); } + +#define LOCKS 48 +#define ITERATIONS 10000 +#define THREADS 100 + + +GThread *owners[LOCKS]; +GRWLock locks[LOCKS]; + +static void +acquire (gint nr) +{ + GThread *self; + + self = g_thread_self (); + + if (!g_rw_lock_writer_trylock (&locks[nr])) + { + if (g_test_verbose ()) + g_print ("thread %p going to block on lock %d\n", self, nr); + + g_rw_lock_writer_lock (&locks[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_rw_lock_writer_unlock (&locks[nr]); +} + +static gpointer +thread_func (gpointer data) +{ + gint i; + GRand *rand; + + rand = g_rand_new (); + + for (i = 0; i < ITERATIONS; i++) + acquire (g_rand_int_range (rand, 0, LOCKS)); + + g_rand_free (rand); + + return NULL; +} + +static void +test_rwlock7 (void) +{ + gint i; + GThread *threads[THREADS]; + + for (i = 0; i < LOCKS; i++) + g_rw_lock_init (&locks[i]); + + 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_rw_lock_clear (&locks[i]); + + for (i = 0; i < LOCKS; i++) + g_assert (owners[i] == NULL); +} + int main (int argc, char *argv[]) { @@ -122,6 +198,7 @@ main (int argc, char *argv[]) g_test_add_func ("/thread/rwlock4", test_rwlock4); g_test_add_func ("/thread/rwlock5", test_rwlock5); g_test_add_func ("/thread/rwlock6", test_rwlock6); + g_test_add_func ("/thread/rwlock7", test_rwlock7); return g_test_run (); }