Unified · Split
| @@ -42,8 +42,8 @@ $(X)BT_O += tcov.o · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | DSO_O = dsohandle.o |
| 44 | 44 | |
| 45 | −I386_O = libtcc1.o alloca86.o alloca86-bt.o $(BT_O) | |
| 46 | −X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o $(BT_O) | |
| 45 | +I386_O = libtcc1.o alloca86.o alloca86-bt.o $(BT_O) atomic-i386.o | |
| 46 | +X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o $(BT_O) atomic-x86_64.o | |
| 47 | 47 | ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o fetch_and_add_arm.o $(BT_O) |
| 48 | 48 | ARM64_O = lib-arm64.o fetch_and_add_arm64.o $(BT_O) |
| 49 | 49 | RISCV64_O = lib-arm64.o fetch_and_add_riscv64.o $(BT_O) |
| @@ -0,0 +1,25 @@ | ||
| 1 | +#include "atomic.h" | |
| 2 | + | |
| 3 | +ATOMIC_EXCHANGE(uint8_t, 1) | |
| 4 | +ATOMIC_EXCHANGE(uint16_t, 2) | |
| 5 | +ATOMIC_EXCHANGE(uint32_t, 4) | |
| 6 | + | |
| 7 | +ATOMIC_FETCH_ADD(uint8_t, 1) | |
| 8 | +ATOMIC_FETCH_ADD(uint16_t, 2) | |
| 9 | +ATOMIC_FETCH_ADD(uint32_t, 4) | |
| 10 | + | |
| 11 | +ATOMIC_FETCH_SUB(uint8_t, 1) | |
| 12 | +ATOMIC_FETCH_SUB(uint16_t, 2) | |
| 13 | +ATOMIC_FETCH_SUB(uint32_t, 4) | |
| 14 | + | |
| 15 | +ATOMIC_FETCH_AND(uint8_t, 1) | |
| 16 | +ATOMIC_FETCH_AND(uint16_t, 2) | |
| 17 | +ATOMIC_FETCH_AND(uint32_t, 4) | |
| 18 | + | |
| 19 | +ATOMIC_FETCH_OR(uint8_t, 1) | |
| 20 | +ATOMIC_FETCH_OR(uint16_t, 2) | |
| 21 | +ATOMIC_FETCH_OR(uint32_t, 4) | |
| 22 | + | |
| 23 | +ATOMIC_FETCH_XOR(uint8_t, 1) | |
| 24 | +ATOMIC_FETCH_XOR(uint16_t, 2) | |
| 25 | +ATOMIC_FETCH_XOR(uint32_t, 4) | |
| @@ -0,0 +1,8 @@ | ||
| 1 | +#include "atomic.h" | |
| 2 | + | |
| 3 | +ATOMIC_EXCHANGE(uint64_t, 8) | |
| 4 | +ATOMIC_FETCH_ADD(uint64_t, 8) | |
| 5 | +ATOMIC_FETCH_SUB(uint64_t, 8) | |
| 6 | +ATOMIC_FETCH_AND(uint64_t, 8) | |
| 7 | +ATOMIC_FETCH_OR(uint64_t, 8) | |
| 8 | +ATOMIC_FETCH_XOR(uint64_t, 8) | |
| @@ -0,0 +1,19 @@ | ||
| 1 | +#pragma once | |
| 2 | + | |
| 3 | +#include <stdint.h> | |
| 4 | + | |
| 5 | +#include "atomic-x86.h" | |
| 6 | + | |
| 7 | +ATOMIC_X86_STORE(uint8_t, 1) | |
| 8 | +ATOMIC_X86_STORE(uint16_t, 2) | |
| 9 | +ATOMIC_X86_STORE(uint32_t, 4) | |
| 10 | + | |
| 11 | +ATOMIC_X86_LOAD(uint8_t, 1) | |
| 12 | +ATOMIC_X86_LOAD(uint16_t, 2) | |
| 13 | +ATOMIC_X86_LOAD(uint32_t, 4) | |
| 14 | + | |
| 15 | +ATOMIC_X86_COMPARE_EXCHANGE(uint8_t, 1, "b") | |
| 16 | +ATOMIC_X86_COMPARE_EXCHANGE(uint16_t, 2, "w") | |
| 17 | +ATOMIC_X86_COMPARE_EXCHANGE(uint32_t, 4, "l") | |
| 18 | + | |
| 19 | +#include "atomic-gen32.c" | |
| @@ -0,0 +1,31 @@ | ||
| 1 | +#pragma once | |
| 2 | + | |
| 3 | +#include <stdbool.h> | |
| 4 | +#include <stdint.h> | |
| 5 | + | |
| 6 | +#define ATOMIC_X86_COMPARE_EXCHANGE(TYPE, MODE, SUFFIX) \ | |
| 7 | + bool __atomic_compare_exchange_##MODE(_Atomic(TYPE) *atom, TYPE *ref, TYPE xchg) \ | |
| 8 | + { \ | |
| 9 | + TYPE rv; \ | |
| 10 | + TYPE cmp = *ref; \ | |
| 11 | + asm volatile( \ | |
| 12 | + "lock cmpxchg" SUFFIX " %2,%1\n" \ | |
| 13 | + : "=a" (rv), "+m" (*atom) \ | |
| 14 | + : "q" (xchg), "0" (cmp) \ | |
| 15 | + : "memory" \ | |
| 16 | + ); \ | |
| 17 | + *ref = rv; \ | |
| 18 | + return (rv == cmp); \ | |
| 19 | + } | |
| 20 | + | |
| 21 | +#define ATOMIC_X86_LOAD(TYPE, MODE) \ | |
| 22 | + TYPE __atomic_load_##MODE(const _Atomic(TYPE) *atom) \ | |
| 23 | + { \ | |
| 24 | + return *(volatile TYPE *)atom; \ | |
| 25 | + } | |
| 26 | + | |
| 27 | +#define ATOMIC_X86_STORE(TYPE, MODE) \ | |
| 28 | + void __atomic_store_##MODE(_Atomic(TYPE) *atom, TYPE value) \ | |
| 29 | + { \ | |
| 30 | + *(volatile TYPE *)atom = value; \ | |
| 31 | + } | |
| @@ -0,0 +1,12 @@ | ||
| 1 | +#pragma once | |
| 2 | + | |
| 3 | +#include <stdint.h> | |
| 4 | + | |
| 5 | +#include "atomic-x86.h" | |
| 6 | +#include "atomic-i386.c" | |
| 7 | + | |
| 8 | +ATOMIC_X86_STORE(uint64_t, 8) | |
| 9 | +ATOMIC_X86_LOAD(uint64_t, 8) | |
| 10 | +ATOMIC_X86_COMPARE_EXCHANGE(uint64_t, 8, "q") | |
| 11 | + | |
| 12 | +#include "atomic-gen64.c" | |
| @@ -0,0 +1,39 @@ | ||
| 1 | +#pragma once | |
| 2 | + | |
| 3 | +#include <stdbool.h> | |
| 4 | +#include <stdint.h> | |
| 5 | + | |
| 6 | +#define ATOMIC_GEN_OP(TYPE, MODE, NAME, OP) \ | |
| 7 | + TYPE __atomic_##NAME##_##MODE(_Atomic(TYPE) *atom, TYPE value) \ | |
| 8 | + { \ | |
| 9 | + TYPE xchg; \ | |
| 10 | + TYPE cmp = __atomic_load(atom, __ATOMIC_RELAXED); \ | |
| 11 | + do { \ | |
| 12 | + xchg = (OP); \ | |
| 13 | + } while (!__atomic_compare_exchange(atom, &cmp, xchg, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)); \ | |
| 14 | + return cmp; \ | |
| 15 | + } | |
| 16 | + | |
| 17 | +#ifndef ATOMIC_EXCHANGE | |
| 18 | +# define ATOMIC_EXCHANGE(TYPE, MODE) ATOMIC_GEN_OP(TYPE, MODE, exchange, value) | |
| 19 | +#endif | |
| 20 | + | |
| 21 | +#ifndef ATOMIC_FETCH_ADD | |
| 22 | +# define ATOMIC_FETCH_ADD(TYPE, MODE) ATOMIC_GEN_OP(TYPE, MODE, fetch_add, (cmp + value)) | |
| 23 | +#endif | |
| 24 | + | |
| 25 | +#ifndef ATOMIC_FETCH_SUB | |
| 26 | +# define ATOMIC_FETCH_SUB(TYPE, MODE) ATOMIC_GEN_OP(TYPE, MODE, fetch_sub, (cmp - value)) | |
| 27 | +#endif | |
| 28 | + | |
| 29 | +#ifndef ATOMIC_FETCH_AND | |
| 30 | +# define ATOMIC_FETCH_AND(TYPE, MODE) ATOMIC_GEN_OP(TYPE, MODE, fetch_and, (cmp & value)) | |
| 31 | +#endif | |
| 32 | + | |
| 33 | +#ifndef ATOMIC_FETCH_OR | |
| 34 | +# define ATOMIC_FETCH_OR(TYPE, MODE) ATOMIC_GEN_OP(TYPE, MODE, fetch_or, (cmp | value)) | |
| 35 | +#endif | |
| 36 | + | |
| 37 | +#ifndef ATOMIC_FETCH_XOR | |
| 38 | +# define ATOMIC_FETCH_XOR(TYPE, MODE) ATOMIC_GEN_OP(TYPE, MODE, fetch_xor, (cmp ^ value)) | |
| 39 | +#endif | |