17 #import "objfw-defs.h"
19 #ifndef OF_HAVE_ATOMIC_OPS
20 # error No atomic operations available!
27 #ifdef OF_HAVE_OSATOMIC
28 # include <libkern/OSAtomic.h>
31 OF_ASSUME_NONNULL_BEGIN
34 of_atomic_int_add(
volatile int *OF_NONNULL p,
int i)
36 #if !defined(OF_HAVE_THREADS)
38 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
39 return __sync_add_and_fetch(p, i);
40 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
42 __asm__ __volatile__ (
50 else if (
sizeof(
int) == 8)
51 __asm__ __volatile__ (
63 #elif defined(OF_PPC_ASM)
64 __asm__ __volatile__ (
68 "stwcx. %0, 0, %2\n\t"
75 #elif defined(OF_HAVE_OSATOMIC)
76 return OSAtomicAdd32Barrier(i, p);
78 # error of_atomic_int_add not implemented!
82 static OF_INLINE int32_t
83 of_atomic_int32_add(
volatile int32_t *OF_NONNULL p, int32_t i)
85 #if !defined(OF_HAVE_THREADS)
87 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
88 return __sync_add_and_fetch(p, i);
89 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
90 __asm__ __volatile__ (
99 #elif defined(OF_PPC_ASM)
100 __asm__ __volatile__ (
102 "lwarx %0, 0, %2\n\t"
104 "stwcx. %0, 0, %2\n\t"
111 #elif defined(OF_HAVE_OSATOMIC)
112 return OSAtomicAdd32Barrier(i, p);
114 # error of_atomic_int32_add not implemented!
118 static OF_INLINE
void*
119 of_atomic_ptr_add(
void *
volatile OF_NULLABLE *OF_NONNULL p, intptr_t i)
121 #if !defined(OF_HAVE_THREADS)
122 return (*(
char*
volatile*)p += i);
123 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
124 return __sync_add_and_fetch(p, (
void*)i);
125 #elif defined(OF_X86_64_ASM)
126 __asm__ __volatile__ (
135 #elif defined(OF_X86_ASM)
136 __asm__ __volatile__ (
145 #elif defined(OF_PPC_ASM)
146 __asm__ __volatile__ (
148 "lwarx %0, 0, %2\n\t"
150 "stwcx. %0, 0, %2\n\t"
157 #elif defined(OF_HAVE_OSATOMIC)
159 return (
void*)OSAtomicAdd64Barrier(i, (int64_t*)p);
161 return (
void*)OSAtomicAdd32Barrier(i, (int32_t*)p);
164 # error of_atomic_ptr_add not implemented!
169 of_atomic_int_sub(
volatile int *OF_NONNULL p,
int i)
171 #if !defined(OF_HAVE_THREADS)
173 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
174 return __sync_sub_and_fetch(p, i);
175 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
176 if (
sizeof(
int) == 4)
177 __asm__ __volatile__ (
185 # ifdef OF_X86_64_ASM
186 else if (
sizeof(
int) == 8)
187 __asm__ __volatile__ (
200 #elif defined(OF_PPC_ASM)
201 __asm__ __volatile__ (
203 "lwarx %0, 0, %2\n\t"
205 "stwcx. %0, 0, %2\n\t"
212 #elif defined(OF_HAVE_OSATOMIC)
213 return OSAtomicAdd32Barrier(-i, p);
215 # error of_atomic_int_sub not implemented!
219 static OF_INLINE int32_t
220 of_atomic_int32_sub(
volatile int32_t *OF_NONNULL p, int32_t i)
222 #if !defined(OF_HAVE_THREADS)
224 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
225 return __sync_sub_and_fetch(p, i);
226 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
227 __asm__ __volatile__ (
237 #elif defined(OF_PPC_ASM)
238 __asm__ __volatile__ (
240 "lwarx %0, 0, %2\n\t"
242 "stwcx. %0, 0, %2\n\t"
249 #elif defined(OF_HAVE_OSATOMIC)
250 return OSAtomicAdd32Barrier(-i, p);
252 # error of_atomic_int32_sub not implemented!
256 static OF_INLINE
void*
257 of_atomic_ptr_sub(
void *
volatile OF_NULLABLE *OF_NONNULL p, intptr_t i)
259 #if !defined(OF_HAVE_THREADS)
260 return (*(
char*
volatile*)p -= i);
261 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
262 return __sync_sub_and_fetch(p, (
void*)i);
263 #elif defined(OF_X86_64_ASM)
264 __asm__ __volatile__ (
274 #elif defined(OF_X86_ASM)
275 __asm__ __volatile__ (
285 #elif defined(OF_PPC_ASM)
286 __asm__ __volatile__ (
288 "lwarx %0, 0, %2\n\t"
290 "stwcx. %0, 0, %2\n\t"
297 #elif defined(OF_HAVE_OSATOMIC)
299 return (
void*)OSAtomicAdd64Barrier(-i, (int64_t*)p);
301 return (
void*)OSAtomicAdd32Barrier(-i, (int32_t*)p);
304 # error of_atomic_ptr_sub not implemented!
309 of_atomic_int_inc(
volatile int *OF_NONNULL p)
311 #if !defined(OF_HAVE_THREADS)
313 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
314 return __sync_add_and_fetch(p, 1);
315 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
318 if (
sizeof(
int) == 4)
319 __asm__ __volatile__ (
328 # ifdef OF_X86_64_ASM
329 else if (
sizeof(
int) == 8)
330 __asm__ __volatile__ (
344 #elif defined(OF_PPC_ASM)
347 __asm__ __volatile__ (
349 "lwarx %0, 0, %1\n\t"
351 "stwcx. %0, 0, %1\n\t"
358 #elif defined(OF_HAVE_OSATOMIC)
359 return OSAtomicIncrement32Barrier(p);
361 # error of_atomic_int_inc not implemented!
365 static OF_INLINE int32_t
366 of_atomic_int32_inc(
volatile int32_t *OF_NONNULL p)
368 #if !defined(OF_HAVE_THREADS)
370 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
371 return __sync_add_and_fetch(p, 1);
372 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
375 __asm__ __volatile__ (
386 #elif defined(OF_PPC_ASM)
389 __asm__ __volatile__ (
391 "lwarx %0, 0, %1\n\t"
393 "stwcx. %0, 0, %1\n\t"
400 #elif defined(OF_HAVE_OSATOMIC)
401 return OSAtomicIncrement32Barrier(p);
403 # error of_atomic_int32_inc not implemented!
408 of_atomic_int_dec(
volatile int *OF_NONNULL p)
410 #if !defined(OF_HAVE_THREADS)
412 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
413 return __sync_sub_and_fetch(p, 1);
414 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
417 if (
sizeof(
int) == 4)
418 __asm__ __volatile__ (
427 # ifdef OF_X86_64_ASM
428 else if (
sizeof(
int) == 8)
429 __asm__ __volatile__ (
443 #elif defined(OF_PPC_ASM)
446 __asm__ __volatile__ (
448 "lwarx %0, 0, %1\n\t"
450 "stwcx. %0, 0, %1\n\t"
457 #elif defined(OF_HAVE_OSATOMIC)
458 return OSAtomicDecrement32Barrier(p);
460 # error of_atomic_int_dec not implemented!
464 static OF_INLINE int32_t
465 of_atomic_int32_dec(
volatile int32_t *OF_NONNULL p)
467 #if !defined(OF_HAVE_THREADS)
469 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
470 return __sync_sub_and_fetch(p, 1);
471 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
474 __asm__ __volatile__ (
485 #elif defined(OF_PPC_ASM)
488 __asm__ __volatile__ (
490 "lwarx %0, 0, %1\n\t"
492 "stwcx. %0, 0, %1\n\t"
499 #elif defined(OF_HAVE_OSATOMIC)
500 return OSAtomicDecrement32Barrier(p);
502 # error of_atomic_int32_dec not implemented!
506 static OF_INLINE
unsigned int
507 of_atomic_int_or(
volatile unsigned int *OF_NONNULL p,
unsigned int i)
509 #if !defined(OF_HAVE_THREADS)
511 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
512 return __sync_or_and_fetch(p, i);
513 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
514 if (
sizeof(
int) == 4)
515 __asm__ __volatile__ (
527 # ifdef OF_X86_64_ASM
528 else if (
sizeof(
int) == 8)
529 __asm__ __volatile__ (
546 #elif defined(OF_PPC_ASM)
547 __asm__ __volatile__ (
549 "lwarx %0, 0, %2\n\t"
551 "stwcx. %0, 0, %2\n\t"
558 #elif defined(OF_HAVE_OSATOMIC)
559 return OSAtomicOr32Barrier(i, p);
561 # error of_atomic_int_or not implemented!
565 static OF_INLINE uint32_t
566 of_atomic_int32_or(
volatile uint32_t *OF_NONNULL p, uint32_t i)
568 #if !defined(OF_HAVE_THREADS)
570 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
571 return __sync_or_and_fetch(p, i);
572 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
573 __asm__ __volatile__ (
587 #elif defined(OF_PPC_ASM)
588 __asm__ __volatile__ (
590 "lwarx %0, 0, %2\n\t"
592 "stwcx. %0, 0, %2\n\t"
599 #elif defined(OF_HAVE_OSATOMIC)
600 return OSAtomicOr32Barrier(i, p);
602 # error of_atomic_int32_or not implemented!
606 static OF_INLINE
unsigned int
607 of_atomic_int_and(
volatile unsigned int *OF_NONNULL p,
unsigned int i)
609 #if !defined(OF_HAVE_THREADS)
611 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
612 return __sync_and_and_fetch(p, i);
613 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
614 if (
sizeof(
int) == 4)
615 __asm__ __volatile__ (
627 # ifdef OF_X86_64_ASM
628 else if (
sizeof(
int) == 8)
629 __asm__ __volatile__ (
646 #elif defined(OF_PPC_ASM)
647 __asm__ __volatile__ (
649 "lwarx %0, 0, %2\n\t"
651 "stwcx. %0, 0, %2\n\t"
658 #elif defined(OF_HAVE_OSATOMIC)
659 return OSAtomicAnd32Barrier(i, p);
661 # error of_atomic_int_and not implemented!
665 static OF_INLINE uint32_t
666 of_atomic_int32_and(
volatile uint32_t *OF_NONNULL p, uint32_t i)
668 #if !defined(OF_HAVE_THREADS)
670 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
671 return __sync_and_and_fetch(p, i);
672 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
673 __asm__ __volatile__ (
687 #elif defined(OF_PPC_ASM)
688 __asm__ __volatile__ (
690 "lwarx %0, 0, %2\n\t"
692 "stwcx. %0, 0, %2\n\t"
699 #elif defined(OF_HAVE_OSATOMIC)
700 return OSAtomicAnd32Barrier(i, p);
702 # error of_atomic_int32_and not implemented!
706 static OF_INLINE
unsigned int
707 of_atomic_int_xor(
volatile unsigned int *OF_NONNULL p,
unsigned int i)
709 #if !defined(OF_HAVE_THREADS)
711 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
712 return __sync_xor_and_fetch(p, i);
713 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
714 if (
sizeof(
int) == 4)
715 __asm__ __volatile__ (
727 # ifdef OF_X86_64_ASM
728 else if (
sizeof(
int) == 8)
729 __asm__ __volatile__ (
746 #elif defined(OF_PPC_ASM)
747 __asm__ __volatile__ (
749 "lwarx %0, 0, %2\n\t"
751 "stwcx. %0, 0, %2\n\t"
758 #elif defined(OF_HAVE_OSATOMIC)
759 return OSAtomicXor32Barrier(i, p);
761 # error of_atomic_int_xor not implemented!
765 static OF_INLINE uint32_t
766 of_atomic_int32_xor(
volatile uint32_t *OF_NONNULL p, uint32_t i)
768 #if !defined(OF_HAVE_THREADS)
770 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
771 return __sync_xor_and_fetch(p, i);
772 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
773 __asm__ __volatile__ (
779 "cmpxchgl %0, %2\n\t"
787 #elif defined(OF_PPC_ASM)
788 __asm__ __volatile__ (
790 "lwarx %0, 0, %2\n\t"
792 "stwcx. %0, 0, %2\n\t"
799 #elif defined(OF_HAVE_OSATOMIC)
800 return OSAtomicXor32Barrier(i, p);
802 # error of_atomic_int32_xor not implemented!
806 static OF_INLINE
bool
807 of_atomic_int_cmpswap(
volatile int *OF_NONNULL p,
int o,
int n)
809 #if !defined(OF_HAVE_THREADS)
816 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
817 return __sync_bool_compare_and_swap(p, o, n);
818 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
821 __asm__ __volatile__ (
832 #elif defined(OF_PPC_ASM)
835 __asm__ __volatile__ (
837 "lwarx %0, 0, %3\n\t"
840 "stwcx. %2, 0, %3\n\t"
845 "stwcx. %0, 0, %3\n\t"
849 :
"r"(o),
"r"(n),
"r"(p)
854 #elif defined(OF_HAVE_OSATOMIC)
855 return OSAtomicCompareAndSwapIntBarrier(o, n, p);
857 # error of_atomic_int_cmpswap not implemented!
861 static OF_INLINE
bool
862 of_atomic_int32_cmpswap(
volatile int32_t *OF_NONNULL p, int32_t o, int32_t n)
864 #if !defined(OF_HAVE_THREADS)
871 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
872 return __sync_bool_compare_and_swap(p, o, n);
873 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
876 __asm__ __volatile__ (
887 #elif defined(OF_PPC_ASM)
890 __asm__ __volatile__ (
892 "lwarx %0, 0, %3\n\t"
895 "stwcx. %2, 0, %3\n\t"
900 "stwcx. %0, 0, %3\n\t"
904 :
"r"(o),
"r"(n),
"r"(p)
909 #elif defined(OF_HAVE_OSATOMIC)
910 return OSAtomicCompareAndSwap32Barrier(o, n, p);
912 # error of_atomic_int32_cmpswap not implemented!
916 static OF_INLINE
bool
917 of_atomic_ptr_cmpswap(
void *
volatile OF_NULLABLE *OF_NONNULL p,
918 void *OF_NULLABLE o,
void *OF_NULLABLE n)
920 #if !defined(OF_HAVE_THREADS)
927 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
928 return __sync_bool_compare_and_swap(p, o, n);
929 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
932 __asm__ __volatile__ (
943 #elif defined(OF_PPC_ASM)
946 __asm__ __volatile__ (
948 "lwarx %0, 0, %3\n\t"
951 "stwcx. %2, 0, %3\n\t"
956 "stwcx. %0, 0, %3\n\t"
960 :
"r"(o),
"r"(n),
"r"(p)
965 #elif defined(OF_HAVE_OSATOMIC)
966 return OSAtomicCompareAndSwapPtrBarrier(o, n, p);
968 # error of_atomic_ptr_cmpswap not implemented!
972 static OF_INLINE
void
973 of_memory_barrier(
void)
975 #if !defined(OF_HAVE_THREADS)
976 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
977 __asm__ __volatile__ (
980 #elif defined(OF_PPC_ASM)
981 __asm__ __volatile__ (
984 #elif defined(OF_HAVE_GCC_ATOMIC_OPS)
985 __sync_synchronize();
986 #elif defined(OF_HAVE_OSATOMIC)
989 # error of_memory_barrier not implemented!
993 static OF_INLINE
void
994 of_memory_read_barrier(
void)
996 #if !defined(OF_HAVE_THREADS)
997 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
998 __asm__ __volatile__ (
1002 of_memory_barrier();
1006 static OF_INLINE
void
1007 of_memory_write_barrier(
void)
1009 #if !defined(OF_HAVE_THREADS)
1010 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
1011 __asm__ __volatile__ (
1015 of_memory_barrier();
1019 OF_ASSUME_NONNULL_END