diff options
author | Jean-Francois Mauguit <jfmauguit@mac.com> | 2024-09-24 09:03:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-24 09:03:25 -0400 |
commit | bab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/replicant/nu/LockFreeLIFO.c | |
parent | 4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff) | |
parent | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff) | |
download | winamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz |
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/replicant/nu/LockFreeLIFO.c')
-rw-r--r-- | Src/replicant/nu/LockFreeLIFO.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/Src/replicant/nu/LockFreeLIFO.c b/Src/replicant/nu/LockFreeLIFO.c new file mode 100644 index 00000000..eb9c1eb1 --- /dev/null +++ b/Src/replicant/nu/LockFreeLIFO.c @@ -0,0 +1,61 @@ +#include "LockFreeLIFO.h" +#include "foundation/atomics.h" + +/* TODO: on windows, replace with InitializeSListHead/InterlockedPushEntrySList/InterlockedPopEntrySList just to be safe */ +void lifo_init(lifo_t *lifo) +{ + lifo->head = 0; +} + +void lifo_push(lifo_t *lifo, queue_node_t *cl) +{ + queue_node_t *new_head = cl; + queue_node_t *old_head = 0; + do + { + old_head = (queue_node_t *)lifo->head; + new_head->Next = old_head; + } while (!nx_atomic_cmpxchg_pointer(old_head, new_head, (void * volatile *)&lifo->head)); +} + +queue_node_t *lifo_pop(lifo_t *lifo) +{ + queue_node_t *new_head = 0, *old_head = 0; + do + { + old_head = (queue_node_t *)lifo->head; + if (old_head) + new_head = old_head->Next; + else + new_head = 0; + } while (!nx_atomic_cmpxchg_pointer(old_head, new_head, (void * volatile *)&lifo->head)); + return old_head; +} + + queue_node_t *lifo_malloc(size_t bytes) + { +#ifdef __GNUC__ +# ifdef __APPLE__ + void *v = 0; + (void) posix_memalign(&v, sizeof(void *), bytes); + return v; +# else + return memalign(bytes, sizeof(void *)); +# endif +#elif defined(_WIN32) + return _aligned_malloc(bytes, MEMORY_ALLOCATION_ALIGNMENT); +#else +#error port me! +#endif + } + + void lifo_free(queue_node_t *ptr) + { +#ifdef __GNUC__ + free(ptr); +#elif defined(_WIN32) + _aligned_free(ptr); +#else +#error port me! +#endif + } |