summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2018-06-04 11:38:40 +0100
committerEmmanuele Bassi <ebassi@gnome.org>2018-06-11 14:59:39 +0100
commit827c208cbf9cc0ef17b8c4531a40aafe1edc3f01 (patch)
tree7409c32ff349bf80c71822ee8c124ea90ba931f1
parent9e5a53d576765819d1c7c233515b9f6e5d77eb61 (diff)
downloadglib-827c208cbf9cc0ef17b8c4531a40aafe1edc3f01.tar.gz
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.
-rw-r--r--glib/grefcount.c20
-rw-r--r--glib/grefcount.h70
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__ */