File indexing completed on 2025-12-22 10:14:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #ifndef __G_ATOMIC_H__
0023 #define __G_ATOMIC_H__
0024
0025 #if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
0026 #error "Only <glib.h> can be included directly."
0027 #endif
0028
0029 #include <glib/gtypes.h>
0030 #include <glib/glib-typeof.h>
0031
0032 G_BEGIN_DECLS
0033
0034 GLIB_AVAILABLE_IN_ALL
0035 gint g_atomic_int_get (const volatile gint *atomic);
0036 GLIB_AVAILABLE_IN_ALL
0037 void g_atomic_int_set (volatile gint *atomic,
0038 gint newval);
0039 GLIB_AVAILABLE_IN_ALL
0040 void g_atomic_int_inc (volatile gint *atomic);
0041 GLIB_AVAILABLE_IN_ALL
0042 gboolean g_atomic_int_dec_and_test (volatile gint *atomic);
0043 GLIB_AVAILABLE_IN_ALL
0044 gboolean g_atomic_int_compare_and_exchange (volatile gint *atomic,
0045 gint oldval,
0046 gint newval);
0047 GLIB_AVAILABLE_IN_2_74
0048 gboolean g_atomic_int_compare_and_exchange_full (gint *atomic,
0049 gint oldval,
0050 gint newval,
0051 gint *preval);
0052 GLIB_AVAILABLE_IN_2_74
0053 gint g_atomic_int_exchange (gint *atomic,
0054 gint newval);
0055 GLIB_AVAILABLE_IN_ALL
0056 gint g_atomic_int_add (volatile gint *atomic,
0057 gint val);
0058 GLIB_AVAILABLE_IN_2_30
0059 guint g_atomic_int_and (volatile guint *atomic,
0060 guint val);
0061 GLIB_AVAILABLE_IN_2_30
0062 guint g_atomic_int_or (volatile guint *atomic,
0063 guint val);
0064 GLIB_AVAILABLE_IN_ALL
0065 guint g_atomic_int_xor (volatile guint *atomic,
0066 guint val);
0067
0068 GLIB_AVAILABLE_IN_ALL
0069 gpointer g_atomic_pointer_get (const volatile void *atomic);
0070 GLIB_AVAILABLE_IN_ALL
0071 void g_atomic_pointer_set (volatile void *atomic,
0072 gpointer newval);
0073 GLIB_AVAILABLE_IN_ALL
0074 gboolean g_atomic_pointer_compare_and_exchange (volatile void *atomic,
0075 gpointer oldval,
0076 gpointer newval);
0077 GLIB_AVAILABLE_IN_2_74
0078 gboolean g_atomic_pointer_compare_and_exchange_full (void *atomic,
0079 gpointer oldval,
0080 gpointer newval,
0081 void *preval);
0082 GLIB_AVAILABLE_IN_2_74
0083 gpointer g_atomic_pointer_exchange (void *atomic,
0084 gpointer newval);
0085 GLIB_AVAILABLE_IN_ALL
0086 gintptr g_atomic_pointer_add (volatile void *atomic,
0087 gssize val);
0088 GLIB_AVAILABLE_IN_2_30
0089 guintptr g_atomic_pointer_and (volatile void *atomic,
0090 gsize val);
0091 GLIB_AVAILABLE_IN_2_30
0092 guintptr g_atomic_pointer_or (volatile void *atomic,
0093 gsize val);
0094 GLIB_AVAILABLE_IN_ALL
0095 guintptr g_atomic_pointer_xor (volatile void *atomic,
0096 gsize val);
0097
0098 GLIB_DEPRECATED_IN_2_30_FOR(g_atomic_int_add)
0099 gint g_atomic_int_exchange_and_add (volatile gint *atomic,
0100 gint val);
0101
0102 G_END_DECLS
0103
0104 #if defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
0105
0106
0107 #if defined(__ATOMIC_SEQ_CST)
0108
0109 #define g_atomic_int_get(atomic) \
0110 (G_GNUC_EXTENSION ({ \
0111 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0112 gint gaig_temp; \
0113 (void) (0 ? *(atomic) ^ *(atomic) : 1); \
0114 __atomic_load ((gint *)(atomic), &gaig_temp, __ATOMIC_SEQ_CST); \
0115 (gint) gaig_temp; \
0116 }))
0117 #define g_atomic_int_set(atomic, newval) \
0118 (G_GNUC_EXTENSION ({ \
0119 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0120 gint gais_temp = (gint) (newval); \
0121 (void) (0 ? *(atomic) ^ (newval) : 1); \
0122 __atomic_store ((gint *)(atomic), &gais_temp, __ATOMIC_SEQ_CST); \
0123 }))
0124
0125 #if defined(glib_typeof)
0126 #define g_atomic_pointer_get(atomic) \
0127 (G_GNUC_EXTENSION ({ \
0128 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0129 glib_typeof (*(atomic)) gapg_temp_newval; \
0130 glib_typeof ((atomic)) gapg_temp_atomic = (atomic); \
0131 __atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \
0132 gapg_temp_newval; \
0133 }))
0134 #define g_atomic_pointer_set(atomic, newval) \
0135 (G_GNUC_EXTENSION ({ \
0136 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0137 glib_typeof ((atomic)) gaps_temp_atomic = (atomic); \
0138 glib_typeof (*(atomic)) gaps_temp_newval = (newval); \
0139 (void) (0 ? (gpointer) * (atomic) : NULL); \
0140 __atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \
0141 }))
0142 #else
0143 #define g_atomic_pointer_get(atomic) \
0144 (G_GNUC_EXTENSION ({ \
0145 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0146 gpointer gapg_temp_newval; \
0147 gpointer *gapg_temp_atomic = (gpointer *)(atomic); \
0148 __atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \
0149 gapg_temp_newval; \
0150 }))
0151 #define g_atomic_pointer_set(atomic, newval) \
0152 (G_GNUC_EXTENSION ({ \
0153 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0154 gpointer *gaps_temp_atomic = (gpointer *)(atomic); \
0155 gpointer gaps_temp_newval = (gpointer)(newval); \
0156 (void) (0 ? (gpointer) *(atomic) : NULL); \
0157 __atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \
0158 }))
0159 #endif
0160
0161 #define g_atomic_int_inc(atomic) \
0162 (G_GNUC_EXTENSION ({ \
0163 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0164 (void) (0 ? *(atomic) ^ *(atomic) : 1); \
0165 (void) __atomic_fetch_add ((atomic), 1, __ATOMIC_SEQ_CST); \
0166 }))
0167 #define g_atomic_int_dec_and_test(atomic) \
0168 (G_GNUC_EXTENSION ({ \
0169 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0170 (void) (0 ? *(atomic) ^ *(atomic) : 1); \
0171 __atomic_fetch_sub ((atomic), 1, __ATOMIC_SEQ_CST) == 1; \
0172 }))
0173 #if defined(glib_typeof) && defined(G_CXX_STD_VERSION)
0174
0175
0176 #define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \
0177 (G_GNUC_EXTENSION ({ \
0178 glib_typeof (*(atomic)) gaicae_oldval = (oldval); \
0179 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0180 (void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 1); \
0181 __atomic_compare_exchange_n ((atomic), &gaicae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \
0182 }))
0183 #else
0184 #define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \
0185 (G_GNUC_EXTENSION ({ \
0186 gint gaicae_oldval = (oldval); \
0187 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0188 (void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 1); \
0189 __atomic_compare_exchange_n ((atomic), (void *) (&(gaicae_oldval)), (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \
0190 }))
0191 #endif
0192 #define g_atomic_int_compare_and_exchange_full(atomic, oldval, newval, preval) \
0193 (G_GNUC_EXTENSION ({ \
0194 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0195 G_STATIC_ASSERT (sizeof *(preval) == sizeof (gint)); \
0196 (void) (0 ? *(atomic) ^ (newval) ^ (oldval) ^ *(preval) : 1); \
0197 *(preval) = (oldval); \
0198 __atomic_compare_exchange_n ((atomic), (preval), (newval), FALSE, \
0199 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) \
0200 ? TRUE : FALSE; \
0201 }))
0202 #define g_atomic_int_exchange(atomic, newval) \
0203 (G_GNUC_EXTENSION ({ \
0204 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0205 (void) (0 ? *(atomic) ^ (newval) : 1); \
0206 (gint) __atomic_exchange_n ((atomic), (newval), __ATOMIC_SEQ_CST); \
0207 }))
0208 #define g_atomic_int_add(atomic, val) \
0209 (G_GNUC_EXTENSION ({ \
0210 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0211 (void) (0 ? *(atomic) ^ (val) : 1); \
0212 (gint) __atomic_fetch_add ((atomic), (val), __ATOMIC_SEQ_CST); \
0213 }))
0214 #define g_atomic_int_and(atomic, val) \
0215 (G_GNUC_EXTENSION ({ \
0216 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0217 (void) (0 ? *(atomic) ^ (val) : 1); \
0218 (guint) __atomic_fetch_and ((atomic), (val), __ATOMIC_SEQ_CST); \
0219 }))
0220 #define g_atomic_int_or(atomic, val) \
0221 (G_GNUC_EXTENSION ({ \
0222 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0223 (void) (0 ? *(atomic) ^ (val) : 1); \
0224 (guint) __atomic_fetch_or ((atomic), (val), __ATOMIC_SEQ_CST); \
0225 }))
0226 #define g_atomic_int_xor(atomic, val) \
0227 (G_GNUC_EXTENSION ({ \
0228 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0229 (void) (0 ? *(atomic) ^ (val) : 1); \
0230 (guint) __atomic_fetch_xor ((atomic), (val), __ATOMIC_SEQ_CST); \
0231 }))
0232
0233 #if defined(glib_typeof) && defined(G_CXX_STD_VERSION)
0234
0235
0236
0237
0238
0239
0240
0241
0242 #define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \
0243 (G_GNUC_EXTENSION ({ \
0244 G_STATIC_ASSERT (sizeof (static_cast<glib_typeof (*(atomic))>((oldval))) \
0245 == sizeof (gpointer)); \
0246 glib_typeof (*(atomic)) gapcae_oldval = (oldval); \
0247 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0248 (void) (0 ? (gpointer) *(atomic) : NULL); \
0249 __atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \
0250 }))
0251 #else
0252 #define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \
0253 (G_GNUC_EXTENSION ({ \
0254 G_STATIC_ASSERT (sizeof (oldval) == sizeof (gpointer)); \
0255 gpointer gapcae_oldval = (gpointer)(oldval); \
0256 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0257 (void) (0 ? (gpointer) *(atomic) : NULL); \
0258 __atomic_compare_exchange_n ((atomic), (void *) (&(gapcae_oldval)), (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \
0259 }))
0260 #endif
0261 #define g_atomic_pointer_compare_and_exchange_full(atomic, oldval, newval, preval) \
0262 (G_GNUC_EXTENSION ({ \
0263 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0264 G_STATIC_ASSERT (sizeof *(preval) == sizeof (gpointer)); \
0265 (void) (0 ? (gpointer) *(atomic) : NULL); \
0266 (void) (0 ? (gpointer) *(preval) : NULL); \
0267 *(preval) = (oldval); \
0268 __atomic_compare_exchange_n ((atomic), (preval), (newval), FALSE, \
0269 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? \
0270 TRUE : FALSE; \
0271 }))
0272 #define g_atomic_pointer_exchange(atomic, newval) \
0273 (G_GNUC_EXTENSION ({ \
0274 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0275 (void) (0 ? (gpointer) *(atomic) : NULL); \
0276 (gpointer) __atomic_exchange_n ((atomic), (newval), __ATOMIC_SEQ_CST); \
0277 }))
0278 #define g_atomic_pointer_add(atomic, val) \
0279 (G_GNUC_EXTENSION ({ \
0280 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0281 (void) (0 ? (gpointer) *(atomic) : NULL); \
0282 (void) (0 ? (val) ^ (val) : 1); \
0283 (gintptr) __atomic_fetch_add ((atomic), (val), __ATOMIC_SEQ_CST); \
0284 }))
0285 #define g_atomic_pointer_and(atomic, val) \
0286 (G_GNUC_EXTENSION ({ \
0287 guintptr *gapa_atomic = (guintptr *) (atomic); \
0288 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0289 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (guintptr)); \
0290 (void) (0 ? (gpointer) *(atomic) : NULL); \
0291 (void) (0 ? (val) ^ (val) : 1); \
0292 (guintptr) __atomic_fetch_and (gapa_atomic, (val), __ATOMIC_SEQ_CST); \
0293 }))
0294 #define g_atomic_pointer_or(atomic, val) \
0295 (G_GNUC_EXTENSION ({ \
0296 guintptr *gapo_atomic = (guintptr *) (atomic); \
0297 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0298 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (guintptr)); \
0299 (void) (0 ? (gpointer) *(atomic) : NULL); \
0300 (void) (0 ? (val) ^ (val) : 1); \
0301 (guintptr) __atomic_fetch_or (gapo_atomic, (val), __ATOMIC_SEQ_CST); \
0302 }))
0303 #define g_atomic_pointer_xor(atomic, val) \
0304 (G_GNUC_EXTENSION ({ \
0305 guintptr *gapx_atomic = (guintptr *) (atomic); \
0306 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0307 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (guintptr)); \
0308 (void) (0 ? (gpointer) *(atomic) : NULL); \
0309 (void) (0 ? (val) ^ (val) : 1); \
0310 (guintptr) __atomic_fetch_xor (gapx_atomic, (val), __ATOMIC_SEQ_CST); \
0311 }))
0312
0313 #else
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343 #define g_atomic_int_get(atomic) \
0344 (G_GNUC_EXTENSION ({ \
0345 gint gaig_result; \
0346 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0347 (void) (0 ? *(atomic) ^ *(atomic) : 1); \
0348 gaig_result = (gint) *(atomic); \
0349 __sync_synchronize (); \
0350 __asm__ __volatile__ ("" : : : "memory"); \
0351 gaig_result; \
0352 }))
0353 #define g_atomic_int_set(atomic, newval) \
0354 (G_GNUC_EXTENSION ({ \
0355 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0356 (void) (0 ? *(atomic) ^ (newval) : 1); \
0357 __sync_synchronize (); \
0358 __asm__ __volatile__ ("" : : : "memory"); \
0359 *(atomic) = (newval); \
0360 }))
0361 #define g_atomic_pointer_get(atomic) \
0362 (G_GNUC_EXTENSION ({ \
0363 gpointer gapg_result; \
0364 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0365 gapg_result = (gpointer) *(atomic); \
0366 __sync_synchronize (); \
0367 __asm__ __volatile__ ("" : : : "memory"); \
0368 gapg_result; \
0369 }))
0370 #if defined(glib_typeof)
0371 #define g_atomic_pointer_set(atomic, newval) \
0372 (G_GNUC_EXTENSION ({ \
0373 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0374 (void) (0 ? (gpointer) *(atomic) : NULL); \
0375 __sync_synchronize (); \
0376 __asm__ __volatile__ ("" : : : "memory"); \
0377 *(atomic) = (glib_typeof (*(atomic))) (guintptr) (newval); \
0378 }))
0379 #else
0380 #define g_atomic_pointer_set(atomic, newval) \
0381 (G_GNUC_EXTENSION ({ \
0382 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0383 (void) (0 ? (gpointer) *(atomic) : NULL); \
0384 __sync_synchronize (); \
0385 __asm__ __volatile__ ("" : : : "memory"); \
0386 *(atomic) = (gpointer) (guintptr) (newval); \
0387 }))
0388 #endif
0389
0390 #define g_atomic_int_inc(atomic) \
0391 (G_GNUC_EXTENSION ({ \
0392 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0393 (void) (0 ? *(atomic) ^ *(atomic) : 1); \
0394 (void) __sync_fetch_and_add ((atomic), 1); \
0395 }))
0396 #define g_atomic_int_dec_and_test(atomic) \
0397 (G_GNUC_EXTENSION ({ \
0398 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0399 (void) (0 ? *(atomic) ^ *(atomic) : 1); \
0400 __sync_fetch_and_sub ((atomic), 1) == 1; \
0401 }))
0402 #define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \
0403 (G_GNUC_EXTENSION ({ \
0404 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0405 (void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 1); \
0406 __sync_bool_compare_and_swap ((atomic), (oldval), (newval)) ? TRUE : FALSE; \
0407 }))
0408 #define g_atomic_int_compare_and_exchange_full(atomic, oldval, newval, preval) \
0409 (G_GNUC_EXTENSION ({ \
0410 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0411 G_STATIC_ASSERT (sizeof *(preval) == sizeof (gint)); \
0412 (void) (0 ? *(atomic) ^ (newval) ^ (oldval) ^ *(preval) : 1); \
0413 *(preval) = __sync_val_compare_and_swap ((atomic), (oldval), (newval)); \
0414 (*(preval) == (oldval)) ? TRUE : FALSE; \
0415 }))
0416 #if defined(_GLIB_GCC_HAVE_SYNC_SWAP)
0417 #define g_atomic_int_exchange(atomic, newval) \
0418 (G_GNUC_EXTENSION ({ \
0419 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0420 (void) (0 ? *(atomic) ^ (newval) : 1); \
0421 (gint) __sync_swap ((atomic), (newval)); \
0422 }))
0423 #else
0424 #define g_atomic_int_exchange(atomic, newval) \
0425 (G_GNUC_EXTENSION ({ \
0426 gint oldval; \
0427 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0428 (void) (0 ? *(atomic) ^ (newval) : 1); \
0429 do \
0430 { \
0431 oldval = *atomic; \
0432 } while (!__sync_bool_compare_and_swap (atomic, oldval, newval)); \
0433 oldval; \
0434 }))
0435 #endif
0436 #define g_atomic_int_add(atomic, val) \
0437 (G_GNUC_EXTENSION ({ \
0438 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0439 (void) (0 ? *(atomic) ^ (val) : 1); \
0440 (gint) __sync_fetch_and_add ((atomic), (val)); \
0441 }))
0442 #define g_atomic_int_and(atomic, val) \
0443 (G_GNUC_EXTENSION ({ \
0444 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0445 (void) (0 ? *(atomic) ^ (val) : 1); \
0446 (guint) __sync_fetch_and_and ((atomic), (val)); \
0447 }))
0448 #define g_atomic_int_or(atomic, val) \
0449 (G_GNUC_EXTENSION ({ \
0450 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0451 (void) (0 ? *(atomic) ^ (val) : 1); \
0452 (guint) __sync_fetch_and_or ((atomic), (val)); \
0453 }))
0454 #define g_atomic_int_xor(atomic, val) \
0455 (G_GNUC_EXTENSION ({ \
0456 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
0457 (void) (0 ? *(atomic) ^ (val) : 1); \
0458 (guint) __sync_fetch_and_xor ((atomic), (val)); \
0459 }))
0460
0461 #define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \
0462 (G_GNUC_EXTENSION ({ \
0463 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0464 (void) (0 ? (gpointer) *(atomic) : NULL); \
0465 __sync_bool_compare_and_swap ((atomic), (oldval), (newval)) ? TRUE : FALSE; \
0466 }))
0467 #define g_atomic_pointer_compare_and_exchange_full(atomic, oldval, newval, preval) \
0468 (G_GNUC_EXTENSION ({ \
0469 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0470 G_STATIC_ASSERT (sizeof *(preval) == sizeof (gpointer)); \
0471 (void) (0 ? (gpointer) *(atomic) : NULL); \
0472 (void) (0 ? (gpointer) *(preval) : NULL); \
0473 *(preval) = __sync_val_compare_and_swap ((atomic), (oldval), (newval)); \
0474 (*(preval) == (oldval)) ? TRUE : FALSE; \
0475 }))
0476 #if defined(_GLIB_GCC_HAVE_SYNC_SWAP)
0477 #define g_atomic_pointer_exchange(atomic, newval) \
0478 (G_GNUC_EXTENSION ({ \
0479 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0480 (void) (0 ? (gpointer) *(atomic) : NULL); \
0481 (gpointer) __sync_swap ((atomic), (newval)); \
0482 }))
0483 #else
0484 #define g_atomic_pointer_exchange(atomic, newval) \
0485 (G_GNUC_EXTENSION ({ \
0486 gpointer oldval; \
0487 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0488 (void) (0 ? (gpointer) *(atomic) : NULL); \
0489 do \
0490 { \
0491 oldval = (gpointer) *atomic; \
0492 } while (!__sync_bool_compare_and_swap (atomic, oldval, newval)); \
0493 oldval; \
0494 }))
0495 #endif
0496 #define g_atomic_pointer_add(atomic, val) \
0497 (G_GNUC_EXTENSION ({ \
0498 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0499 (void) (0 ? (gpointer) *(atomic) : NULL); \
0500 (void) (0 ? (val) ^ (val) : 1); \
0501 (gintptr) __sync_fetch_and_add ((atomic), (val)); \
0502 }))
0503 #define g_atomic_pointer_and(atomic, val) \
0504 (G_GNUC_EXTENSION ({ \
0505 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0506 (void) (0 ? (gpointer) *(atomic) : NULL); \
0507 (void) (0 ? (val) ^ (val) : 1); \
0508 (guintptr) __sync_fetch_and_and ((atomic), (val)); \
0509 }))
0510 #define g_atomic_pointer_or(atomic, val) \
0511 (G_GNUC_EXTENSION ({ \
0512 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0513 (void) (0 ? (gpointer) *(atomic) : NULL); \
0514 (void) (0 ? (val) ^ (val) : 1); \
0515 (guintptr) __sync_fetch_and_or ((atomic), (val)); \
0516 }))
0517 #define g_atomic_pointer_xor(atomic, val) \
0518 (G_GNUC_EXTENSION ({ \
0519 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
0520 (void) (0 ? (gpointer) *(atomic) : NULL); \
0521 (void) (0 ? (val) ^ (val) : 1); \
0522 (guintptr) __sync_fetch_and_xor ((atomic), (val)); \
0523 }))
0524
0525 #endif
0526
0527 #else
0528
0529 #define g_atomic_int_get(atomic) \
0530 (g_atomic_int_get ((gint *) (atomic)))
0531 #define g_atomic_int_set(atomic, newval) \
0532 (g_atomic_int_set ((gint *) (atomic), (gint) (newval)))
0533 #define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \
0534 (g_atomic_int_compare_and_exchange ((gint *) (atomic), (oldval), (newval)))
0535 #define g_atomic_int_compare_and_exchange_full(atomic, oldval, newval, preval) \
0536 (g_atomic_int_compare_and_exchange_full ((gint *) (atomic), (oldval), (newval), (gint *) (preval)))
0537 #define g_atomic_int_exchange(atomic, newval) \
0538 (g_atomic_int_exchange ((gint *) (atomic), (newval)))
0539 #define g_atomic_int_add(atomic, val) \
0540 (g_atomic_int_add ((gint *) (atomic), (val)))
0541 #define g_atomic_int_and(atomic, val) \
0542 (g_atomic_int_and ((guint *) (atomic), (val)))
0543 #define g_atomic_int_or(atomic, val) \
0544 (g_atomic_int_or ((guint *) (atomic), (val)))
0545 #define g_atomic_int_xor(atomic, val) \
0546 (g_atomic_int_xor ((guint *) (atomic), (val)))
0547 #define g_atomic_int_inc(atomic) \
0548 (g_atomic_int_inc ((gint *) (atomic)))
0549 #define g_atomic_int_dec_and_test(atomic) \
0550 (g_atomic_int_dec_and_test ((gint *) (atomic)))
0551
0552 #if defined(glib_typeof)
0553
0554
0555
0556
0557
0558
0559
0560 #define g_atomic_pointer_get(atomic) \
0561 (glib_typeof (*(atomic))) (void *) ((g_atomic_pointer_get) ((void *) atomic))
0562 #else
0563 #define g_atomic_pointer_get(atomic) \
0564 (g_atomic_pointer_get (atomic))
0565 #endif
0566
0567 #define g_atomic_pointer_set(atomic, newval) \
0568 (g_atomic_pointer_set ((atomic), (gpointer) (newval)))
0569
0570 #define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \
0571 (g_atomic_pointer_compare_and_exchange ((atomic), (gpointer) (oldval), (gpointer) (newval)))
0572 #define g_atomic_pointer_compare_and_exchange_full(atomic, oldval, newval, prevval) \
0573 (g_atomic_pointer_compare_and_exchange_full ((atomic), (gpointer) (oldval), (gpointer) (newval), (prevval)))
0574 #define g_atomic_pointer_exchange(atomic, newval) \
0575 (g_atomic_pointer_exchange ((atomic), (gpointer) (newval)))
0576 #define g_atomic_pointer_add(atomic, val) \
0577 (g_atomic_pointer_add ((atomic), (gssize) (val)))
0578 #define g_atomic_pointer_and(atomic, val) \
0579 (g_atomic_pointer_and ((atomic), (gsize) (val)))
0580 #define g_atomic_pointer_or(atomic, val) \
0581 (g_atomic_pointer_or ((atomic), (gsize) (val)))
0582 #define g_atomic_pointer_xor(atomic, val) \
0583 (g_atomic_pointer_xor ((atomic), (gsize) (val)))
0584
0585 #endif
0586
0587 #endif