gobject: use per-object bit-lock instead of global mutex for notify-queue

This commit is contained in:
Thomas Haller 2023-12-20 09:55:32 +01:00
parent c66880e46f
commit cf044ba7ad

View File

@ -124,6 +124,7 @@ enum {
* 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_WEAK_REFS 1 #define OPTIONAL_BIT_LOCK_WEAK_REFS 1
#define OPTIONAL_BIT_LOCK_NOTIFY 2
#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
@ -232,8 +233,6 @@ static guint (*floating_flag_handler) (GObject*, gint) = object_floating_flag_ha
static GQuark quark_weak_locations = 0; static GQuark quark_weak_locations = 0;
static GRWLock weak_locations_lock; static GRWLock weak_locations_lock;
G_LOCK_DEFINE_STATIC(notify_lock);
#if HAVE_PRIVATE #if HAVE_PRIVATE
G_ALWAYS_INLINE static inline GObjectPrivate * G_ALWAYS_INLINE static inline GObjectPrivate *
g_object_get_instance_private (GObject *object) g_object_get_instance_private (GObject *object)
@ -321,7 +320,7 @@ g_object_notify_queue_freeze (GObject *object)
{ {
GObjectNotifyQueue *nqueue; GObjectNotifyQueue *nqueue;
G_LOCK(notify_lock); object_bit_lock (object, OPTIONAL_BIT_LOCK_NOTIFY);
nqueue = g_datalist_id_get_data (&object->qdata, quark_notify_queue); nqueue = g_datalist_id_get_data (&object->qdata, quark_notify_queue);
if (!nqueue) if (!nqueue)
{ {
@ -338,7 +337,7 @@ g_object_notify_queue_freeze (GObject *object)
nqueue->freeze_count++; nqueue->freeze_count++;
out: out:
G_UNLOCK(notify_lock); object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
return nqueue; return nqueue;
} }
@ -352,7 +351,7 @@ g_object_notify_queue_thaw (GObject *object,
GSList *slist; GSList *slist;
guint n_pspecs = 0; guint n_pspecs = 0;
G_LOCK(notify_lock); object_bit_lock (object, OPTIONAL_BIT_LOCK_NOTIFY);
if (!nqueue) if (!nqueue)
{ {
@ -363,7 +362,7 @@ g_object_notify_queue_thaw (GObject *object,
/* Just make sure we never get into some nasty race condition */ /* Just make sure we never get into some nasty race condition */
if (G_UNLIKELY (!nqueue || nqueue->freeze_count == 0)) if (G_UNLIKELY (!nqueue || nqueue->freeze_count == 0))
{ {
G_UNLOCK (notify_lock); object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
g_critical ("%s: property-changed notification for %s(%p) is not frozen", g_critical ("%s: property-changed notification for %s(%p) is not frozen",
G_STRFUNC, G_OBJECT_TYPE_NAME (object), object); G_STRFUNC, G_OBJECT_TYPE_NAME (object), object);
return; return;
@ -372,7 +371,7 @@ g_object_notify_queue_thaw (GObject *object,
nqueue->freeze_count--; nqueue->freeze_count--;
if (nqueue->freeze_count) if (nqueue->freeze_count)
{ {
G_UNLOCK (notify_lock); object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
return; return;
} }
@ -384,7 +383,7 @@ g_object_notify_queue_thaw (GObject *object,
} }
g_datalist_id_set_data (&object->qdata, quark_notify_queue, NULL); g_datalist_id_set_data (&object->qdata, quark_notify_queue, NULL);
G_UNLOCK(notify_lock); object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
if (n_pspecs) if (n_pspecs)
{ {
@ -405,7 +404,7 @@ g_object_notify_queue_add (GObject *object,
GParamSpec *pspec, GParamSpec *pspec,
gboolean in_init) gboolean in_init)
{ {
G_LOCK(notify_lock); object_bit_lock (object, OPTIONAL_BIT_LOCK_NOTIFY);
if (!nqueue) if (!nqueue)
{ {
@ -419,7 +418,7 @@ g_object_notify_queue_add (GObject *object,
{ {
/* We don't have a notify queue and are not in_init. The event /* We don't have a notify queue and are not in_init. The event
* is not to be queued. The caller will dispatch directly. */ * is not to be queued. The caller will dispatch directly. */
G_UNLOCK (notify_lock); object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
return FALSE; return FALSE;
} }
@ -442,7 +441,7 @@ g_object_notify_queue_add (GObject *object,
nqueue->n_pspecs++; nqueue->n_pspecs++;
} }
G_UNLOCK(notify_lock); object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
return TRUE; return TRUE;
} }