gobject: drop OPTIONAL_BIT_LOCK_TOGGLE_REFS lock

It was replaced by the GData lock and g_datalist_id_update_atomic().

Note that we introduced object_bit_lock() to replace global mutexes.
Now, object_bit_lock() is itself completely replaced, by the GData lock
(and hooking it via g_datalist_id_update_atomic()).

This means, all mutex-like locks now only go through the GData lock on
the GObject's qdata.

The object_bit_lock() API is still here, because it might be useful. For
example, there might be cases where the GData lock is not sufficient.

Also, we introduced GObjectPrivate mainly for object_bit_lock(). On 32
bit architecture, there is an overhead with that, as we cannot fit the
optional_flags into GObject. This is not dropped either. The optional
flags seem rather useful even without the object_bit_lock(). For
example, the OPTIONAL_FLAG_EVER_HAD_WEAK_REF flag is an important
optimization.
This commit is contained in:
Thomas Haller 2024-01-30 13:09:19 +01:00
parent 1294522fed
commit 16d670c367

View File

@ -124,7 +124,7 @@ enum {
* parallel as possible. The alternative would be to add individual locking * parallel as possible. The alternative would be to add individual locking
* integers to GObjectPrivate. But increasing memory usage for more parallelism * integers to GObjectPrivate. But increasing memory usage for more parallelism
* (per-object!) is not worth it. */ * (per-object!) is not worth it. */
#define OPTIONAL_BIT_LOCK_TOGGLE_REFS 1 #define OPTIONAL_BIT_LOCK_UNUSED 1
#if SIZEOF_INT == 4 && GLIB_SIZEOF_VOID_P >= 8 #if SIZEOF_INT == 4 && GLIB_SIZEOF_VOID_P >= 8
#define HAVE_OPTIONAL_FLAGS_IN_GOBJECT 1 #define HAVE_OPTIONAL_FLAGS_IN_GOBJECT 1
@ -623,7 +623,7 @@ weak_ref_data_has (GObject *object, WeakRefData *wrdata, WeakRefData **out_new_w
static G_THREAD_LOCAL guint _object_bit_is_locked; static G_THREAD_LOCAL guint _object_bit_is_locked;
#endif #endif
static void G_GNUC_UNUSED static void
object_bit_lock (GObject *object, guint lock_bit) object_bit_lock (GObject *object, guint lock_bit)
{ {
#if defined(G_ENABLE_DEBUG) && defined(G_THREAD_LOCAL) #if defined(G_ENABLE_DEBUG) && defined(G_THREAD_LOCAL)
@ -638,7 +638,7 @@ object_bit_lock (GObject *object, guint lock_bit)
g_bit_lock ((gint *) object_get_optional_flags_p (object), _OPTIONAL_BIT_LOCK); g_bit_lock ((gint *) object_get_optional_flags_p (object), _OPTIONAL_BIT_LOCK);
} }
static void G_GNUC_UNUSED static void
object_bit_unlock (GObject *object, guint lock_bit) object_bit_unlock (GObject *object, guint lock_bit)
{ {
#if defined(G_ENABLE_DEBUG) && defined(G_THREAD_LOCAL) #if defined(G_ENABLE_DEBUG) && defined(G_THREAD_LOCAL)
@ -4151,8 +4151,6 @@ toggle_refs_check_and_ref_or_deref (GObject *object,
*toggle_notify = NULL; *toggle_notify = NULL;
*toggle_data = NULL; *toggle_data = NULL;
object_bit_lock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS);
/* This is called from g_object_ref()/g_object_unref() and a hot path. /* This is called from g_object_ref()/g_object_unref() and a hot path.
* *
* We hack the GData open and take the g_datalist_lock() outside. Then we * We hack the GData open and take the g_datalist_lock() outside. Then we
@ -4186,7 +4184,6 @@ toggle_refs_check_and_ref_or_deref (GObject *object,
if (G_UNLIKELY (!success)) if (G_UNLIKELY (!success))
{ {
g_datalist_unlock (&object->qdata); g_datalist_unlock (&object->qdata);
object_bit_unlock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS);
return FALSE; return FALSE;
} }
@ -4194,7 +4191,6 @@ toggle_refs_check_and_ref_or_deref (GObject *object,
{ {
/* We have no toggle ref set. We are done. */ /* We have no toggle ref set. We are done. */
g_datalist_unlock (&object->qdata); g_datalist_unlock (&object->qdata);
object_bit_unlock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS);
*toggle_notify = NULL; *toggle_notify = NULL;
return TRUE; return TRUE;
} }
@ -4208,7 +4204,6 @@ toggle_refs_check_and_ref_or_deref (GObject *object,
toggle_refs_check_and_ref_cb, toggle_refs_check_and_ref_cb,
(gpointer[2]){ toggle_notify, toggle_data }); (gpointer[2]){ toggle_notify, toggle_data });
object_bit_unlock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS);
return TRUE; return TRUE;
} }
@ -4301,8 +4296,6 @@ g_object_add_toggle_ref (GObject *object,
g_object_ref (object); g_object_ref (object);
object_bit_lock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS);
_g_datalist_id_update_atomic (&object->qdata, _g_datalist_id_update_atomic (&object->qdata,
quark_toggle_refs, quark_toggle_refs,
toggle_refs_ref_cb, toggle_refs_ref_cb,
@ -4311,8 +4304,6 @@ g_object_add_toggle_ref (GObject *object,
.tuple.notify = notify, .tuple.notify = notify,
.tuple.data = data, .tuple.data = data,
})); }));
object_bit_unlock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS);
} }
static gpointer static gpointer
@ -4380,8 +4371,6 @@ g_object_remove_toggle_ref (GObject *object,
g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (notify != NULL); g_return_if_fail (notify != NULL);
object_bit_lock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS);
result = _g_datalist_id_update_atomic (&object->qdata, result = _g_datalist_id_update_atomic (&object->qdata,
quark_toggle_refs, quark_toggle_refs,
toggle_refs_unref_cb, toggle_refs_unref_cb,
@ -4391,8 +4380,6 @@ g_object_remove_toggle_ref (GObject *object,
.tuple.data = data, .tuple.data = data,
})); }));
object_bit_unlock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS);
if (!GPOINTER_TO_INT (result)) if (!GPOINTER_TO_INT (result))
{ {
g_critical ("%s: couldn't find toggle ref %p(%p)", G_STRFUNC, notify, data); g_critical ("%s: couldn't find toggle ref %p(%p)", G_STRFUNC, notify, data);