项目作者: huangfcn

项目描述 :
lock-free data structures: SPSC ring buffer, MPMC ring buffer, MPMC single linked list queue, MPMC single linked list stack; lock free memory management library using fix sized memory managed in single linked list
高级语言: C
项目地址: git://github.com/huangfcn/lockfree.git
创建时间: 2019-11-14T03:59:34Z
项目社区:https://github.com/huangfcn/lockfree

开源协议:

下载


lock free single producer single consumer queue based on ring buffer (magic ring buffer)

  1. #include "magicq.h"
  2. // initialize magicq (size will be (1 << order))
  3. bool magicq_init(magicq_t * cb, int order);
  4. // free magicq
  5. void magicq_free(magicq_t * cb);
  6. // push/pop/full/empty/size operations
  7. bool magicq_push(magicq_t * cb, void * data);
  8. void * magicq_pop (magicq_t * cb);
  9. bool magicq_full (const magicq_t * cb);
  10. bool magicq_empty(const magicq_t * cb);
  11. size_t magicq_size (const magicq_t * cb);

lock free multiple producers multiple consumers queue based on ring buffer (RBQ)

  1. #include "rbq.h"
  2. // initialize rbq (size will be (1 << order))
  3. bool bool rbq_init(rbq_t * rbq, int order);
  4. // free ring buffer queue
  5. void rbq_free(rbq_t * rbq);
  6. // ================================================================================
  7. // push/pop/full/empty/size operations =
  8. // ================================================================================
  9. // Push and pop are implemented with a FAA on index and CAS loops on data. =
  10. // FAA will assign a data slot to the caller and CAS loops will make sure =
  11. // a correct data swap. =
  12. // ================================================================================
  13. // CAS loop on data will distribute CAS loops onto the whole data array, and =
  14. // at most 2 threads will loop on one address(a reader and a writer). =
  15. // This will effectively reduce the CAS conflicts and boost the performance. =
  16. // ================================================================================
  17. // Datas enqued/dequeued are assumed to be pointers, =
  18. // NULL is not allowed and it is used as a special value in CAS loop. =
  19. // ================================================================================
  20. bool rbq_push (rbq_t * rbq, void * data);
  21. void * rbq_pop (rbq_t * rbq);
  22. bool rbq_full (const rbq_t * rbq);
  23. bool rbq_empty(const rbq_t * rbq);
  24. size_t rbq_size (const rbq_t * rbq);
  25. // push/pop using the method in
  26. // "Yet another implementation of a lock-free circular array queue"
  27. // by Faustino Frechilla
  28. bool rbq_push2(rbq_t * rbq, void * data);
  29. void * rbq_pop2 (rbq_t * rbq);
  30. // push/pop if only one producer & one consumer
  31. bool rbq_pushspsc(rbq_t * rbq, void * data);
  32. void * rbq_popspsc (rbq_t * rbq);

lock free multiple producers multiple consumers queue based on single linked list (Michael Scott)

  1. #include "lffifo.h"
  2. // initialize lock-free msq
  3. bool lffifo_init(lffifo_t * fifo);
  4. // free msq
  5. void lffifo_free(lffifo_t * fifo);
  6. // push/pop/full/empty/size operations
  7. bool lffifo_push (lffifo_t * fifo, void * value);
  8. void * lffifo_pop (lffifo_t * fifo);
  9. bool lffifo_full (const lffifo_t * fifo);
  10. bool lffifo_empty(const lffifo_t * fifo);
  11. size_t lffifo_size (const lffifo_t * fifo);

lock free multiple producers multiple consumers stack based on single linked list

  1. #include "lffifo.h"
  2. // initialize lock-free stack
  3. bool lfstack_init(lfstack_t * stack);
  4. // free stack
  5. void lfstack_free(lfstack_t * stack);
  6. // push/pop/full/empty/size operations
  7. bool lfstack_push(lfstack_t * stack, void * value);
  8. void * lfstack_pop (lfstack_t * stack);
  9. bool lfstack_full (const lfstack_t * stack);
  10. bool lfstack_empty(const lfstack_t * stack);
  11. size_t lfstack_size (const lfstack_t * stack);

