diff options
| author | 2024-10-04 12:30:41 -0400 | |
|---|---|---|
| committer | 2024-10-04 12:30:41 -0400 | |
| commit | 71dbdb7241fcae5ae91524669ede2d549bdb0ee6 (patch) | |
| tree | 6a23b45c56dbd73218c278962a0dc46595304715 | |
| parent | 395d423e6a6fda56e02d9551cadc93d229fe71c5 (diff) | |
| download | libalabaster-71dbdb7241fcae5ae91524669ede2d549bdb0ee6.tar.gz libalabaster-71dbdb7241fcae5ae91524669ede2d549bdb0ee6.tar.bz2 libalabaster-71dbdb7241fcae5ae91524669ede2d549bdb0ee6.zip | |
atomic: New syntax
al_atomic_ptr_load() -> al_atomic_load(void)()
al_atomic_u16_store() -> al_atomic_store(u16)()
...
Signed-off-by: Andrew Opalach <andrew@akon.city>
| -rw-r--r-- | include/al/atomic.h | 78 | ||||
| -rw-r--r-- | include/al/random.h | 17 | ||||
| -rw-r--r-- | src/ring_buffer.c | 44 | ||||
| -rw-r--r-- | tests/ring_buffer.c | 6 |
4 files changed, 78 insertions, 67 deletions
diff --git a/include/al/atomic.h b/include/al/atomic.h index 1b733ad..7f8a087 100644 --- a/include/al/atomic.h +++ b/include/al/atomic.h @@ -12,44 +12,54 @@ #define AL_ATOMIC_ACQ_REL c89atomic_memory_order_acq_rel #define AL_ATOMIC_SEQ_CST c89atomic_memory_order_seq_cst -#define al_atomic_ptr_load(p, order) c89atomic_load_explicit_ptr(((volatile void **)p), order) -#define al_atomic_ptr_store(p, v, order) c89atomic_store_explicit_ptr(((volatile void **)p), (void *)v, order) +#define atomic(T) _al_atomic_##T -#define atomic_size_t c89atomic_uint64 -#define al_atomic_size_t_load(p, order) ((size_t)c89atomic_load_explicit_64(p, order)) -#define al_atomic_size_t_store(p, v, order) c89atomic_store_explicit_64(p, ((size_t)v), order) +#define al_atomic_load(T) _al_atomic_load_##T +#define al_atomic_store(T) _al_atomic_store_##T +#define al_atomic_add(T) _al_atomic_add_##T +#define al_atomic_sub(T) _al_atomic_sub_##T -#define atomic_s64 c89atomic_int64 -#define al_atomic_s64_load(p, order) ((s64)c89atomic_load_explicit_i64(p, order)) -#define al_atomic_s64_store(p, v, order) c89atomic_store_explicit_i64(p, ((s64)v), order) +// Special case for pointers. +#define _al_atomic_load_void(p, order) c89atomic_load_explicit_ptr(((volatile void **)p), order) +#define _al_atomic_store_void(p, v, order) c89atomic_store_explicit_ptr(((volatile void **)p), (void *)v, order) -#define atomic_u64 c89atomic_uint64 -#define al_atomic_u64_load(p, order) ((u64)c89atomic_load_explicit_64(p, order)) -#define al_atomic_u64_store(p, v, order) c89atomic_store_explicit_64(p, ((u64)v), order) -#define al_atomic_u64_add(p, v, order) c89atomic_fetch_add_explicit_64(p, ((u64)v), order) -#define al_atomic_u64_sub(p, v, order) c89atomic_fetch_sub_explicit_64(p, ((u64)v), order) +// c89atomic compat. +typedef f64 c89atomic_f64; +typedef f32 c89atomic_f32; -#define atomic_f64 f64 -#define al_atomic_f64_load(p, order) ((f64)c89atomic_load_explicit_f64(p, order)) -#define al_atomic_f64_store(p, v, order) c89atomic_store_explicit_f64(p, ((f64)v), order) +#define AL_ATOMIC_DEFINE(T, C, S) \ + typedef c89atomic_##C atomic(T); \ + static inline T al_atomic_load(T)(atomic(T) *a, int order) \ + { \ + return c89atomic_load_explicit_##S(a, order); \ + } \ + static inline void al_atomic_store(T)(atomic(T) *a, T value, int order) \ + { \ + c89atomic_store_explicit_##S(a, value, order); \ + } \ + static inline T al_atomic_add(T)(atomic(T) *a, T value, int order) \ + { \ + return c89atomic_fetch_add_explicit_##S(a, value, order); \ + } \ + static inline T al_atomic_sub(T)(atomic(T) *a, T value, int order) \ + { \ + return c89atomic_fetch_sub_explicit_##S(a, value, order); \ + } -#define atomic_s32 c89atomic_int32 -#define al_atomic_s32_load(p, order) ((s32)c89atomic_load_explicit_i32(p, order)) -#define al_atomic_s32_store(p, v, order) c89atomic_store_explicit_i32(p, ((s32)v), order) -#define al_atomic_s32_add(p, v, order) c89atomic_fetch_add_explicit_i32(p, ((s32)v), order) -#define al_atomic_s32_sub(p, v, order) c89atomic_fetch_sub_explicit_i32(p, ((s32)v), order) - -#define atomic_u16 c89atomic_uint16 -#define al_atomic_u16_load(p, order) c89atomic_load_explicit_16(p, order) -#define al_atomic_u16_store(p, v, order) c89atomic_store_explicit_16(p, ((u16)v), order) -#define al_atomic_u16_add(p, v, order) c89atomic_fetch_add_explicit_16(p, ((u16)v), order) - -#define atomic_u8 c89atomic_uint8 -#define al_atomic_u8_load(p, order) c89atomic_load_explicit_8(p, order) -#define al_atomic_u8_store(p, v, order) c89atomic_store_explicit_8(p, ((u8)v), order) - -#define atomic_bool c89atomic_uint8 -#define al_atomic_bool_load(p, order) c89atomic_load_explicit_8(p, order) -#define al_atomic_bool_store(p, v, order) c89atomic_store_explicit_8(p, ((bool)v), order) +#if defined C89ATOMIC_64BIT +AL_ATOMIC_DEFINE(size_t, uint64, 64) +#elif defined C89ATOMIC_32BIT +AL_ATOMIC_DEFINE(size_t, uint32, 32) +#endif +AL_ATOMIC_DEFINE(u64, uint64, 64); +AL_ATOMIC_DEFINE(s64, int64, i64); +AL_ATOMIC_DEFINE(u32, uint32, 32); +AL_ATOMIC_DEFINE(s32, int32, i32); +AL_ATOMIC_DEFINE(u16, uint16, 16); +AL_ATOMIC_DEFINE(s16, int16, i16); +AL_ATOMIC_DEFINE(u8, uint8, 8); +AL_ATOMIC_DEFINE(s8, int8, i8); +AL_ATOMIC_DEFINE(f64, f64, f64); +AL_ATOMIC_DEFINE(f32, f32, f32); #endif // _AL_ATOMIC_H diff --git a/include/al/random.h b/include/al/random.h index 40c8654..9d27c18 100644 --- a/include/al/random.h +++ b/include/al/random.h @@ -18,17 +18,18 @@ static s32 al_rand(void) return rand(); } -static atomic_u16 _al_rand_value = 1; +// Each file that includes this header will have a separate counter. +static atomic(u16) _al_inc_value = 1; -// Temporary, can guarantee no collisions for the current use case. This functions per-file, -// so each file this is included in will have a seperate counter. -static u16 al_rand_u16(void) +// This is apart of random because currently al_inc_u16() is used as a substitute +// for proper random ID generation. +static u16 al_inc_u16(void) { - u16 ret = al_atomic_u16_add(&_al_rand_value, 1, AL_ATOMIC_RELAXED); - if (ret == UINT16_MAX) { - al_atomic_u16_store(&_al_rand_value, 1, AL_ATOMIC_RELAXED); + if (al_atomic_load(u16)(&_al_inc_value, AL_ATOMIC_ACQUIRE) == UINT16_MAX) { + al_atomic_store(u16)(&_al_inc_value, 1, AL_ATOMIC_RELEASE); + return 1; } - return ret; + return al_atomic_add(u16)(&_al_inc_value, 1, AL_ATOMIC_RELEASE); } AL_UNUSED_FUNCTION_POP diff --git a/src/ring_buffer.c b/src/ring_buffer.c index c985d86..adb22ad 100644 --- a/src/ring_buffer.c +++ b/src/ring_buffer.c @@ -23,20 +23,20 @@ static inline void add(struct al_ring_buffer *buf, u8 **v, u8 *ptr, size_t n) ptr += n; al_assert(ptr <= buf->end); if (ptr == buf->end) ptr = buf->start; - al_atomic_ptr_store(v, ptr, AL_ATOMIC_RELEASE); + al_atomic_store(void)(v, ptr, AL_ATOMIC_RELEASE); } size_t al_ring_buffer_space(struct al_ring_buffer *buf) { - u8 *wp = al_atomic_ptr_load(&buf->write, AL_ATOMIC_RELAXED); - u8 *rp = previous(buf, (u8 *)al_atomic_ptr_load(&buf->read, AL_ATOMIC_RELAXED)); + u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); + u8 *rp = previous(buf, (u8 *)al_atomic_load(void)(&buf->read, AL_ATOMIC_RELAXED)); return (wp <= rp) ? rp - wp : (buf->end - wp) + (rp - buf->start); } u8 *al_ring_buffer_write_chunk(struct al_ring_buffer *buf, size_t *size) { - u8 *wp = al_atomic_ptr_load(&buf->write, AL_ATOMIC_ACQUIRE); - u8 *rp = previous(buf, al_atomic_ptr_load(&buf->read, AL_ATOMIC_RELAXED)); + u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_ACQUIRE); + u8 *rp = previous(buf, al_atomic_load(void)(&buf->read, AL_ATOMIC_RELAXED)); *size = (wp <= rp ? rp : buf->end) - wp; return wp; } @@ -48,15 +48,15 @@ void al_ring_buffer_append(struct al_ring_buffer *buf, u8 *ptr, size_t n) size_t al_ring_buffer_occupied(struct al_ring_buffer *buf) { - u8 *rp = al_atomic_ptr_load(&buf->read, AL_ATOMIC_RELAXED); - u8 *wp = al_atomic_ptr_load(&buf->write, AL_ATOMIC_RELAXED); + u8 *rp = al_atomic_load(void)(&buf->read, AL_ATOMIC_RELAXED); + u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); return (rp <= wp) ? wp - rp : (buf->end - rp) + (wp - buf->start); } u8 *al_ring_buffer_read_chunk(struct al_ring_buffer *buf, size_t *size) { - u8 *rp = al_atomic_ptr_load(&buf->read, AL_ATOMIC_ACQUIRE); - u8 *wp = al_atomic_ptr_load(&buf->write, AL_ATOMIC_RELAXED); + u8 *rp = al_atomic_load(void)(&buf->read, AL_ATOMIC_ACQUIRE); + u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); *size = (rp <= wp ? wp : buf->end) - rp; return rp; } @@ -68,8 +68,8 @@ void al_ring_buffer_consume(struct al_ring_buffer *buf, u8 *ptr, size_t n) size_t al_ring_buffer_write(struct al_ring_buffer *buf, u8 *data, size_t n) { - u8 *wp = al_atomic_ptr_load(&buf->write, AL_ATOMIC_ACQUIRE); - u8 *rp = previous(buf, al_atomic_ptr_load(&buf->read, AL_ATOMIC_RELAXED)); + u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_ACQUIRE); + u8 *rp = previous(buf, al_atomic_load(void)(&buf->read, AL_ATOMIC_RELAXED)); size_t size = AL_MIN((wp <= rp ? rp : buf->end) - wp, (ptrdiff_t)n); @@ -83,15 +83,15 @@ size_t al_ring_buffer_write(struct al_ring_buffer *buf, u8 *data, size_t n) size += wrap; } - al_atomic_ptr_store(&buf->write, wp, AL_ATOMIC_RELEASE); + al_atomic_store(void)(&buf->write, wp, AL_ATOMIC_RELEASE); return size; } size_t al_ring_buffer_read(struct al_ring_buffer *buf, u8 *ptr, size_t n) { - u8 *rp = al_atomic_ptr_load(&buf->read, AL_ATOMIC_ACQUIRE); - u8 *wp = al_atomic_ptr_load(&buf->write, AL_ATOMIC_RELAXED); + u8 *rp = al_atomic_load(void)(&buf->read, AL_ATOMIC_ACQUIRE); + u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); size_t size = AL_MIN((rp <= wp ? wp : buf->end) - rp, (ptrdiff_t)n); @@ -105,15 +105,15 @@ size_t al_ring_buffer_read(struct al_ring_buffer *buf, u8 *ptr, size_t n) size += wrap; } - al_atomic_ptr_store(&buf->read, rp, AL_ATOMIC_RELEASE); + al_atomic_store(void)(&buf->read, rp, AL_ATOMIC_RELEASE); return size; } size_t al_ring_buffer_peek(struct al_ring_buffer *buf, u8 *ptr, size_t offset, size_t n) { - u8 *rp = al_atomic_ptr_load(&buf->read, AL_ATOMIC_RELAXED); - u8 *wp = al_atomic_ptr_load(&buf->write, AL_ATOMIC_RELAXED); + u8 *rp = al_atomic_load(void)(&buf->read, AL_ATOMIC_RELAXED); + u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); ptrdiff_t size; @@ -145,8 +145,8 @@ size_t al_ring_buffer_peek(struct al_ring_buffer *buf, u8 *ptr, size_t offset, s size_t al_ring_buffer_discard(struct al_ring_buffer *buf, size_t n) { - u8 *rp = al_atomic_ptr_load(&buf->read, AL_ATOMIC_ACQUIRE); - u8 *wp = al_atomic_ptr_load(&buf->write, AL_ATOMIC_RELAXED); + u8 *rp = al_atomic_load(void)(&buf->read, AL_ATOMIC_ACQUIRE); + u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); size_t discard = AL_MIN((rp <= wp ? wp : buf->end) - rp, (ptrdiff_t)n); rp += discard; @@ -157,7 +157,7 @@ size_t al_ring_buffer_discard(struct al_ring_buffer *buf, size_t n) discard += wrap; } - al_atomic_ptr_store(&buf->read, rp, AL_ATOMIC_RELEASE); + al_atomic_store(void)(&buf->read, rp, AL_ATOMIC_RELEASE); return discard; } @@ -165,6 +165,6 @@ size_t al_ring_buffer_discard(struct al_ring_buffer *buf, size_t n) // Not thread-safe. void al_ring_buffer_reset(struct al_ring_buffer *buf) { - al_atomic_ptr_store(&buf->read, buf->start, AL_ATOMIC_RELAXED); - al_atomic_ptr_store(&buf->write, buf->start, AL_ATOMIC_RELAXED); + al_atomic_store(void)(&buf->read, buf->start, AL_ATOMIC_RELAXED); + al_atomic_store(void)(&buf->write, buf->start, AL_ATOMIC_RELAXED); } diff --git a/tests/ring_buffer.c b/tests/ring_buffer.c index a8e26ef..30b583e 100644 --- a/tests/ring_buffer.c +++ b/tests/ring_buffer.c @@ -18,8 +18,8 @@ static bool ring_buffer_test_init(void) AL_TEST_EQ(buf.start, buffer, ptr); AL_TEST_EQ(buf.end, buffer + TEST_BUFFER_SIZE, ptr); - AL_TEST_EQ(al_atomic_ptr_load(&buf.read, AL_ATOMIC_RELAXED), buffer, ptr); - AL_TEST_EQ(al_atomic_ptr_load(&buf.write, AL_ATOMIC_RELAXED), buffer, ptr); + AL_TEST_EQ(al_atomic_load(void)(&buf.read, AL_ATOMIC_RELAXED), buffer, ptr); + AL_TEST_EQ(al_atomic_load(void)(&buf.write, AL_ATOMIC_RELAXED), buffer, ptr); AL_TEST_END(); } @@ -112,7 +112,7 @@ static bool ring_buffer_test_read_and_write(void) AL_TEST_EQ(al_ring_buffer_write(&buf, buffer_half, sizeof(buffer_half)), sizeof(buffer_half), size_t); AL_TEST_EQ(al_ring_buffer_occupied(&buf), TEST_BUFFER_SIZE - data_size, size_t); - AL_TEST_LT(al_atomic_ptr_load(&buf.write, AL_ATOMIC_RELAXED), al_atomic_ptr_load(&buf.read, AL_ATOMIC_RELAXED), ptr); + AL_TEST_LT(al_atomic_load(void)(&buf.write, AL_ATOMIC_RELAXED), al_atomic_load(void)(&buf.read, AL_ATOMIC_RELAXED), ptr); size_t space = al_ring_buffer_space(&buf); AL_TEST_EQ(space, data_size - 1, size_t); |