Small improvements of the LF MPMC queue Making the LF MPMC queue generic and in a seperate header file
162 lines
3.7 KiB
C
162 lines
3.7 KiB
C
#pragma once
|
|
|
|
#include <assert.h>
|
|
#include <immintrin.h>
|
|
#include <stdatomic.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
|
|
#if defined(_WIN32) || defined(_WIN64)
|
|
#define PLATFORM_WINDOWS 1
|
|
#include <aclapi.h>
|
|
#include <fcntl.h>
|
|
#include <io.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <windows.h>
|
|
|
|
#define strdup _strdup
|
|
#else
|
|
#include <dirent.h>
|
|
#include <fcntl.h>
|
|
#include <pthread.h>
|
|
#include <pwd.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#define XXH_VECTOR \
|
|
XXH_AVX2 // not recommanded to compile with gcc see xxhash.h line 4082
|
|
// Must compile with /arch:AVX2 in clang-cl or -mavx2 in clang/gcc
|
|
#define XXH_INLINE_ALL
|
|
#include "xxhash.c"
|
|
#include "xxhash.h"
|
|
|
|
/* ------------------------------------------------------------
|
|
Base types
|
|
------------------------------------------------------------ */
|
|
|
|
typedef uint8_t u8;
|
|
typedef uint16_t u16;
|
|
typedef uint32_t u32;
|
|
typedef uint64_t u64;
|
|
typedef int8_t i8;
|
|
typedef int16_t i16;
|
|
typedef int32_t i32;
|
|
typedef int64_t i64;
|
|
|
|
typedef i8 b8;
|
|
typedef int b32;
|
|
|
|
typedef float f32;
|
|
typedef double f64;
|
|
|
|
/* ------------------------------------------------------------
|
|
Size helpers
|
|
------------------------------------------------------------ */
|
|
|
|
#define KiB(x) ((u64)(x) * 1024ULL)
|
|
#define MiB(x) (KiB(x) * 1024ULL)
|
|
#define GiB(x) (MiB(x) * 1024ULL)
|
|
|
|
/* ------------------------------------------------------------
|
|
Min / Max helpers
|
|
------------------------------------------------------------ */
|
|
|
|
#ifndef MIN
|
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
#endif
|
|
|
|
#ifndef MAX
|
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
|
#endif
|
|
|
|
/* ------------------------------------------------------------
|
|
Alignment helpers
|
|
------------------------------------------------------------ */
|
|
|
|
#define ALIGN_UP_POW2(x, a) ((a) ? (((x) + ((a) - 1)) & ~((a) - 1)) : (x))
|
|
|
|
/* ------------------------------------------------------------
|
|
Assert
|
|
------------------------------------------------------------ */
|
|
|
|
#ifndef ASSERT
|
|
#define ASSERT(x) assert(x)
|
|
#endif
|
|
|
|
#define NDEBUG // Comment to enable asserts
|
|
|
|
/* ------------------------------------------------------------
|
|
Some helper functions
|
|
------------------------------------------------------------ */
|
|
|
|
#if defined(_WIN32) || defined(_WIN64)
|
|
|
|
static u32 plat_get_pagesize(void) {
|
|
SYSTEM_INFO sysinfo = {0};
|
|
GetSystemInfo(&sysinfo);
|
|
|
|
return sysinfo.dwPageSize;
|
|
}
|
|
|
|
static void *plat_mem_reserve(u64 size) {
|
|
return VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_READWRITE);
|
|
}
|
|
|
|
static b32 plat_mem_commit(void *ptr, u64 size) {
|
|
void *ret = VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE);
|
|
return ret != NULL;
|
|
}
|
|
|
|
static b32 plat_mem_decommit(void *ptr, u64 size) {
|
|
return VirtualFree(ptr, size, MEM_DECOMMIT);
|
|
}
|
|
|
|
static b32 plat_mem_release(void *ptr, u64 size) {
|
|
return VirtualFree(ptr, size, MEM_RELEASE);
|
|
}
|
|
|
|
#elif defined(__linux__)
|
|
|
|
#ifndef _DEFAULT_SOURCE
|
|
#define _DEFAULT_SOURCE
|
|
#endif
|
|
|
|
#include <sys/mman.h>
|
|
#include <unistd.h>
|
|
|
|
static u32 plat_get_pagesize(void) { return (u32)sysconf(_SC_PAGESIZE); }
|
|
|
|
static void *plat_mem_reserve(u64 size) {
|
|
void *out = mmap(NULL, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
if (out == MAP_FAILED) {
|
|
return NULL;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
static b32 plat_mem_commit(void *ptr, u64 size) {
|
|
i32 ret = mprotect(ptr, size, PROT_READ | PROT_WRITE);
|
|
return ret == 0;
|
|
}
|
|
|
|
static b32 plat_mem_decommit(void *ptr, u64 size) {
|
|
i32 ret = mprotect(ptr, size, PROT_NONE);
|
|
if (ret != 0)
|
|
return false;
|
|
ret = madvise(ptr, size, MADV_DONTNEED);
|
|
return ret == 0;
|
|
}
|
|
|
|
static b32 plat_mem_release(void *ptr, u64 size) {
|
|
i32 ret = munmap(ptr, size);
|
|
return ret == 0;
|
|
}
|
|
|
|
#endif
|