aboutsummaryrefslogtreecommitdiff
path: root/Src/replicant/nu/LockFreeLIFO.c
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/replicant/nu/LockFreeLIFO.c
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/replicant/nu/LockFreeLIFO.c')
-rw-r--r--Src/replicant/nu/LockFreeLIFO.c61
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
+ }