|
|
|
|
@ -1,16 +1,126 @@
|
|
|
|
|
|
|
|
|
|
#ifndef UTIL_H |
|
|
|
|
#define UTIL_H |
|
|
|
|
|
|
|
|
|
#include <cassert> |
|
|
|
|
#include <cstring> |
|
|
|
|
|
|
|
|
|
#include "types.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------
|
|
|
|
|
// Hashing
|
|
|
|
|
|
|
|
|
|
// NOTE: FNV1a hashing algorithm http://www.isthe.com/chongo/tech/comp/fnv/
|
|
|
|
|
#define FNV1_64_INIT ((u64) 0xcbf29ce484222325ULL) |
|
|
|
|
#define FNV_64_PRIME ((u64) 0x100000001b3ULL) |
|
|
|
|
u64 |
|
|
|
|
utilFNV64a_str(const char *str, u64 hval = FNV1_64_INIT); |
|
|
|
|
|
|
|
|
|
//-----------------
|
|
|
|
|
// Memory allocation
|
|
|
|
|
|
|
|
|
|
struct memory_arena |
|
|
|
|
{ |
|
|
|
|
size_t max_size; |
|
|
|
|
void* head; |
|
|
|
|
void* next_free; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#define DEFAULT_ARENA_SIZE 10 * 1024 * 1024 // 10MB
|
|
|
|
|
memory_arena* arenaInit(size_t initial_size = DEFAULT_ARENA_SIZE); |
|
|
|
|
|
|
|
|
|
void arenaFree(memory_arena*& arena); |
|
|
|
|
uint arenaGetFreeSize(memory_arena* arena); |
|
|
|
|
|
|
|
|
|
#define ARENA_ALLOC(arena, type, count) \ |
|
|
|
|
(type*) arenaAllocateBlock(arena, sizeof(type) * count) |
|
|
|
|
void* arenaAllocateBlock(memory_arena* arena, size_t block_size); |
|
|
|
|
|
|
|
|
|
#define MAX_NAME_LENGTH 256 |
|
|
|
|
char* arenaCopyCStr(memory_arena* arena, |
|
|
|
|
const char* input, |
|
|
|
|
u32 max_len = MAX_NAME_LENGTH); |
|
|
|
|
|
|
|
|
|
char* utilAllocateCStr(const char* str, u32 max_len = 256); |
|
|
|
|
void utilSafeFree(void* p); |
|
|
|
|
|
|
|
|
|
#endif // UTIL_H
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef UTIL_IMPLEMENTATION |
|
|
|
|
|
|
|
|
|
//-----------------
|
|
|
|
|
// Hashing
|
|
|
|
|
|
|
|
|
|
uint64_t |
|
|
|
|
utilFNV64a_str(const char* str, uint64_t hval) |
|
|
|
|
{ |
|
|
|
|
unsigned char* s = (unsigned char *)str; // unsigned string
|
|
|
|
|
|
|
|
|
|
// FNV-1a hash each octet of the string
|
|
|
|
|
while (*s) { |
|
|
|
|
// xor the bottom with the current octet
|
|
|
|
|
hval ^= (uint64_t)*s++; |
|
|
|
|
// multiply by the 64 bit FNV magic prime mod 2^64
|
|
|
|
|
hval *= FNV_64_PRIME; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return hval; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//-----------------
|
|
|
|
|
// Memory allocation
|
|
|
|
|
|
|
|
|
|
memory_arena* |
|
|
|
|
arenaInit(size_t initial_size) |
|
|
|
|
{ |
|
|
|
|
uint sz = sizeof(memory_arena); |
|
|
|
|
memory_arena* arena = |
|
|
|
|
(memory_arena*) std::calloc(initial_size + sz, sizeof(u8)); |
|
|
|
|
arena->head = arena->next_free = (uint8_t*) arena + sz; |
|
|
|
|
arena->max_size = initial_size; |
|
|
|
|
return arena; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
arenaFree(memory_arena*& arena) |
|
|
|
|
{ |
|
|
|
|
if (arena != nullptr) { |
|
|
|
|
std::free(arena); |
|
|
|
|
arena = nullptr; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint |
|
|
|
|
arenaGetFreeSize(memory_arena* arena) |
|
|
|
|
{ |
|
|
|
|
return (uint8_t*) arena->head |
|
|
|
|
+ arena->max_size |
|
|
|
|
- (uint8_t*) arena->next_free; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void* |
|
|
|
|
arenaAllocateBlock(memory_arena* arena, size_t block_size) |
|
|
|
|
{ |
|
|
|
|
// TODO: resizable memory arena
|
|
|
|
|
assert(arenaGetFreeSize(arena) >= block_size); |
|
|
|
|
assert(block_size > 0); |
|
|
|
|
void* ret = arena->next_free; |
|
|
|
|
arena->next_free = (uint8_t*) arena->next_free + block_size; |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char* |
|
|
|
|
arenaCopyCStr(memory_arena* arena, const char* input, u32 max_len) |
|
|
|
|
{ |
|
|
|
|
u32 name_len = std::strlen(input) + 1; |
|
|
|
|
assert(name_len < max_len); |
|
|
|
|
char* out = ARENA_ALLOC(arena, char, name_len); |
|
|
|
|
std::strncpy(out, input, name_len); |
|
|
|
|
return out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char* |
|
|
|
|
utilAllocateCStr(const char* str, u32 max_len) |
|
|
|
|
{ |
|
|
|
|
|