LockFreeLIFO.c 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #include "LockFreeLIFO.h"
  2. #include "foundation/atomics.h"
  3. /* TODO: on windows, replace with InitializeSListHead/InterlockedPushEntrySList/InterlockedPopEntrySList just to be safe */
  4. void lifo_init(lifo_t *lifo)
  5. {
  6. lifo->head = 0;
  7. }
  8. void lifo_push(lifo_t *lifo, queue_node_t *cl)
  9. {
  10. queue_node_t *new_head = cl;
  11. queue_node_t *old_head = 0;
  12. do
  13. {
  14. old_head = (queue_node_t *)lifo->head;
  15. new_head->Next = old_head;
  16. } while (!nx_atomic_cmpxchg_pointer(old_head, new_head, (void * volatile *)&lifo->head));
  17. }
  18. queue_node_t *lifo_pop(lifo_t *lifo)
  19. {
  20. queue_node_t *new_head = 0, *old_head = 0;
  21. do
  22. {
  23. old_head = (queue_node_t *)lifo->head;
  24. if (old_head)
  25. new_head = old_head->Next;
  26. else
  27. new_head = 0;
  28. } while (!nx_atomic_cmpxchg_pointer(old_head, new_head, (void * volatile *)&lifo->head));
  29. return old_head;
  30. }
  31. queue_node_t *lifo_malloc(size_t bytes)
  32. {
  33. #ifdef __GNUC__
  34. # ifdef __APPLE__
  35. void *v = 0;
  36. (void) posix_memalign(&v, sizeof(void *), bytes);
  37. return v;
  38. # else
  39. return memalign(bytes, sizeof(void *));
  40. # endif
  41. #elif defined(_WIN32)
  42. return _aligned_malloc(bytes, MEMORY_ALLOCATION_ALIGNMENT);
  43. #else
  44. #error port me!
  45. #endif
  46. }
  47. void lifo_free(queue_node_t *ptr)
  48. {
  49. #ifdef __GNUC__
  50. free(ptr);
  51. #elif defined(_WIN32)
  52. _aligned_free(ptr);
  53. #else
  54. #error port me!
  55. #endif
  56. }