diff --git a/libs/libc/machine/arch_atomic.c b/libs/libc/machine/arch_atomic.c index b318e981a7c..789d8db306e 100644 --- a/libs/libc/machine/arch_atomic.c +++ b/libs/libc/machine/arch_atomic.c @@ -182,6 +182,131 @@ return ret; \ } +#define SYNC_ADD_FETCH(n, type) \ + \ + type __sync_add_and_fetch_ ## n (volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = spin_lock_irqsave(NULL); \ + type *tmp = (type *)ptr; \ + \ + *tmp = *tmp + value; \ + \ + spin_unlock_irqrestore(NULL, irqstate); \ + return *tmp; \ + } + +#define SYNC_SUB_FETCH(n, type) \ + \ + type __sync_sub_and_fetch_ ## n (volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = spin_lock_irqsave(NULL); \ + type *tmp = (type *)ptr; \ + \ + *tmp = *tmp - value; \ + \ + spin_unlock_irqrestore(NULL, irqstate); \ + return *tmp; \ + } + +#define SYNC_OR_FETCH(n, type) \ + \ + type __sync_or_and_fetch_ ## n (volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = spin_lock_irqsave(NULL); \ + type *tmp = (type *)ptr; \ + \ + *tmp = *tmp | value; \ + \ + spin_unlock_irqrestore(NULL, irqstate); \ + return *tmp; \ + } + +#define SYNC_AND_FETCH(n, type) \ + \ + type __sync_and_and_fetch_ ## n (volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = spin_lock_irqsave(NULL); \ + type *tmp = (type *)ptr; \ + \ + *tmp = *tmp & value; \ + \ + spin_unlock_irqrestore(NULL, irqstate); \ + return *tmp; \ + } + +#define SYNC_XOR_FETCH(n, type) \ + \ + type __sync_xor_and_fetch_ ## n (volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = spin_lock_irqsave(NULL); \ + type *tmp = (type *)ptr; \ + \ + *tmp = *tmp ^ value; \ + \ + spin_unlock_irqrestore(NULL, irqstate); \ + return *tmp; \ + } + +#define SYNC_NAND_FETCH(n, type) \ + \ + type __sync_nand_and_fetch_ ## n (volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = spin_lock_irqsave(NULL); \ + type *tmp = (type *)ptr; \ + \ + *tmp = ~(*tmp & value); \ + \ + spin_unlock_irqrestore(NULL, irqstate); \ + return *tmp; \ + } + +#define SYNC_BOOL_CMP_SWAP(n, type) \ + \ + bool __sync_bool_compare_and_swap_ ## n ( \ + volatile void *ptr, \ + type oldvalue, \ + type newvalue) \ + { \ + bool ret = false; \ + irqstate_t irqstate = spin_lock_irqsave(NULL); \ + type *tmp = (type *)ptr; \ + \ + if (*tmp == oldvalue) \ + { \ + ret = true; \ + *tmp = newvalue; \ + } \ + \ + spin_unlock_irqrestore(NULL, irqstate); \ + return ret; \ + } + +#define SYNC_VAL_CMP_SWAP(n, type) \ + \ + type __sync_val_compare_and_swap_ ## n ( \ + volatile void *ptr, \ + type oldvalue, \ + type newvalue) \ + { \ + irqstate_t irqstate = spin_lock_irqsave(NULL); \ + type *tmp = (type *)ptr; \ + type ret = *tmp; \ + \ + if (*tmp == oldvalue) \ + { \ + *tmp = newvalue; \ + } \ + \ + spin_unlock_irqrestore(NULL, irqstate); \ + return ret; \ + } + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -401,3 +526,203 @@ FETCH_XOR(4, uint32_t) ****************************************************************************/ FETCH_XOR(8, uint64_t) + +/* Clang define the __sync builtins, add #ifndef to avoid + * redefined/redeclared problem. + */ + +#ifndef __clang__ + +/**************************************************************************** + * Name: __sync_add_and_fetch_1 + ****************************************************************************/ + +SYNC_ADD_FETCH(1, uint8_t) + +/**************************************************************************** + * Name: __sync_add_and_fetch_2 + ****************************************************************************/ + +SYNC_ADD_FETCH(2, uint16_t) + +/**************************************************************************** + * Name: __sync_add_and_fetch_4 + ****************************************************************************/ + +SYNC_ADD_FETCH(4, uint32_t) + +/**************************************************************************** + * Name: __sync_add_and_fetch_8 + ****************************************************************************/ + +SYNC_ADD_FETCH(8, uint64_t) + +/**************************************************************************** + * Name: __sync_sub_and_fetch_1 + ****************************************************************************/ + +SYNC_SUB_FETCH(1, uint8_t) + +/**************************************************************************** + * Name: __sync_sub_and_fetch_2 + ****************************************************************************/ + +SYNC_SUB_FETCH(2, uint16_t) + +/**************************************************************************** + * Name: __sync_sub_and_fetch_4 + ****************************************************************************/ + +SYNC_SUB_FETCH(4, uint32_t) + +/**************************************************************************** + * Name: __sync_sub_and_fetch_8 + ****************************************************************************/ + +SYNC_SUB_FETCH(8, uint64_t) + +/**************************************************************************** + * Name: __sync_or_and_fetch_1 + ****************************************************************************/ + +SYNC_OR_FETCH(1, uint8_t) + +/**************************************************************************** + * Name: __sync_or_and_fetch_2 + ****************************************************************************/ + +SYNC_OR_FETCH(2, uint16_t) + +/**************************************************************************** + * Name: __sync_or_and_fetch_4 + ****************************************************************************/ + +SYNC_OR_FETCH(4, uint32_t) + +/**************************************************************************** + * Name: __sync_or_and_fetch_8 + ****************************************************************************/ + +SYNC_OR_FETCH(8, uint64_t) + +/**************************************************************************** + * Name: __sync_and_and_fetch_1 + ****************************************************************************/ + +SYNC_AND_FETCH(1, uint8_t) + +/**************************************************************************** + * Name: __sync_and_and_fetch_2 + ****************************************************************************/ + +SYNC_AND_FETCH(2, uint16_t) + +/**************************************************************************** + * Name: __sync_and_and_fetch_4 + ****************************************************************************/ + +SYNC_AND_FETCH(4, uint32_t) + +/**************************************************************************** + * Name: __sync_and_and_fetch_8 + ****************************************************************************/ + +SYNC_AND_FETCH(8, uint64_t) + +/**************************************************************************** + * Name: __sync_xor_and_fetch_1 + ****************************************************************************/ + +SYNC_XOR_FETCH(1, uint8_t) + +/**************************************************************************** + * Name: __sync_xor_and_fetch_2 + ****************************************************************************/ + +SYNC_XOR_FETCH(2, uint16_t) + +/**************************************************************************** + * Name: __sync_xor_and_fetch_4 + ****************************************************************************/ + +SYNC_XOR_FETCH(4, uint32_t) + +/**************************************************************************** + * Name: __sync_xor_and_fetch_8 + ****************************************************************************/ + +SYNC_XOR_FETCH(8, uint64_t) + +/**************************************************************************** + * Name: __sync_nand_and_fetch_1 + ****************************************************************************/ + +SYNC_NAND_FETCH(1, uint8_t) + +/**************************************************************************** + * Name: __sync_nand_and_fetch_2 + ****************************************************************************/ + +SYNC_NAND_FETCH(2, uint16_t) + +/**************************************************************************** + * Name: __sync_nand_and_fetch_4 + ****************************************************************************/ + +SYNC_NAND_FETCH(4, uint32_t) + +/**************************************************************************** + * Name: __sync_nand_and_fetch_8 + ****************************************************************************/ + +SYNC_NAND_FETCH(8, uint64_t) + +/**************************************************************************** + * Name: __sync_bool_compare_and_swap_1 + ****************************************************************************/ + +SYNC_BOOL_CMP_SWAP(1, uint8_t) + +/**************************************************************************** + * Name: __sync_bool_compare_and_swap_2 + ****************************************************************************/ + +SYNC_BOOL_CMP_SWAP(2, uint16_t) + +/**************************************************************************** + * Name: __sync_bool_compare_and_swap_4 + ****************************************************************************/ + +SYNC_BOOL_CMP_SWAP(4, uint32_t) + +/**************************************************************************** + * Name: __sync_bool_compare_and_swap_8 + ****************************************************************************/ + +SYNC_BOOL_CMP_SWAP(8, uint64_t) + +/**************************************************************************** + * Name: __sync_val_compare_and_swap_1 + ****************************************************************************/ + +SYNC_VAL_CMP_SWAP(1, uint8_t) + +/**************************************************************************** + * Name: __sync_val_compare_and_swap_2 + ****************************************************************************/ + +SYNC_VAL_CMP_SWAP(2, uint16_t) + +/**************************************************************************** + * Name: __sync_val_compare_and_swap_4 + ****************************************************************************/ + +SYNC_VAL_CMP_SWAP(4, uint32_t) + +/**************************************************************************** + * Name: __sync_val_compare_and_swap_8 + ****************************************************************************/ + +SYNC_VAL_CMP_SWAP(8, uint64_t) + +#endif /* __clang__ */