You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
3.1 KiB
155 lines
3.1 KiB
|
|
#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); |
|
|
|
#define UTIL_ALLOC(count, type) (type*) utilAllocate(count, sizeof(type)) |
|
void* utilAllocate(u32 count, u32 type_size); |
|
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; |
|
} |
|
|
|
void* |
|
utilAllocate(u32 count, u32 type_size) |
|
{ |
|
void* out = std::calloc(count, type_size); |
|
assert(out != nullptr); |
|
return out; |
|
} |
|
|
|
char* |
|
utilAllocateCStr(const char* str, u32 max_len) |
|
{ |
|
u32 len = strlen(str) + 1; |
|
|
|
if (len > max_len) { |
|
printf("%s(), %s , longer than %i\n", __FUNCTION__, str, max_len); |
|
return nullptr; |
|
} |
|
|
|
char* out = (char*) std::calloc(len, sizeof(u8)); |
|
strncpy(out, str, len - 1); |
|
return out; |
|
} |
|
|
|
void |
|
utilSafeFree(void* p) |
|
{ |
|
assert(p != nullptr); |
|
free(p); |
|
} |
|
|
|
#endif
|
|
|