mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-03 17:56:17 +01:00
gatomic: Use g(u)intptr where appropriate
This is required for CHERI systems such as Arm Morello, where gsize is not large enough to hold a pointer. For all other architectures this should not result in any functional changes since gsize is already the same size (and I believe for most architectures even the same type) as guintptr. This is fully ABI compatible with all currently supported architectures and should also be fully API compatible except for some rather unlikely examples such as someone happening to use something like `decltype(g_atomic_pointer_add(&a, 0))` in a C++ context where it changes name mangling of some function. Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/2842
This commit is contained in:
parent
877c575cd9
commit
c762d51134
@ -34,7 +34,7 @@
|
||||
*
|
||||
* The macros that have 'int' in the name will operate on pointers to
|
||||
* #gint and #guint. The macros with 'pointer' in the name will operate
|
||||
* on pointers to any pointer-sized value, including #gsize. There is
|
||||
* on pointers to any pointer-sized value, including #guintptr. There is
|
||||
* no support for 64bit operations on platforms with 32bit pointers
|
||||
* because it is not generally possible to perform these operations
|
||||
* atomically.
|
||||
@ -538,11 +538,15 @@ gpointer
|
||||
* While @atomic has a `volatile` qualifier, this is a historical artifact and
|
||||
* the pointer passed to it should not be `volatile`.
|
||||
*
|
||||
* In GLib 2.80, the return type was changed from #gssize to #gintptr to add
|
||||
* support for platforms with 128-bit pointers. This should not affect existing
|
||||
* code.
|
||||
*
|
||||
* Returns: the value of @atomic before the add, signed
|
||||
*
|
||||
* Since: 2.30
|
||||
**/
|
||||
gssize
|
||||
gintptr
|
||||
(g_atomic_pointer_add) (volatile void *atomic,
|
||||
gssize val)
|
||||
{
|
||||
@ -565,11 +569,15 @@ gssize
|
||||
* While @atomic has a `volatile` qualifier, this is a historical artifact and
|
||||
* the pointer passed to it should not be `volatile`.
|
||||
*
|
||||
* In GLib 2.80, the return type was changed from #gsize to #guintptr to add
|
||||
* support for platforms with 128-bit pointers. This should not affect existing
|
||||
* code.
|
||||
*
|
||||
* Returns: the value of @atomic before the operation, unsigned
|
||||
*
|
||||
* Since: 2.30
|
||||
**/
|
||||
gsize
|
||||
guintptr
|
||||
(g_atomic_pointer_and) (volatile void *atomic,
|
||||
gsize val)
|
||||
{
|
||||
@ -592,11 +600,15 @@ gsize
|
||||
* While @atomic has a `volatile` qualifier, this is a historical artifact and
|
||||
* the pointer passed to it should not be `volatile`.
|
||||
*
|
||||
* In GLib 2.80, the return type was changed from #gsize to #guintptr to add
|
||||
* support for platforms with 128-bit pointers. This should not affect existing
|
||||
* code.
|
||||
*
|
||||
* Returns: the value of @atomic before the operation, unsigned
|
||||
*
|
||||
* Since: 2.30
|
||||
**/
|
||||
gsize
|
||||
guintptr
|
||||
(g_atomic_pointer_or) (volatile void *atomic,
|
||||
gsize val)
|
||||
{
|
||||
@ -619,11 +631,15 @@ gsize
|
||||
* While @atomic has a `volatile` qualifier, this is a historical artifact and
|
||||
* the pointer passed to it should not be `volatile`.
|
||||
*
|
||||
* In GLib 2.80, the return type was changed from #gsize to #guintptr to add
|
||||
* support for platforms with 128-bit pointers. This should not affect existing
|
||||
* code.
|
||||
*
|
||||
* Returns: the value of @atomic before the operation, unsigned
|
||||
*
|
||||
* Since: 2.30
|
||||
**/
|
||||
gsize
|
||||
guintptr
|
||||
(g_atomic_pointer_xor) (volatile void *atomic,
|
||||
gsize val)
|
||||
{
|
||||
@ -820,7 +836,7 @@ gpointer
|
||||
return InterlockedExchangePointer (atomic, newval);
|
||||
}
|
||||
|
||||
gssize
|
||||
gintptr
|
||||
(g_atomic_pointer_add) (volatile void *atomic,
|
||||
gssize val)
|
||||
{
|
||||
@ -831,7 +847,7 @@ gssize
|
||||
#endif
|
||||
}
|
||||
|
||||
gsize
|
||||
guintptr
|
||||
(g_atomic_pointer_and) (volatile void *atomic,
|
||||
gsize val)
|
||||
{
|
||||
@ -842,7 +858,7 @@ gsize
|
||||
#endif
|
||||
}
|
||||
|
||||
gsize
|
||||
guintptr
|
||||
(g_atomic_pointer_or) (volatile void *atomic,
|
||||
gsize val)
|
||||
{
|
||||
@ -853,7 +869,7 @@ gsize
|
||||
#endif
|
||||
}
|
||||
|
||||
gsize
|
||||
guintptr
|
||||
(g_atomic_pointer_xor) (volatile void *atomic,
|
||||
gsize val)
|
||||
{
|
||||
@ -1112,12 +1128,12 @@ gpointer
|
||||
return oldval;
|
||||
}
|
||||
|
||||
gssize
|
||||
gintptr
|
||||
(g_atomic_pointer_add) (volatile void *atomic,
|
||||
gssize val)
|
||||
{
|
||||
gssize *ptr = atomic;
|
||||
gssize oldval;
|
||||
gintptr *ptr = atomic;
|
||||
gintptr oldval;
|
||||
|
||||
pthread_mutex_lock (&g_atomic_lock);
|
||||
oldval = *ptr;
|
||||
@ -1127,12 +1143,12 @@ gssize
|
||||
return oldval;
|
||||
}
|
||||
|
||||
gsize
|
||||
guintptr
|
||||
(g_atomic_pointer_and) (volatile void *atomic,
|
||||
gsize val)
|
||||
{
|
||||
gsize *ptr = atomic;
|
||||
gsize oldval;
|
||||
guintptr *ptr = atomic;
|
||||
guintptr oldval;
|
||||
|
||||
pthread_mutex_lock (&g_atomic_lock);
|
||||
oldval = *ptr;
|
||||
@ -1142,12 +1158,12 @@ gsize
|
||||
return oldval;
|
||||
}
|
||||
|
||||
gsize
|
||||
guintptr
|
||||
(g_atomic_pointer_or) (volatile void *atomic,
|
||||
gsize val)
|
||||
{
|
||||
gsize *ptr = atomic;
|
||||
gsize oldval;
|
||||
guintptr *ptr = atomic;
|
||||
guintptr oldval;
|
||||
|
||||
pthread_mutex_lock (&g_atomic_lock);
|
||||
oldval = *ptr;
|
||||
@ -1157,12 +1173,12 @@ gsize
|
||||
return oldval;
|
||||
}
|
||||
|
||||
gsize
|
||||
guintptr
|
||||
(g_atomic_pointer_xor) (volatile void *atomic,
|
||||
gsize val)
|
||||
{
|
||||
gsize *ptr = atomic;
|
||||
gsize oldval;
|
||||
guintptr *ptr = atomic;
|
||||
guintptr oldval;
|
||||
|
||||
pthread_mutex_lock (&g_atomic_lock);
|
||||
oldval = *ptr;
|
||||
|
@ -83,16 +83,16 @@ GLIB_AVAILABLE_IN_2_74
|
||||
gpointer g_atomic_pointer_exchange (void *atomic,
|
||||
gpointer newval);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
gssize g_atomic_pointer_add (volatile void *atomic,
|
||||
gintptr g_atomic_pointer_add (volatile void *atomic,
|
||||
gssize val);
|
||||
GLIB_AVAILABLE_IN_2_30
|
||||
gsize g_atomic_pointer_and (volatile void *atomic,
|
||||
guintptr g_atomic_pointer_and (volatile void *atomic,
|
||||
gsize val);
|
||||
GLIB_AVAILABLE_IN_2_30
|
||||
gsize g_atomic_pointer_or (volatile void *atomic,
|
||||
guintptr g_atomic_pointer_or (volatile void *atomic,
|
||||
gsize val);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
gsize g_atomic_pointer_xor (volatile void *atomic,
|
||||
guintptr g_atomic_pointer_xor (volatile void *atomic,
|
||||
gsize val);
|
||||
|
||||
GLIB_DEPRECATED_IN_2_30_FOR(g_atomic_int_add)
|
||||
@ -280,34 +280,34 @@ G_END_DECLS
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : NULL); \
|
||||
(void) (0 ? (val) ^ (val) : 1); \
|
||||
(gssize) __atomic_fetch_add ((atomic), (val), __ATOMIC_SEQ_CST); \
|
||||
(gintptr) __atomic_fetch_add ((atomic), (val), __ATOMIC_SEQ_CST); \
|
||||
}))
|
||||
#define g_atomic_pointer_and(atomic, val) \
|
||||
(G_GNUC_EXTENSION ({ \
|
||||
gsize *gapa_atomic = (gsize *) (atomic); \
|
||||
guintptr *gapa_atomic = (guintptr *) (atomic); \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize)); \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (guintptr)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : NULL); \
|
||||
(void) (0 ? (val) ^ (val) : 1); \
|
||||
(gsize) __atomic_fetch_and (gapa_atomic, (val), __ATOMIC_SEQ_CST); \
|
||||
(guintptr) __atomic_fetch_and (gapa_atomic, (val), __ATOMIC_SEQ_CST); \
|
||||
}))
|
||||
#define g_atomic_pointer_or(atomic, val) \
|
||||
(G_GNUC_EXTENSION ({ \
|
||||
gsize *gapo_atomic = (gsize *) (atomic); \
|
||||
guintptr *gapo_atomic = (guintptr *) (atomic); \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize)); \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (guintptr)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : NULL); \
|
||||
(void) (0 ? (val) ^ (val) : 1); \
|
||||
(gsize) __atomic_fetch_or (gapo_atomic, (val), __ATOMIC_SEQ_CST); \
|
||||
(guintptr) __atomic_fetch_or (gapo_atomic, (val), __ATOMIC_SEQ_CST); \
|
||||
}))
|
||||
#define g_atomic_pointer_xor(atomic, val) \
|
||||
(G_GNUC_EXTENSION ({ \
|
||||
gsize *gapx_atomic = (gsize *) (atomic); \
|
||||
guintptr *gapx_atomic = (guintptr *) (atomic); \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize)); \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (guintptr)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : NULL); \
|
||||
(void) (0 ? (val) ^ (val) : 1); \
|
||||
(gsize) __atomic_fetch_xor (gapx_atomic, (val), __ATOMIC_SEQ_CST); \
|
||||
(guintptr) __atomic_fetch_xor (gapx_atomic, (val), __ATOMIC_SEQ_CST); \
|
||||
}))
|
||||
|
||||
#else /* defined(__ATOMIC_SEQ_CST) */
|
||||
@ -374,7 +374,7 @@ G_END_DECLS
|
||||
(void) (0 ? (gpointer) *(atomic) : NULL); \
|
||||
__sync_synchronize (); \
|
||||
__asm__ __volatile__ ("" : : : "memory"); \
|
||||
*(atomic) = (glib_typeof (*(atomic))) (gsize) (newval); \
|
||||
*(atomic) = (glib_typeof (*(atomic))) (guintptr) (newval); \
|
||||
}))
|
||||
#else /* if !(defined(glib_typeof) */
|
||||
#define g_atomic_pointer_set(atomic, newval) \
|
||||
@ -383,7 +383,7 @@ G_END_DECLS
|
||||
(void) (0 ? (gpointer) *(atomic) : NULL); \
|
||||
__sync_synchronize (); \
|
||||
__asm__ __volatile__ ("" : : : "memory"); \
|
||||
*(atomic) = (gpointer) (gsize) (newval); \
|
||||
*(atomic) = (gpointer) (guintptr) (newval); \
|
||||
}))
|
||||
#endif /* if defined(glib_typeof) */
|
||||
|
||||
@ -498,28 +498,28 @@ G_END_DECLS
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : NULL); \
|
||||
(void) (0 ? (val) ^ (val) : 1); \
|
||||
(gssize) __sync_fetch_and_add ((atomic), (val)); \
|
||||
(gintptr) __sync_fetch_and_add ((atomic), (val)); \
|
||||
}))
|
||||
#define g_atomic_pointer_and(atomic, val) \
|
||||
(G_GNUC_EXTENSION ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : NULL); \
|
||||
(void) (0 ? (val) ^ (val) : 1); \
|
||||
(gsize) __sync_fetch_and_and ((atomic), (val)); \
|
||||
(guintptr) __sync_fetch_and_and ((atomic), (val)); \
|
||||
}))
|
||||
#define g_atomic_pointer_or(atomic, val) \
|
||||
(G_GNUC_EXTENSION ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : NULL); \
|
||||
(void) (0 ? (val) ^ (val) : 1); \
|
||||
(gsize) __sync_fetch_and_or ((atomic), (val)); \
|
||||
(guintptr) __sync_fetch_and_or ((atomic), (val)); \
|
||||
}))
|
||||
#define g_atomic_pointer_xor(atomic, val) \
|
||||
(G_GNUC_EXTENSION ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : NULL); \
|
||||
(void) (0 ? (val) ^ (val) : 1); \
|
||||
(gsize) __sync_fetch_and_xor ((atomic), (val)); \
|
||||
(guintptr) __sync_fetch_and_xor ((atomic), (val)); \
|
||||
}))
|
||||
|
||||
#endif /* !defined(__ATOMIC_SEQ_CST) */
|
||||
|
@ -31,7 +31,7 @@ test_types (void)
|
||||
const char *str = "Hello";
|
||||
const char *old_str;
|
||||
int *ip, *ip2;
|
||||
gsize gs, gs2;
|
||||
guintptr gu, gu2;
|
||||
gboolean res;
|
||||
|
||||
csp = &s;
|
||||
@ -158,36 +158,36 @@ test_types (void)
|
||||
res = g_atomic_pointer_compare_and_exchange_full (&ip, NULL, &s, &ip2);
|
||||
g_assert_true (res);
|
||||
g_assert_true (ip == &s);
|
||||
g_assert_cmpuint ((gsize) ip2, ==, 0);
|
||||
g_assert_cmpuint ((guintptr) ip2, ==, 0);
|
||||
|
||||
res = g_atomic_pointer_compare_and_exchange_full (&ip, NULL, NULL, &ip2);
|
||||
g_assert_false (res);
|
||||
g_assert_true (ip == &s);
|
||||
g_assert_true (ip2 == &s);
|
||||
|
||||
g_atomic_pointer_set (&gs, 0);
|
||||
vp2 = (gpointer) g_atomic_pointer_get (&gs);
|
||||
gs2 = (gsize) vp2;
|
||||
g_assert_cmpuint (gs2, ==, 0);
|
||||
res = g_atomic_pointer_compare_and_exchange (&gs, NULL, (gsize) NULL);
|
||||
g_atomic_pointer_set (&gu, 0);
|
||||
vp2 = (gpointer) g_atomic_pointer_get (&gu);
|
||||
gu2 = (guintptr) vp2;
|
||||
g_assert_cmpuint (gu2, ==, 0);
|
||||
res = g_atomic_pointer_compare_and_exchange (&gu, NULL, (guintptr) NULL);
|
||||
g_assert_true (res);
|
||||
g_assert_cmpuint (gs, ==, 0);
|
||||
res = g_atomic_pointer_compare_and_exchange_full (&gs, (gsize) NULL, (gsize) NULL, &gs2);
|
||||
g_assert_cmpuint (gu, ==, 0);
|
||||
res = g_atomic_pointer_compare_and_exchange_full (&gu, (guintptr) NULL, (guintptr) NULL, &gu2);
|
||||
g_assert_true (res);
|
||||
g_assert_cmpuint (gs, ==, 0);
|
||||
g_assert_cmpuint (gs2, ==, 0);
|
||||
gs2 = (gsize) g_atomic_pointer_add (&gs, 5);
|
||||
g_assert_cmpuint (gs2, ==, 0);
|
||||
g_assert_cmpuint (gs, ==, 5);
|
||||
gs2 = g_atomic_pointer_and (&gs, 6);
|
||||
g_assert_cmpuint (gs2, ==, 5);
|
||||
g_assert_cmpuint (gs, ==, 4);
|
||||
gs2 = g_atomic_pointer_or (&gs, 8);
|
||||
g_assert_cmpuint (gs2, ==, 4);
|
||||
g_assert_cmpuint (gs, ==, 12);
|
||||
gs2 = g_atomic_pointer_xor (&gs, 4);
|
||||
g_assert_cmpuint (gs2, ==, 12);
|
||||
g_assert_cmpuint (gs, ==, 8);
|
||||
g_assert_cmpuint (gu, ==, 0);
|
||||
g_assert_cmpuint (gu2, ==, 0);
|
||||
gu2 = (guintptr) g_atomic_pointer_add (&gu, 5);
|
||||
g_assert_cmpuint (gu2, ==, 0);
|
||||
g_assert_cmpuint (gu, ==, 5);
|
||||
gu2 = g_atomic_pointer_and (&gu, 6);
|
||||
g_assert_cmpuint (gu2, ==, 5);
|
||||
g_assert_cmpuint (gu, ==, 4);
|
||||
gu2 = g_atomic_pointer_or (&gu, 8);
|
||||
g_assert_cmpuint (gu2, ==, 4);
|
||||
g_assert_cmpuint (gu, ==, 12);
|
||||
gu2 = g_atomic_pointer_xor (&gu, 4);
|
||||
g_assert_cmpuint (gu2, ==, 12);
|
||||
g_assert_cmpuint (gu, ==, 8);
|
||||
vp_str2 = g_atomic_pointer_exchange (&vp_str, str);
|
||||
g_assert_cmpstr (vp_str, ==, str);
|
||||
g_assert_null (vp_str2);
|
||||
@ -340,41 +340,41 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
res = g_atomic_pointer_compare_and_exchange_full (&ip, NULL, (gpointer) 1, &cp);
|
||||
g_assert_true (res);
|
||||
g_assert_cmpint ((gsize) ip, ==, 1);
|
||||
g_assert_cmpuint ((gsize) cp, ==, 0);
|
||||
g_assert_cmpint ((guintptr) ip, ==, 1);
|
||||
g_assert_cmpuint ((guintptr) cp, ==, 0);
|
||||
|
||||
res = g_atomic_pointer_compare_and_exchange_full (&ip, NULL, NULL, &cp);
|
||||
g_assert_false (res);
|
||||
g_assert_cmpuint ((gsize) ip, ==, 1);
|
||||
g_assert_cmpuint ((gsize) cp, ==, 1);
|
||||
g_assert_cmpuint ((guintptr) ip, ==, 1);
|
||||
g_assert_cmpuint ((guintptr) cp, ==, 1);
|
||||
|
||||
g_atomic_pointer_set (&gs, 0);
|
||||
vp = g_atomic_pointer_get (&gs);
|
||||
gs2 = (gsize) vp;
|
||||
g_assert_cmpuint (gs2, ==, 0);
|
||||
res = g_atomic_pointer_compare_and_exchange (&gs, NULL, NULL);
|
||||
g_atomic_pointer_set (&gu, 0);
|
||||
vp = g_atomic_pointer_get (&gu);
|
||||
gu2 = (guintptr) vp;
|
||||
g_assert_cmpuint (gu2, ==, 0);
|
||||
res = g_atomic_pointer_compare_and_exchange (&gu, NULL, NULL);
|
||||
g_assert_true (res);
|
||||
g_assert_cmpuint (gs, ==, 0);
|
||||
res = g_atomic_pointer_compare_and_exchange_full (&gs, NULL, NULL, &cp);
|
||||
g_assert_cmpuint (gu, ==, 0);
|
||||
res = g_atomic_pointer_compare_and_exchange_full (&gu, NULL, NULL, &cp);
|
||||
g_assert_true (res);
|
||||
g_assert_cmpuint (gs, ==, 0);
|
||||
g_assert_cmpuint ((gsize) cp, ==, 0);
|
||||
gs2 = (gsize) g_atomic_pointer_add (&gs, 5);
|
||||
g_assert_cmpuint (gs2, ==, 0);
|
||||
g_assert_cmpuint (gs, ==, 5);
|
||||
gs2 = g_atomic_pointer_and (&gs, 6);
|
||||
g_assert_cmpuint (gs2, ==, 5);
|
||||
g_assert_cmpuint (gs, ==, 4);
|
||||
gs2 = g_atomic_pointer_or (&gs, 8);
|
||||
g_assert_cmpuint (gs2, ==, 4);
|
||||
g_assert_cmpuint (gs, ==, 12);
|
||||
gs2 = g_atomic_pointer_xor (&gs, 4);
|
||||
g_assert_cmpuint (gs2, ==, 12);
|
||||
g_assert_cmpuint (gs, ==, 8);
|
||||
vp2 = g_atomic_pointer_exchange (&gs, NULL);
|
||||
gs2 = (gsize) vp2;
|
||||
g_assert_cmpuint (gs2, ==, 8);
|
||||
g_assert_null ((gpointer) gs);
|
||||
g_assert_cmpuint (gu, ==, 0);
|
||||
g_assert_cmpuint ((guintptr) cp, ==, 0);
|
||||
gu2 = (guintptr) g_atomic_pointer_add (&gu, 5);
|
||||
g_assert_cmpuint (gu2, ==, 0);
|
||||
g_assert_cmpuint (gu, ==, 5);
|
||||
gu2 = g_atomic_pointer_and (&gu, 6);
|
||||
g_assert_cmpuint (gu2, ==, 5);
|
||||
g_assert_cmpuint (gu, ==, 4);
|
||||
gu2 = g_atomic_pointer_or (&gu, 8);
|
||||
g_assert_cmpuint (gu2, ==, 4);
|
||||
g_assert_cmpuint (gu, ==, 12);
|
||||
gu2 = g_atomic_pointer_xor (&gu, 4);
|
||||
g_assert_cmpuint (gu2, ==, 12);
|
||||
g_assert_cmpuint (gu, ==, 8);
|
||||
vp2 = g_atomic_pointer_exchange (&gu, NULL);
|
||||
gu2 = (guintptr) vp2;
|
||||
g_assert_cmpuint (gu2, ==, 8);
|
||||
g_assert_null ((gpointer) gu);
|
||||
|
||||
g_assert_cmpint (g_atomic_int_get (csp), ==, s);
|
||||
g_assert_true (g_atomic_pointer_get (cspp) == csp);
|
||||
|
Loading…
Reference in New Issue
Block a user