lock free memory management based on fixed size memory blocks

  1. All memory blocks in same size are managed in a stack using single
  2. linked list. Allocate or free memory only requires one push/pop op
  3. of the stack, usually, it only needs one pointer assignment.
  4. fixed size memory blocks routines (startup, cleanup, alloc, free)
  5. create a free list with fixed size memory block
  6. allocation of a memory block becomes getting a block from free list
  7. free of a memory block becomes putting a block into free list
  8. general memory malloc/free/realloc/calloc through fixed size memory blocks
  9. maintain fixed size memory blocks with different size
  10. allocation becomes getting a block from corresponding free list
  11. free becomes putting a block into corresponding free list
  12. 1 bytes - 240 bytes, maintained in blocks aligned to 16 bytes
  13. 241 bytes - 3,840 bytes, maintained in blocks aligned to 256 bytes
  14. 3,841 bytes - 61,440 bytes, maintained in blocks aligned to 4k bytes
  15. 61,441 bytes - 524,288 bytes, maintained in blocks aligned to 64k bytes
  16. otherwise , call system memory management calls
  17. =============================== API ===============================
  18. #include "fixedSizeMemoryLF.h"
  19. /* ============================================================ *
  20. * Memory management based on fixed size memory block *
  21. * ============================================================ */
  22. // initialzie library
  23. int mmFixedSizeMemoryStartup();
  24. // de-initialize library
  25. void mmFixedSizeMemoryCleanup();
  26. // allocate memory
  27. void * mmFixedSizeMemoryAlloc(size_t nsize);
  28. // free memory block
  29. void mmFixedSizeMemoryFree (void * buf, size_t size);
  30. /* ============================================================== *
  31. * GENERAL PURPOSE MEMORY MANAGEMENT (malloc/free/realloc/calloc) *
  32. * ============================================================== */
  33. void * slab_malloc (size_t size);
  34. void slab_free (void * _pblk);
  35. void * slab_realloc(void * pmem, size_t size);
  36. void * slab_calloc (size_t blksize, size_t numblk);
  37. ////////////////////////////////////////////////////////////////////

performance (main.cpp)

  1. running on i7-8750H 2.2G, compiled with Visual Studio 2017.
  2. -------- Lock free ring buffer (SPSC) bench ----------
  3. threads count: 1 totSum = 0, perf (in us per pop/push): 0.089000
  4. -------- Lock free ring buffer (MPMC) bench ----------
  5. threads count: 1 totSum = 0, perf (in us per pop/push): 0.176400
  6. threads count: 2 totSum = 0, perf (in us per pop/push): 0.222120
  7. threads count: 3 totSum = 0, perf (in us per pop/push): 0.174881
  8. threads count: 4 totSum = 0, perf (in us per pop/push): 0.141935
  9. threads count: 5 totSum = 0, perf (in us per pop/push): 0.140524
  10. threads count: 6 totSum = 0, perf (in us per pop/push): 0.140971
  11. threads count: 7 totSum = 0, perf (in us per pop/push): 0.163714
  12. threads count: 8 totSum = 0, perf (in us per pop/push): 0.140792
  13. -------- Lock free queue (MSQ) bench ----------
  14. threads count: 1 totSum = 0, perf (in us per pop/push): 0.319150
  15. threads count: 2 totSum = 0, perf (in us per pop/push): 0.460602
  16. threads count: 3 totSum = 0, perf (in us per pop/push): 0.626329
  17. threads count: 4 totSum = 0, perf (in us per pop/push): 0.705676
  18. threads count: 5 totSum = 0, perf (in us per pop/push): 0.688684
  19. threads count: 6 totSum = 0, perf (in us per pop/push): 0.621664
  20. threads count: 7 totSum = 0, perf (in us per pop/push): 0.684918
  21. threads count: 8 totSum = 0, perf (in us per pop/push): 0.672412
  22. -------- Lock free stack bench ----------
  23. threads count: 1 totSum = 0, perf (in us per pop/push): 0.293375
  24. threads count: 2 totSum = 0, perf (in us per pop/push): 0.494783
  25. threads count: 3 totSum = 0, perf (in us per pop/push): 0.628804
  26. threads count: 4 totSum = 0, perf (in us per pop/push): 0.727656
  27. threads count: 5 totSum = 0, perf (in us per pop/push): 0.674413
  28. threads count: 6 totSum = 0, perf (in us per pop/push): 0.676848
  29. threads count: 7 totSum = 0, perf (in us per pop/push): 0.729400
  30. threads count: 8 totSum = 0, perf (in us per pop/push): 0.703722