You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
lock free multiple producers multiple consumers queue based on ring buffer (RBQ)
#include "rbq.h"
// initialize rbq (size will be (1 << order))
bool bool rbq_init(rbq_t * rbq, int order);
// free ring buffer queue
void rbq_free(rbq_t * rbq);
// ================================================================================
// push/pop/full/empty/size operations =
// ================================================================================
// Push and pop are implemented with a FAA on index and CAS loops on data. =
// FAA will assign a data slot to the caller and CAS loops will make sure =
// a correct data swap. =
// ================================================================================
// CAS loop on data will distribute CAS loops onto the whole data array, and =
// at most 2 threads will loop on one address(a reader and a writer). =
// This will effectively reduce the CAS conflicts and boost the performance. =
// ================================================================================
// Datas enqued/dequeued are assumed to be pointers, =
// NULL is not allowed and it is used as a special value in CAS loop. =
// ================================================================================
bool rbq_push (rbq_t * rbq, void * data);
void * rbq_pop (rbq_t * rbq);
bool rbq_full (const rbq_t * rbq);
bool rbq_empty(const rbq_t * rbq);
size_t rbq_size (const rbq_t * rbq);
// push/pop using the method in
// "Yet another implementation of a lock-free circular array queue"
// by Faustino Frechilla
bool rbq_push2(rbq_t * rbq, void * data);
void * rbq_pop2 (rbq_t * rbq);
// push/pop if only one producer & one consumer
bool rbq_pushspsc(rbq_t * rbq, void * data);
void * rbq_popspsc (rbq_t * rbq);
lock free multiple producers multiple consumers queue based on single linked list (Michael Scott)
lock free memory management based on fixed size memory blocks
All memory blocks in same size are managed in a stack using single
linked list. Allocate or free memory only requires one push/pop op
of the stack, usually, it only needs one pointer assignment.
fixed size memory blocks routines (startup, cleanup, alloc, free)
create a free list with fixed size memory block
allocation of a memory block becomes getting a block from free list
free of a memory block becomes putting a block into free list
general memory malloc/free/realloc/calloc through fixed size memory blocks
maintain fixed size memory blocks with different size
allocation becomes getting a block from corresponding free list
free becomes putting a block into corresponding free list
1 bytes - 240 bytes, maintained in blocks aligned to 16 bytes
241 bytes - 3,840 bytes, maintained in blocks aligned to 256 bytes
3,841 bytes - 61,440 bytes, maintained in blocks aligned to 4k bytes
61,441 bytes - 524,288 bytes, maintained in blocks aligned to 64k bytes
otherwise , call system memory management calls
=============================== API ===============================
#include "fixedSizeMemoryLF.h"
/* ============================================================ *
* Memory management based on fixed size memory block *
* ============================================================ */
// initialzie library
int mmFixedSizeMemoryStartup();
// de-initialize library
void mmFixedSizeMemoryCleanup();
// allocate memory
void * mmFixedSizeMemoryAlloc(size_t nsize);
// free memory block
void mmFixedSizeMemoryFree (void * buf, size_t size);
/* ============================================================== *
* GENERAL PURPOSE MEMORY MANAGEMENT (malloc/free/realloc/calloc) *
* ============================================================== */
void * slab_malloc (size_t size);
void slab_free (void * _pblk);
void * slab_realloc(void * pmem, size_t size);
void * slab_calloc (size_t blksize, size_t numblk);
////////////////////////////////////////////////////////////////////
performance (main.cpp)
running on i7-8750H 2.2G, compiled with Visual Studio 2017.
-------- Lock free ring buffer (SPSC) bench ----------
threads count: 1 totSum = 0, perf (in us per pop/push): 0.089000
-------- Lock free ring buffer (MPMC) bench ----------
threads count: 1 totSum = 0, perf (in us per pop/push): 0.176400
threads count: 2 totSum = 0, perf (in us per pop/push): 0.222120
threads count: 3 totSum = 0, perf (in us per pop/push): 0.174881
threads count: 4 totSum = 0, perf (in us per pop/push): 0.141935
threads count: 5 totSum = 0, perf (in us per pop/push): 0.140524
threads count: 6 totSum = 0, perf (in us per pop/push): 0.140971
threads count: 7 totSum = 0, perf (in us per pop/push): 0.163714
threads count: 8 totSum = 0, perf (in us per pop/push): 0.140792
-------- Lock free queue (MSQ) bench ----------
threads count: 1 totSum = 0, perf (in us per pop/push): 0.319150
threads count: 2 totSum = 0, perf (in us per pop/push): 0.460602
threads count: 3 totSum = 0, perf (in us per pop/push): 0.626329
threads count: 4 totSum = 0, perf (in us per pop/push): 0.705676
threads count: 5 totSum = 0, perf (in us per pop/push): 0.688684
threads count: 6 totSum = 0, perf (in us per pop/push): 0.621664
threads count: 7 totSum = 0, perf (in us per pop/push): 0.684918
threads count: 8 totSum = 0, perf (in us per pop/push): 0.672412
-------- Lock free stack bench ----------
threads count: 1 totSum = 0, perf (in us per pop/push): 0.293375
threads count: 2 totSum = 0, perf (in us per pop/push): 0.494783
threads count: 3 totSum = 0, perf (in us per pop/push): 0.628804
threads count: 4 totSum = 0, perf (in us per pop/push): 0.727656
threads count: 5 totSum = 0, perf (in us per pop/push): 0.674413
threads count: 6 totSum = 0, perf (in us per pop/push): 0.676848
threads count: 7 totSum = 0, perf (in us per pop/push): 0.729400
threads count: 8 totSum = 0, perf (in us per pop/push): 0.703722