[glib/gobject-performance] Make ClassData->init_state atomic
- From: Benjamin Otte <otte src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [glib/gobject-performance] Make ClassData->init_state atomic
- Date: Thu, 24 Sep 2009 11:30:50 +0000 (UTC)
commit 9f7231f4807c9106cf148be8e4261462ea0de99d
Author: Benjamin Otte <otte gnome org>
Date: Thu Sep 24 12:26:53 2009 +0200
Make ClassData->init_state atomic
This is necessary to make g_type_class_ref() lockless.
https://bugzilla.gnome.org/show_bug.cgi?id=585375
Also includes fix for:
https://bugzilla.gnome.org/show_bug.cgi?id=587892
gobject/gtype.c | 24 +++++++++++++-----------
1 files changed, 13 insertions(+), 11 deletions(-)
---
diff --git a/gobject/gtype.c b/gobject/gtype.c
index 6861a9d..be08719 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -313,7 +313,7 @@ struct _ClassData
{
CommonData common;
guint16 class_size;
- guint init_state : 4;
+ int volatile init_state; /* atomic - g_type_class_ref reads it unlocked */
GBaseInitFunc class_init_base;
GBaseFinalizeFunc class_finalize_base;
GClassInitFunc class_init;
@@ -326,7 +326,7 @@ struct _InstanceData
{
CommonData common;
guint16 class_size;
- guint init_state : 4;
+ int volatile init_state; /* atomic - g_type_class_ref reads it unlocked */
GBaseInitFunc class_init_base;
GBaseFinalizeFunc class_finalize_base;
GClassInitFunc class_init;
@@ -2055,7 +2055,7 @@ type_class_init_Wm (TypeNode *node,
class = g_malloc0 (node->data->class.class_size);
node->data->class.class = class;
- node->data->class.init_state = BASE_CLASS_INIT;
+ g_atomic_int_set (&node->data->class.init_state, BASE_CLASS_INIT);
if (pclass)
{
@@ -2092,7 +2092,7 @@ type_class_init_Wm (TypeNode *node,
G_WRITE_LOCK (&type_rw_lock);
- node->data->class.init_state = BASE_IFACE_INIT;
+ g_atomic_int_set (&node->data->class.init_state, BASE_IFACE_INIT);
/* Before we initialize the class, base initialize all interfaces, either
* from parent, or through our holder info
@@ -2148,7 +2148,7 @@ type_class_init_Wm (TypeNode *node,
i++;
}
- node->data->class.init_state = CLASS_INIT;
+ g_atomic_int_set (&node->data->class.init_state, CLASS_INIT);
G_WRITE_UNLOCK (&type_rw_lock);
@@ -2157,7 +2157,7 @@ type_class_init_Wm (TypeNode *node,
G_WRITE_LOCK (&type_rw_lock);
- node->data->class.init_state = IFACE_INIT;
+ g_atomic_int_set (&node->data->class.init_state, IFACE_INIT);
/* finish initializing the interfaces through our holder info.
* inherited interfaces are already init_state == INITIALIZED, because
@@ -2188,7 +2188,7 @@ type_class_init_Wm (TypeNode *node,
i++;
}
- node->data->class.init_state = INITIALIZED;
+ g_atomic_int_set (&node->data->class.init_state, INITIALIZED);
}
static void
@@ -2819,8 +2819,7 @@ g_type_class_ref (GType type)
G_WRITE_LOCK (&type_rw_lock);
node = lookup_type_node_I (type);
if (node && node->is_classed && node->data &&
- node->data->class.class &&
- node->data->class.init_state == INITIALIZED)
+ g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)
{
type_data_ref_Wm (node);
G_WRITE_UNLOCK (&type_rw_lock);
@@ -2929,7 +2928,9 @@ g_type_class_peek (GType type)
node = lookup_type_node_I (type);
G_READ_LOCK (&type_rw_lock);
- if (node && node->is_classed && node->data && node->data->class.class) /* ref_count _may_ be 0 */
+ if (node && node->is_classed && node->data &&
+ g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)
+ /* ref_count _may_ be 0 */
class = node->data->class.class;
else
class = NULL;
@@ -2959,7 +2960,8 @@ g_type_class_peek_static (GType type)
G_READ_LOCK (&type_rw_lock);
if (node && node->is_classed && node->data &&
/* peek only static types: */ node->plugin == NULL &&
- node->data->class.class) /* ref_count _may_ be 0 */
+ g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)
+ /* ref_count _may_ be 0 */
class = node->data->class.class;
else
class = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]