diff options
| author | Wat <[email protected]> | 2024-03-21 04:30:59 +0800 |
|---|---|---|
| committer | Meco Man <[email protected]> | 2024-03-24 23:01:11 -0400 |
| commit | cb6d4515644a6f7e6b6b37878bcc2b59d23b2955 (patch) | |
| tree | 627184bb0db427b629addee45638fafc8cf69f2b /components | |
| parent | 99dafb1fef3e094561fcb8c6b3c6288a3dadc705 (diff) | |
Add GCC generalized atomic operation function
Diffstat (limited to 'components')
| -rw-r--r-- | components/libc/cplusplus/cpp11/atomic_8.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/components/libc/cplusplus/cpp11/atomic_8.c b/components/libc/cplusplus/cpp11/atomic_8.c index bb8a2b637b..65fe22abcf 100644 --- a/components/libc/cplusplus/cpp11/atomic_8.c +++ b/components/libc/cplusplus/cpp11/atomic_8.c @@ -11,6 +11,7 @@ #include <rthw.h> #include <stdint.h> #include <stdbool.h> +#include <rtthread.h> /* * override gcc builtin atomic function for std::atomic<int64_t>, std::atomic<uint64_t> @@ -69,6 +70,84 @@ bool __atomic_compare_exchange_8(volatile void *ptr, volatile void *expected, ui return exchanged; } +/** + * @param size is the length of the value to load. + * + * @param mem is the source memory to load the value from. + * + * @param _return is the pointer to the space where the loaded value will be stored. + */ +void __atomic_load(size_t size, void *mem, void *_return, int model) +{ + rt_base_t level; + level = rt_hw_interrupt_disable(); + rt_memcpy(_return, mem, size); + rt_hw_interrupt_enable(level); +} + +/** + * @param size is the length of the value to store. + * + * @param mem is the destination memory space to store the value. + * + * @param val is the pointer to the value to store. + */ +void __atomic_store(size_t size, void *mem, void *val, int model) +{ + rt_base_t level; + level = rt_hw_interrupt_disable(); + rt_memcpy(mem, val, size); + rt_hw_interrupt_enable(level); +} + +/** + * @param size is the length of value to exchange. + * + * @param mem is the destination space to exchange. + * + * @param val is the pointer of value to exchange. + * + * @param _return gives back the the value before exchanging. + */ +void __atomic_exchange(size_t size, void *mem, void *val, void *_return, int model) +{ + rt_base_t level; + level = rt_hw_interrupt_disable(); + rt_memcpy(_return, mem, size); + rt_memcpy(mem, val, size); + rt_hw_interrupt_enable(level); +} + +/** + * @param size is the length of value to operate. + * + * @param obj is the destination value space to operate. + * + * @param expected is the value to be compared with obj. + * + * @param desired is the value pointer to be written into obj, under the condition that *expected equals *obj. + * + * @return true if succeed in writing *desired into *obj; false if not. +*/ +bool __atomic_compare_exchange(size_t size, void *obj, void *expected, void *desired, int success, int failure) +{ + rt_base_t level; + volatile bool exchanged = false; + level = rt_hw_interrupt_disable(); + if (rt_memcmp(obj, expected, size) == 0) + { + rt_memcpy(obj, desired, size); + exchanged = true; + } + else + { + rt_memcpy(expected, obj, size); + exchanged = false; + } + rt_hw_interrupt_enable(level); + return exchanged; +} + #define __atomic_fetch_op_8(OPNAME, OP) \ uint64_t __atomic_fetch_##OPNAME##_8(volatile void *ptr, uint64_t val, int memorder) {\ volatile uint64_t* val_ptr = (volatile uint64_t*)ptr;\ |
