From d80d70458ad1711f9c1935a58df3eb9e04853464 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 1 Sep 2012 00:20:22 -0400 Subject: [PATCH] Add a threaded test for g_object_replace_data This is the threaded atomic add test from glib/tests/atomic.c, redone using qdata instead of an atomic int to store the values. --- gobject/tests/Makefile.am | 1 + gobject/tests/qdata.c | 93 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 gobject/tests/qdata.c diff --git a/gobject/tests/Makefile.am b/gobject/tests/Makefile.am index a150b0a52..fcc7b848e 100644 --- a/gobject/tests/Makefile.am +++ b/gobject/tests/Makefile.am @@ -12,6 +12,7 @@ noinst_PROGRAMS = $(TEST_PROGS) LDADD = ../libgobject-2.0.la $(top_builddir)/gthread/libgthread-2.0.la $(top_builddir)/glib/libglib-2.0.la TEST_PROGS += \ + qdata \ boxed \ enums \ param \ diff --git a/gobject/tests/qdata.c b/gobject/tests/qdata.c new file mode 100644 index 000000000..aeacc4596 --- /dev/null +++ b/gobject/tests/qdata.c @@ -0,0 +1,93 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * 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. + */ + +#include + +gboolean fail; + +#define THREADS 10 +#define ROUNDS 10000 + +GObject *object; +volatile gint bucket[THREADS]; + +static gpointer +thread_func (gpointer data) +{ + gint idx = GPOINTER_TO_INT (data); + gint i; + gint d; + gint value; + gint new_value; + + for (i = 0; i < ROUNDS; i++) + { + d = g_random_int_range (-10, 100); + bucket[idx] += d; +retry: + value = GPOINTER_TO_INT (g_object_get_data (object, "test")); + new_value = value + d; + if (fail) + g_object_set_data (object, "test", GINT_TO_POINTER (new_value)); + else + { + if (!g_object_replace_data (object, "test", + GINT_TO_POINTER (value), + GINT_TO_POINTER (new_value), + NULL, NULL)) + goto retry; + } + g_thread_yield (); + } + + return NULL; +} + +static void +test_qdata_threaded (void) +{ + gint sum; + gint i; + GThread *threads[THREADS]; + gint result; + + object = g_object_new (G_TYPE_OBJECT, NULL); + g_object_set_data (object, "test", GINT_TO_POINTER (0)); + + for (i = 0; i < THREADS; i++) + bucket[i] = 0; + + for (i = 0; i < THREADS; i++) + threads[i] = g_thread_new ("qdata", thread_func, GINT_TO_POINTER (i)); + + for (i = 0; i < THREADS; i++) + g_thread_join (threads[i]); + + sum = 0; + for (i = 0; i < THREADS; i++) + sum += bucket[i]; + + result = GPOINTER_TO_INT (g_object_get_data (object, "test")); + + g_assert_cmpint (sum, ==, result); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + g_type_init (); + fail = !!g_getenv ("FAIL"); + + g_test_add_func ("/qdata/threaded", test_qdata_threaded); + + return g_test_run (); +}