From 12287c8cc70fc65bc7bbeb4f7079b262337fce09 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 2 Oct 2011 09:51:13 -0400 Subject: [PATCH] Don't put threads created with g_thread_new() on the list This lets us avoid the overhead of maintaining the global list in the non-deprecated case. https://bugzilla.gnome.org/show_bug.cgi?id=660635 --- glib/deprecated/gthread-deprecated.c | 4 +- glib/gthread.c | 76 +++++++++++++++++----------- glib/gthreadprivate.h | 8 +++ 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/glib/deprecated/gthread-deprecated.c b/glib/deprecated/gthread-deprecated.c index 16ab73212..dabab8d95 100644 --- a/glib/deprecated/gthread-deprecated.c +++ b/glib/deprecated/gthread-deprecated.c @@ -155,7 +155,7 @@ g_thread_create (GThreadFunc func, gboolean joinable, GError **error) { - return g_thread_new_full (NULL, func, data, joinable, 0, error); + return g_thread_new_internal (NULL, func, data, joinable, 0, TRUE, error); } /** @@ -183,7 +183,7 @@ g_thread_create_full (GThreadFunc func, GThreadPriority priority, GError **error) { - return g_thread_new_full (NULL, func, data, joinable, stack_size, error); + return g_thread_new_internal (NULL, func, data, joinable, stack_size, TRUE, error); } /* GStaticMutex {{{1 ------------------------------------------------------ */ diff --git a/glib/gthread.c b/glib/gthread.c index f9082fd54..a75388345 100644 --- a/glib/gthread.c +++ b/glib/gthread.c @@ -585,6 +585,7 @@ struct _GRealThread GArray *private_data; GRealThread *next; const gchar *name; + gboolean enumerable; gpointer retval; GSystemThread system_thread; }; @@ -1102,21 +1103,24 @@ g_thread_cleanup (gpointer data) */ if (!thread->thread.joinable) { - GRealThread *t, *p; - - G_LOCK (g_thread); - for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next) + if (thread->enumerable) { - if (t == thread) + GRealThread *t, *p; + + G_LOCK (g_thread); + for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next) { - if (p) - p->next = t->next; - else - g_thread_all_threads = t->next; - break; + if (t == thread) + { + if (p) + p->next = t->next; + else + g_thread_all_threads = t->next; + break; + } } + G_UNLOCK (g_thread); } - G_UNLOCK (g_thread); /* Just to make sure, this isn't used any more */ g_system_thread_assign (thread->system_thread, zero_thread); g_free (thread); @@ -1183,7 +1187,7 @@ g_thread_new (const gchar *name, gboolean joinable, GError **error) { - return g_thread_new_full (name, func, data, joinable, 0, error); + return g_thread_new_internal (name, func, data, joinable, 0, FALSE, error); } /** @@ -1232,7 +1236,19 @@ g_thread_new_full (const gchar *name, gsize stack_size, GError **error) { - GRealThread* result; + return g_thread_new_internal (name, func, data, joinable, stack_size, FALSE, error); +} + +GThread * +g_thread_new_internal (const gchar *name, + GThreadFunc func, + gpointer data, + gboolean joinable, + gsize stack_size, + gboolean enumerable, + GError **error) +{ + GRealThread *result; GError *local_error = NULL; g_return_val_if_fail (func, NULL); @@ -1242,12 +1258,13 @@ g_thread_new_full (const gchar *name, result->thread.func = func; result->thread.data = data; result->private_data = NULL; + result->enumerable = enumerable; result->name = name; G_LOCK (g_thread); g_system_thread_create (g_thread_create_proxy, result, stack_size, joinable, &result->system_thread, &local_error); - if (!local_error) + if (enumerable && !local_error) { result->next = g_thread_all_threads; g_thread_all_threads = result; @@ -1308,9 +1325,9 @@ g_thread_exit (gpointer retval) * Returns: the return value of the thread */ gpointer -g_thread_join (GThread* thread) +g_thread_join (GThread *thread) { - GRealThread* real = (GRealThread*) thread; + GRealThread *real = (GRealThread*) thread; GRealThread *p, *t; gpointer retval; @@ -1322,19 +1339,22 @@ g_thread_join (GThread* thread) retval = real->retval; - G_LOCK (g_thread); - for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next) + if (real->enumerable) { - if (t == (GRealThread*) thread) + G_LOCK (g_thread); + for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next) { - if (p) - p->next = t->next; - else - g_thread_all_threads = t->next; - break; + if (t == real) + { + if (p) + p->next = t->next; + else + g_thread_all_threads = t->next; + break; + } } + G_UNLOCK (g_thread); } - G_UNLOCK (g_thread); /* Just to make sure, this isn't used any more */ thread->joinable = 0; g_system_thread_assign (real->system_thread, zero_thread); @@ -1372,15 +1392,11 @@ g_thread_self (void) thread->thread.func = NULL; thread->thread.data = NULL; thread->private_data = NULL; + thread->enumerable = FALSE; g_system_thread_self (&thread->system_thread); g_private_set (&g_thread_specific_private, thread); - - G_LOCK (g_thread); - thread->next = g_thread_all_threads; - g_thread_all_threads = thread; - G_UNLOCK (g_thread); } return (GThread*)thread; diff --git a/glib/gthreadprivate.h b/glib/gthreadprivate.h index 57eb975cc..1a95668bf 100644 --- a/glib/gthreadprivate.h +++ b/glib/gthreadprivate.h @@ -48,6 +48,14 @@ G_GNUC_INTERNAL gboolean g_system_thread_equal (gpointer thread1, G_GNUC_INTERNAL void g_system_thread_exit (void); G_GNUC_INTERNAL void g_system_thread_set_name (const gchar *name); +G_GNUC_INTERNAL GThread *g_thread_new_internal (const gchar *name, + GThreadFunc func, + gpointer data, + gboolean joinable, + gsize stack_size, + gboolean enumerable, + GError **error); + G_GNUC_INTERNAL GSystemThread zero_thread; G_GNUC_INTERNAL GMutex g_once_mutex;