summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Janik <timj@imendio.com>2007-07-12 15:26:47 +0000
committerTim Janik <timj@src.gnome.org>2007-07-12 15:26:47 +0000
commit223754f6277032b0b149da29e7e937915ebd913d (patch)
tree4498ba2c672cb477c49e3876928185c4f26ca3eb
parent964d75ebe37ba879d05fa1b27f06aed63e7106db (diff)
added GSLice test from Stefan Westerfeld, bug #433314.
Thu Jul 12 17:26:05 2007 Tim Janik <timj@imendio.com> * tests/slice-concurrent.c: added GSLice test from Stefan Westerfeld, bug #433314. svn path=/trunk/; revision=5630
-rw-r--r--ChangeLog5
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/slice-concurrent.c108
3 files changed, 116 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index ee2e81c0d..2355e2c23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Thu Jul 12 17:26:05 2007 Tim Janik <timj@imendio.com>
+
+ * tests/slice-concurrent.c: added GSLice test from Stefan Westerfeld,
+ bug #433314.
+
Thu Jul 12 15:46:40 2007 Tim Janik <timj@imendio.com>
* glib/gslice.c: migrate per-thread magazine caches from single-thread
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 891939999..9088136c7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -104,6 +104,7 @@ test_programs = \
slist-test \
slice-test \
slice-color \
+ slice-concurrent \
slice-threadinit \
spawn-test \
$(spawn_test_win32_gui) \
@@ -176,6 +177,8 @@ slice_test_SOURCES = slice-test.c memchunks.c
slice_test_LDADD = $(thread_ldadd)
slice_color_SOURCES = slice-color.c memchunks.c
slice_color_LDADD = $(thread_ldadd)
+slice_concurrent_SOURCES = slice-concurrent.c
+slice_concurrent_LDADD = $(thread_ldadd)
slice_threadinit_SOURCES = slice-threadinit.c
slice_threadinit_LDADD = $(thread_ldadd)
spawn_test_LDADD = $(progs_ldadd)
diff --git a/tests/slice-concurrent.c b/tests/slice-concurrent.c
new file mode 100644
index 000000000..3e9f77f09
--- /dev/null
+++ b/tests/slice-concurrent.c
@@ -0,0 +1,108 @@
+/* test for gslice cross thread allocation/free
+ * Copyright (C) 2006 Stefan Westerfeld
+ *
+ * This library 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <glib.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define N_THREADS 8
+#define N_ALLOCS 50000
+#define MAX_BLOCK_SIZE 32
+
+struct ThreadData
+{
+ int thread_id;
+ GThread* gthread;
+
+ GMutex* to_free_mutex;
+ void* to_free [N_THREADS * N_ALLOCS];
+ int bytes_to_free [N_THREADS * N_ALLOCS];
+ int n_to_free;
+ int n_freed;
+} tdata[N_THREADS];
+
+void*
+thread_func (void *arg)
+{
+ struct ThreadData *td = arg;
+ int i;
+ g_print ("Thread %d starting\n", td->thread_id);
+ for (i = 0; i < N_ALLOCS; i++)
+ {
+ if (rand() % (N_ALLOCS / 20) == 0)
+ g_print ("%d", td->thread_id);
+
+ int bytes = rand() % MAX_BLOCK_SIZE + 1;
+ char *mem = g_slice_alloc (bytes);
+
+ int f;
+ for (f = 0; f < bytes; f++)
+ mem[f] = rand();
+
+ int t = rand() % N_THREADS;
+ g_mutex_lock (tdata[t].to_free_mutex);
+ tdata[t].to_free[tdata[t].n_to_free] = mem;
+ tdata[t].bytes_to_free[tdata[t].n_to_free] = bytes;
+ tdata[t].n_to_free++;
+ g_mutex_unlock (tdata[t].to_free_mutex);
+
+ usleep (rand() % 1000);
+
+ g_mutex_lock (td->to_free_mutex);
+ if (td->n_to_free > 0)
+ {
+ td->n_to_free--;
+ g_slice_free1 (td->bytes_to_free[td->n_to_free], td->to_free[td->n_to_free]);
+ td->n_freed++;
+ }
+ g_mutex_unlock (td->to_free_mutex);
+ }
+
+ return NULL;
+}
+
+int
+main()
+{
+ int t;
+ g_thread_init (NULL);
+
+ for (t = 0; t < N_THREADS; t++)
+ {
+ tdata[t].thread_id = t + 1;
+ tdata[t].n_to_free = 0;
+ tdata[t].n_freed = 0;
+ tdata[t].to_free_mutex = g_mutex_new();
+ }
+ for (t = 0; t < N_THREADS; t++)
+ {
+ tdata[t].gthread = g_thread_create (thread_func, &tdata[t], TRUE, NULL);
+ g_assert (tdata[t].gthread != NULL);
+ }
+ for (t = 0; t < N_THREADS; t++)
+ {
+ g_thread_join (tdata[t].gthread);
+ }
+ g_print ("\n");
+ for (t = 0; t < N_THREADS; t++)
+ {
+ g_print ("Thread %d: %d blocks freed, %d blocks not freed\n",
+ tdata[t].thread_id, tdata[t].n_freed, tdata[t].n_to_free);
+ }
+ return 0;
+}