From e54f27322d46f7026390c0a59cfc0a18bfa31612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 9 May 2023 14:06:21 +0200 Subject: [PATCH 1/4] gdataset: Use atomic compare and exchange full to set pointers In case first exchange failed we can avoid repeating the pointer get operation given that exchange full can provide us the old value. --- glib/gdataset.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/glib/gdataset.c b/glib/gdataset.c index 500022630..c8461d943 100644 --- a/glib/gdataset.c +++ b/glib/gdataset.c @@ -144,12 +144,13 @@ #define G_DATALIST_GET_POINTER(datalist) \ ((GData*) ((gsize) g_atomic_pointer_get (datalist) & ~(gsize) G_DATALIST_FLAGS_MASK_INTERNAL)) -#define G_DATALIST_SET_POINTER(datalist, pointer) G_STMT_START { \ - gpointer _oldv, _newv; \ - do { \ - _oldv = g_atomic_pointer_get (datalist); \ +#define G_DATALIST_SET_POINTER(datalist, pointer) G_STMT_START { \ + gpointer _oldv = g_atomic_pointer_get (datalist); \ + gpointer _newv; \ + do { \ _newv = (gpointer) (((gsize) _oldv & G_DATALIST_FLAGS_MASK_INTERNAL) | (gsize) pointer); \ - } while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, _oldv, _newv)); \ + } while (!g_atomic_pointer_compare_and_exchange_full ((void**) datalist, _oldv, \ + _newv, &_oldv)); \ } G_STMT_END /* --- structures --- */ From f792b2ce64aeb5ffd9ef8a88d56454e7664a9b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 9 May 2023 14:18:50 +0200 Subject: [PATCH 2/4] gobject: Use atomic compare and exchange full to force floating In case first exchange failed we can avoid repeating the pointer get operation given that exchange full can provide us the old value. --- gobject/gobject.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/gobject/gobject.c b/gobject/gobject.c index a61754b9f..62bf6d0ef 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -3436,16 +3436,20 @@ object_floating_flag_handler (GObject *object, { gpointer oldvalue; case +1: /* force floating if possible */ - do - oldvalue = g_atomic_pointer_get (&object->qdata); - while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue, - (gpointer) ((gsize) oldvalue | OBJECT_FLOATING_FLAG))); + oldvalue = g_atomic_pointer_get (&object->qdata); + while (!g_atomic_pointer_compare_and_exchange_full ( + (void**) &object->qdata, oldvalue, + (void *) ((gsize) oldvalue | OBJECT_FLOATING_FLAG), + &oldvalue)) + ; return (gsize) oldvalue & OBJECT_FLOATING_FLAG; case -1: /* sink if possible */ - do - oldvalue = g_atomic_pointer_get (&object->qdata); - while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue, - (gpointer) ((gsize) oldvalue & ~(gsize) OBJECT_FLOATING_FLAG))); + oldvalue = g_atomic_pointer_get (&object->qdata); + while (!g_atomic_pointer_compare_and_exchange_full ( + (void**) &object->qdata, oldvalue, + (void *) ((gsize) oldvalue & ~(gsize) OBJECT_FLOATING_FLAG), + &oldvalue)) + ; return (gsize) oldvalue & OBJECT_FLOATING_FLAG; default: /* check floating */ return 0 != ((gsize) g_atomic_pointer_get (&object->qdata) & OBJECT_FLOATING_FLAG); From 28f83c9cf7d236c35ca9b0e1443f81a0fe8ef0c8 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Tue, 30 May 2023 12:31:55 +0100 Subject: [PATCH 3/4] gresource: Ensure lazy_register_resources is always accessed atomically On some platforms, pointer-sized reads are not necessarily atomic, so we always need to use the correct atomic access primitives. Signed-off-by: Philip Withnall --- gio/gresource.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gio/gresource.c b/gio/gresource.c index 4ccd33364..6c23d4cfe 100644 --- a/gio/gresource.c +++ b/gio/gresource.c @@ -1367,7 +1367,7 @@ register_lazy_static_resources_unlocked (void) GStaticResource *list; do - list = lazy_register_resources; + list = g_atomic_pointer_get (&lazy_register_resources); while (!g_atomic_pointer_compare_and_exchange (&lazy_register_resources, list, NULL)); while (list != NULL) @@ -1416,7 +1416,7 @@ g_static_resource_init (GStaticResource *static_resource) do { - next = lazy_register_resources; + next = g_atomic_pointer_get (&lazy_register_resources); static_resource->next = next; } while (!g_atomic_pointer_compare_and_exchange (&lazy_register_resources, next, static_resource)); From ea904fba1a32a9642256275d2017efe811462fb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 9 May 2023 14:25:44 +0200 Subject: [PATCH 4/4] gresource: Use compare and exchange full to get registered resources --- gio/gresource.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gio/gresource.c b/gio/gresource.c index 6c23d4cfe..a67df11ef 100644 --- a/gio/gresource.c +++ b/gio/gresource.c @@ -1364,11 +1364,10 @@ g_resources_get_info (const gchar *path, static void register_lazy_static_resources_unlocked (void) { - GStaticResource *list; + GStaticResource *list = g_atomic_pointer_get (&lazy_register_resources); - do - list = g_atomic_pointer_get (&lazy_register_resources); - while (!g_atomic_pointer_compare_and_exchange (&lazy_register_resources, list, NULL)); + while (!g_atomic_pointer_compare_and_exchange_full (&lazy_register_resources, list, NULL, &list)) + ; while (list != NULL) {