From 827c208cbf9cc0ef17b8c4531a40aafe1edc3f01 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 4 Jun 2018 11:38:40 +0100 Subject: [PATCH] Use macros for refcount types API If we're using GCC we can use __extension__ to inline the grefcount and gatomicrefcount API, and avoid the function call. These macros are only enabled if G_DISABLE_CHECKS is defined, as they remove critical warnings when the reference counters achieve saturation. --- glib/grefcount.c | 20 +++++++------- glib/grefcount.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 10 deletions(-) diff --git a/glib/grefcount.c b/glib/grefcount.c index 10e35a217..37085316b 100644 --- a/glib/grefcount.c +++ b/glib/grefcount.c @@ -89,7 +89,7 @@ * Since: 2.58 */ void -g_ref_count_init (grefcount *rc) +(g_ref_count_init) (grefcount *rc) { g_return_if_fail (rc != NULL); @@ -114,7 +114,7 @@ g_ref_count_init (grefcount *rc) * Since: 2.58 */ void -g_ref_count_inc (grefcount *rc) +(g_ref_count_inc) (grefcount *rc) { grefcount rrc; @@ -147,7 +147,7 @@ g_ref_count_inc (grefcount *rc) * Since: 2.58 */ gboolean -g_ref_count_dec (grefcount *rc) +(g_ref_count_dec) (grefcount *rc) { grefcount rrc; @@ -179,8 +179,8 @@ g_ref_count_dec (grefcount *rc) * Since: 2.58 */ gboolean -g_ref_count_compare (grefcount *rc, - gint val) +(g_ref_count_compare) (grefcount *rc, + gint val) { grefcount rrc; @@ -204,7 +204,7 @@ g_ref_count_compare (grefcount *rc, * Since: 2.58 */ void -g_atomic_ref_count_init (gatomicrefcount *arc) +(g_atomic_ref_count_init) (gatomicrefcount *arc) { g_return_if_fail (arc != NULL); @@ -229,7 +229,7 @@ g_atomic_ref_count_init (gatomicrefcount *arc) * Since: 2.58 */ void -g_atomic_ref_count_inc (gatomicrefcount *arc) +(g_atomic_ref_count_inc) (gatomicrefcount *arc) { g_return_if_fail (arc != NULL); g_return_if_fail (g_atomic_int_get (arc) > 0); @@ -254,7 +254,7 @@ g_atomic_ref_count_inc (gatomicrefcount *arc) * Since: 2.58 */ gboolean -g_atomic_ref_count_dec (gatomicrefcount *arc) +(g_atomic_ref_count_dec) (gatomicrefcount *arc) { g_return_val_if_fail (arc != NULL, FALSE); g_return_val_if_fail (g_atomic_int_get (arc) > 0, FALSE); @@ -275,8 +275,8 @@ g_atomic_ref_count_dec (gatomicrefcount *arc) * Since: 2.58 */ gboolean -g_atomic_ref_count_compare (gatomicrefcount *arc, - gint val) +(g_atomic_ref_count_compare) (gatomicrefcount *arc, + gint val) { g_return_val_if_fail (arc != NULL, FALSE); g_return_val_if_fail (val >= 0, FALSE); diff --git a/glib/grefcount.h b/glib/grefcount.h index b24c71e8c..dec9a5ffb 100644 --- a/glib/grefcount.h +++ b/glib/grefcount.h @@ -47,6 +47,76 @@ GLIB_AVAILABLE_IN_2_58 gboolean g_atomic_ref_count_compare (gatomicrefcount *arc, gint val); +/* On GCC we can use __extension__ to inline the API without using + * ancillary functions; we only do this when disabling checks, as + * it disables warnings when saturating the reference counters + */ +#if defined(__GNUC__) && defined(G_DISABLE_CHECKS) + +# define g_ref_count_init(rc) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \ + (void) (0 ? *(rc) ^ *(rc) : 1); \ + *(rc) = -1; \ + })) + +# define g_ref_count_inc(rc) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \ + (void) (0 ? *(rc) ^ *(rc) : 1); \ + if (*(rc) == G_MININT) ; else { \ + *(rc) -= 1; \ + } \ + })) + +# define g_ref_count_dec(rc) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \ + grefcount __rc = *(rc); \ + __rc += 1; \ + if (__rc == 0) ; else { \ + *(rc) = __rc; \ + } \ + (gboolean) (__rc == 0); \ + })) + +# define g_ref_count_compare(rc,val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \ + (void) (0 ? *(rc) ^ (val) : 1); \ + (gboolean) (*(rc) == -(val)); \ + })) + +# define g_atomic_ref_count_init(rc) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \ + (void) (0 ? *(rc) ^ *(rc) : 1); \ + g_atomic_int_set ((rc), 1); \ + })) + +# define g_atomic_ref_count_inc(rc) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \ + (void) (0 ? *(rc) ^ *(rc) : 1); \ + (void) (g_atomic_int_get (rc) == G_MAXINT ? 0 : g_atomic_int_inc ((rc))); \ + })) + +# define g_atomic_ref_count_dec(rc) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \ + (void) (0 ? *(rc) ^ *(rc) : 1); \ + g_atomic_int_dec_and_test ((rc)); \ + })) + +# define g_atomic_ref_count_compare(rc,val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \ + (void) (0 ? *(rc) ^ (val) : 1); \ + (gboolean) (g_atomic_int_get (rc) == (val)); \ + })) + +#endif /* __GNUC__ && G_DISABLE_CHECKS */ + G_END_DECLS #endif /* __GREFCOUNT_H__ */