clock: Use g_atomic_rc_box for refcounting entry clocks

g_atomic_rc_box was added in GLib 2.58, and we require 2.62 now, so we
can fix the FIXME and use this.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2568>
This commit is contained in:
Nirbheek Chauhan 2022-06-08 11:33:22 +05:30 committed by GStreamer Marge Bot
parent 9d9e59622f
commit 604b92b9cb
2 changed files with 24 additions and 69 deletions

View file

@ -514,14 +514,11 @@ struct _GstDynamicTypeFactoryClass {
/* privat flag used by GstBus / GstMessage */
#define GST_MESSAGE_FLAG_ASYNC_DELIVERY (GST_MINI_OBJECT_FLAG_LAST << 0)
/* private type used by GstClock */
typedef struct _GstClockWeakRef GstClockWeakRef;
/* private struct used by GstClock and GstSystemClock */
struct _GstClockEntryImpl
{
GstClockEntry entry;
GstClockWeakRef *weakref;
GWeakRef *clock;
GDestroyNotify destroy_entry;
gpointer padding[21]; /* padding for allowing e.g. systemclock
* to add data in lieu of overridable

View file

@ -132,60 +132,6 @@ enum
#define GST_CLOCK_SLAVE_LOCK(clock) g_mutex_lock (&GST_CLOCK_CAST (clock)->priv->slave_lock)
#define GST_CLOCK_SLAVE_UNLOCK(clock) g_mutex_unlock (&GST_CLOCK_CAST (clock)->priv->slave_lock)
/* An atomically ref-counted wrapper around a GWeakRef for a GstClock, created
* by the clock and shared with all its clock entries.
*
* This exists because g_weak_ref_ operations are quite expensive and operate
* with a global GRWLock. _get takes a reader lock, _init and _clear take a
* writer lock. We want to avoid having a GWeakRef in every clock entry.
*
* FIXME: Simplify this with g_atomic_rc_box_new (GWeakRef) once we can depend
* on GLib 2.58.
*/
struct _GstClockWeakRef
{
gint refcount;
GWeakRef clock;
};
static GstClockWeakRef *
gst_clock_weak_ref_new (GstClock * clock)
{
GstClockWeakRef *weakref = g_slice_new (GstClockWeakRef);
weakref->refcount = 1;
g_weak_ref_init (&weakref->clock, clock);
return weakref;
}
static GstClockWeakRef *
gst_clock_weak_ref_ref (GstClockWeakRef * weakref)
{
g_atomic_int_add (&weakref->refcount, 1);
return weakref;
}
static void
gst_clock_weak_ref_unref (GstClockWeakRef * weakref)
{
gint old_refcount;
old_refcount = g_atomic_int_add (&weakref->refcount, -1);
g_return_if_fail (old_refcount > 0);
if (G_UNLIKELY (old_refcount == 1)) {
g_weak_ref_clear (&weakref->clock);
g_slice_free (GstClockWeakRef, weakref);
}
}
static GstClock *
gst_clock_weak_ref_get (GstClockWeakRef * weakref)
{
return g_weak_ref_get (&weakref->clock);
}
struct _GstClockPrivate
{
GMutex slave_lock; /* order: SLAVE_LOCK, OBJECT_LOCK */
@ -220,12 +166,12 @@ struct _GstClockPrivate
gboolean synced;
GstClockWeakRef *weakref;
GWeakRef *clock_weakref;
};
typedef struct _GstClockEntryImpl GstClockEntryImpl;
#define GST_CLOCK_ENTRY_CLOCK_WEAK_REF(entry) (((GstClockEntryImpl *)(entry))->weakref)
#define GST_CLOCK_ENTRY_CLOCK_WEAK_REF(entry) (((GstClockEntryImpl *)(entry))->clock)
/* seqlocks */
#define read_seqbegin(clock) \
@ -317,7 +263,7 @@ gst_clock_entry_new (GstClock * clock, GstClockTime time,
#endif
#endif
GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry) =
gst_clock_weak_ref_ref (clock->priv->weakref);
g_atomic_rc_box_acquire (clock->priv->clock_weakref);
entry->type = type;
entry->time = time;
entry->interval = interval;
@ -431,7 +377,8 @@ _gst_clock_id_free (GstClockID id)
if (entry_impl->destroy_entry)
entry_impl->destroy_entry (entry_impl);
gst_clock_weak_ref_unref (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry));
g_atomic_rc_box_release_full (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry),
(GDestroyNotify) g_weak_ref_clear);
/* FIXME: add tracer hook for struct allocations such as clock entries */
@ -588,7 +535,7 @@ gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
entry = (GstClockEntry *) id;
requested = GST_CLOCK_ENTRY_TIME (entry);
clock = gst_clock_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry));
clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry));
if (G_UNLIKELY (clock == NULL))
goto invalid_entry;
@ -670,7 +617,7 @@ gst_clock_id_wait_async (GstClockID id,
entry = (GstClockEntry *) id;
requested = GST_CLOCK_ENTRY_TIME (entry);
clock = gst_clock_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry));
clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry));
if (G_UNLIKELY (clock == NULL))
goto invalid_entry;
@ -733,7 +680,7 @@ gst_clock_id_unschedule (GstClockID id)
g_return_if_fail (id != NULL);
entry = (GstClockEntry *) id;
clock = gst_clock_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry));
clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry));
if (G_UNLIKELY (clock == NULL))
goto invalid_entry;
@ -826,7 +773,17 @@ gst_clock_init (GstClock * clock)
priv->timeout = DEFAULT_TIMEOUT;
priv->times = g_new0 (GstClockTime, 4 * priv->window_size);
priv->times_temp = priv->times + 2 * priv->window_size;
priv->weakref = gst_clock_weak_ref_new (clock);
/*
* An atomically ref-counted wrapper around a GWeakRef for this GstClock,
* created by the clock and shared with all its clock entries.
*
* This exists because g_weak_ref_ operations are quite expensive and operate
* with a global GRWLock. _get takes a reader lock, _init and _clear take
* a writer lock. We want to avoid having to instantiate a new GWeakRef for
* every clock entry.
*/
priv->clock_weakref = g_atomic_rc_box_new (GWeakRef);
g_weak_ref_init (priv->clock_weakref, clock);
}
static void
@ -859,7 +816,8 @@ gst_clock_finalize (GObject * object)
clock->priv->times_temp = NULL;
GST_CLOCK_SLAVE_UNLOCK (clock);
gst_clock_weak_ref_unref (clock->priv->weakref);
g_atomic_rc_box_release_full (clock->priv->clock_weakref,
(GDestroyNotify) g_weak_ref_clear);
g_mutex_clear (&clock->priv->slave_lock);
g_cond_clear (&clock->priv->sync_cond);
@ -1433,7 +1391,7 @@ gst_clock_id_get_clock (GstClockID id)
g_return_val_if_fail (id != NULL, NULL);
entry = (GstClockEntry *) id;
return gst_clock_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry));
return g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry));
}
/**
@ -1460,7 +1418,7 @@ gst_clock_id_uses_clock (GstClockID id, GstClock * clock)
g_return_val_if_fail (clock != NULL, FALSE);
entry = (GstClockEntry *) id;
entry_clock = gst_clock_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry));
entry_clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry));
if (entry_clock == clock)
ret = TRUE;