#include "magicq.h"
// initialize magicq (size will be (1 << order))
bool magicq_init(magicq_t * cb, int order);
// free magicq
void magicq_free(magicq_t * cb);
// push/pop/full/empty/size operations
bool magicq_push(magicq_t * cb, void * data);
void * magicq_pop (magicq_t * cb);
bool magicq_full (const magicq_t * cb);
bool magicq_empty(const magicq_t * cb);
size_t magicq_size (const magicq_t * cb);
#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);
#include "lffifo.h"
// initialize lock-free msq
bool lffifo_init(lffifo_t * fifo);
// free msq
void lffifo_free(lffifo_t * fifo);
// push/pop/full/empty/size operations
bool lffifo_push (lffifo_t * fifo, void * value);
void * lffifo_pop (lffifo_t * fifo);
bool lffifo_full (const lffifo_t * fifo);
bool lffifo_empty(const lffifo_t * fifo);
size_t lffifo_size (const lffifo_t * fifo);
#include "lffifo.h"
// initialize lock-free stack
bool lfstack_init(lfstack_t * stack);
// free stack
void lfstack_free(lfstack_t * stack);
// push/pop/full/empty/size operations
bool lfstack_push(lfstack_t * stack, void * value);
void * lfstack_pop (lfstack_t * stack);
bool lfstack_full (const lfstack_t * stack);
bool lfstack_empty(const lfstack_t * stack);
size_t lfstack_size (const lfstack_t * stack);
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);
////////////////////////////////////////////////////////////////////
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