Files
filehasher/base.h
2026-05-01 20:59:51 +01:00

245 lines
5.5 KiB
C

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#if defined(_WIN32) || defined(_WIN64)
#if defined(_MSC_VER)
#pragma comment(lib, "advapi32.lib")
#endif
#include <aclapi.h>
#include <fcntl.h>
#include <io.h>
#include <ioringapi.h> // Needs to be included before stdatomic to avoid errors
#include <ntioring_x.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <windows.h>
#include <winerror.h>
#elif defined(__linux__)
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dirent.h>
#include <fcntl.h>
#include <liburing.h>
#include <poll.h>
#include <pthread.h>
#include <pwd.h>
#include <sys/eventfd.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/vfs.h>
#include <unistd.h>
#endif
#include <assert.h>
#include <ctype.h>
#include <immintrin.h>
#include <limits.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.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
#ifndef NDEBUG
#define NDEBUG 1 // 0 to enable asserts
#endif
/* ------------------------------------------------------------
Some helper functions
------------------------------------------------------------ */
#if defined(_WIN32) || defined(_WIN64)
// Memory allocation
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) { // Comment to prevent warning: unused function
// return VirtualFree(ptr, size, MEM_DECOMMIT);
// }
static b32 plat_mem_release(void *ptr, u64 size) {
return VirtualFree(ptr, size, MEM_RELEASE);
}
// Semaphores
typedef struct plat_sem {
HANDLE handle;
} plat_sem;
static b32 plat_sem_init(plat_sem *s, u32 initial) {
s->handle = CreateSemaphore(NULL, initial, LONG_MAX, NULL);
return s->handle != NULL;
}
static void plat_sem_wait(plat_sem *s) {
WaitForSingleObject(s->handle, INFINITE);
}
// static b32 plat_sem_trywait(HANDLE sem) { // Comment to prevent warning: unused function
// DWORD r = WaitForSingleObject(sem, 0);
// return r == WAIT_OBJECT_0;
// }
static void plat_sem_post(plat_sem *s, u32 count) {
ReleaseSemaphore(s->handle, count, NULL);
}
// static void plat_sem_destroy(plat_sem *s) { // Comment to prevent warning: unused function
// if (s->handle) {
// CloseHandle(s->handle);
// s->handle = NULL;
// }
// }
// Sleep
static void sleep_ms(int ms) { Sleep(ms); }
#elif defined(__linux__)
// Memory allocation
#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) { // Comment to prevent warning: unused function
// 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;
}
// Semaphores
#include <semaphore.h>
typedef struct plat_sem {
sem_t sem;
} plat_sem;
static b32 plat_sem_init(plat_sem *s, u32 initial) {
return sem_init(&s->sem, 0, initial) == 0;
}
static void plat_sem_wait(plat_sem *s) {
while (sem_wait(&s->sem) == -1 && errno == EINTR) {
}
}
// static b32 plat_sem_trywait(sem_t *sem) { return sem_trywait(sem) == 0; } // Comment to prevent warning: unused function
static void plat_sem_post(plat_sem *s, u32 count) {
for (u32 i = 0; i < count; i++) {
sem_post(&s->sem);
}
}
// static void plat_sem_destroy(plat_sem *s) { sem_destroy(&s->sem); } // Comment to prevent warning: unused function
// Sleep
static void sleep_ms(int ms) { usleep(ms * 1000); }
#endif