diff options
| author | 2015-11-29 19:03:08 +0000 | |
|---|---|---|
| committer | 2015-11-29 19:03:08 +0000 | |
| commit | fdf6d07472a9523c2c81d0e500e2027c6d42a6ba (patch) | |
| tree | 1eacfdb8a6f33b2872399c7d44cda77a40129ad5 /gb.hpp | |
| parent | Heap Allocator Fix (diff) | |
Dealloc to Free & More Hashing Functions
Diffstat (limited to '')
| -rw-r--r-- | gb.hpp | 424 |
1 files changed, 229 insertions, 195 deletions
@@ -1,4 +1,4 @@ -// gb.hpp - v0.26a - public domain C++11 helper library - no warranty implied; use at your own risk +// gb.hpp - v0.27 - public domain C++11 helper library - no warranty implied; use at your own risk // (Experimental) A C++11 helper library without STL geared towards game development /* @@ -847,7 +847,6 @@ bool is_running(const Thread& t); u32 current_id(); } // namespace thread - /// Default alignment for memory allocations #ifndef GB_DEFAULT_ALIGNMENT #define GB_DEFAULT_ALIGNMENT 8 @@ -858,8 +857,8 @@ struct Allocator { /// Allocates the specified amount of memory aligned to the specified alignment void* (*alloc)(Allocator* a, usize size, usize align); - /// Deallocates/frees an allocation made with alloc() - void (*dealloc)(Allocator* a, void* ptr); + /// Frees an allocation made with alloc() + void (*free)(Allocator* a, void* ptr); /// Returns the amount of usuable memory allocated at `ptr`. /// /// If the allocator does not support tracking of the allocation size, @@ -960,7 +959,7 @@ void swap(T (& a)[N], T (& b)[N]); } // namespace memory void* alloc(Allocator* a, usize size, usize align = GB_DEFAULT_ALIGNMENT); -void dealloc(Allocator* a, void* ptr); +void free(Allocator* a, void* ptr); s64 allocated_size(Allocator* a, const void* ptr); s64 total_allocated(Allocator* a); @@ -1210,11 +1209,10 @@ u32 adler32(const void* key, u32 num_bytes); u32 crc32(const void* key, u32 num_bytes); u64 crc64(const void* key, usize num_bytes); -// TODO(bill): Complete hashing functions -// u32 fnv32(const void* key, usize num_bytes); -// u64 fnv64(const void* key, usize num_bytes); -// u32 fnv32a(const void* key, usize num_bytes); -// u64 fnv64a(const void* key, usize num_bytes); +u32 fnv32(const void* key, usize num_bytes); +u64 fnv64(const void* key, usize num_bytes); +u32 fnv32a(const void* key, usize num_bytes); +u64 fnv64a(const void* key, usize num_bytes); u32 murmur32(const void* key, u32 num_bytes, u32 seed = 0x9747b28c); u64 murmur64(const void* key, usize num_bytes, u64 seed = 0x9747b28c); @@ -1411,7 +1409,7 @@ inline Array<T>::~Array() { if (allocator && capacity > 0) - dealloc(allocator, data); + free(allocator, data); } @@ -1435,7 +1433,7 @@ Array<T>::operator=(Array<T>&& other) if (this != &other) { if (allocator && capacity > 0) - dealloc(allocator, data); + free(allocator, data); allocator = other.allocator; count = other.count; @@ -1497,7 +1495,7 @@ inline void free(Array<T>* a) { if (a->allocator) - dealloc(a->allocator, a->data); + free(a->allocator, a->data); a->count = 0; a->capacity = 0; a->data = nullptr; @@ -1581,7 +1579,7 @@ set_capacity(Array<T>* a, usize capacity) data = alloc_array<T>(a->allocator, capacity); memory::copy_array(a->data, a->count, data); } - dealloc(a->allocator, a->data); + free(a->allocator, a->data); a->data = data; a->capacity = capacity; } @@ -2658,7 +2656,7 @@ alloc(Allocator* a, usize size, usize align) } internal_linkage void -dealloc(Allocator* a, void* ptr) +free(Allocator* a, void* ptr) { if (!ptr) return; @@ -2702,7 +2700,7 @@ allocated_size(Allocator* a, const void* ptr) return static_cast<usize>(malloc_size(ptr)); #elif defined(GB_SYSTEM_LINUX) - return static_cast<usize>(malloc_usable_size(const_cast<void*>(ptr))); + return static_cast<usize>(malloc_usable_size(ptr)); #else #error Implement heap_allocator::allocated_size @@ -2739,7 +2737,7 @@ make(bool use_mutex) #endif heap.alloc = functions::alloc; - heap.dealloc = functions::dealloc; + heap.free = functions::free; heap.allocated_size = functions::allocated_size; heap.total_allocated = functions::total_allocated; @@ -2781,7 +2779,7 @@ alloc(Allocator* a, usize size, usize align) } inline void -dealloc(Allocator* a, void*) {} +free(Allocator* a, void*) {} inline s64 allocated_size(Allocator*, const void*) { return -1; } @@ -2806,7 +2804,7 @@ make(Allocator* backing, usize size) arena.physical_start = alloc(arena.backing, size); arena.alloc = functions::alloc; - arena.dealloc = functions::dealloc; + arena.free = functions::free; arena.allocated_size = functions::allocated_size; arena.total_allocated = functions::total_allocated; @@ -2825,7 +2823,7 @@ make(void* start, usize size) arena.total_allocated_count = 0; arena.alloc = functions::alloc; - arena.dealloc = functions::dealloc; + arena.free = functions::free; arena.allocated_size = functions::allocated_size; arena.total_allocated = functions::total_allocated; @@ -2836,7 +2834,7 @@ void destroy(Arena_Allocator* arena) { if (arena->backing) - dealloc(arena->backing, arena->physical_start); + free(arena->backing, arena->physical_start); GB_ASSERT(arena->temp_count == 0, "%ld Temporary_Arena_Memory have not be cleared", arena->temp_count); @@ -2963,11 +2961,11 @@ alloc(Allocator* a, usize size, usize align) } inline void -dealloc(Allocator* a, void* ptr) +free(Allocator* a, void* ptr) { GB_ASSERT(a != nullptr); if (ptr) - a->dealloc(a, ptr); + a->free(a, ptr); } inline s64 @@ -3032,7 +3030,7 @@ free(String str) string::Header* h = string::header(str); if (h->allocator) - dealloc(h->allocator, h); + free(h->allocator, h); } inline String @@ -3130,7 +3128,7 @@ string_realloc(Allocator* a, void* ptr, usize old_size, usize new_size) memory::copy(ptr, old_size, new_ptr); - dealloc(a, ptr); + free(a, ptr); return new_ptr; } @@ -3609,25 +3607,61 @@ crc64(const void* key, usize num_bytes) return ~result; } -// u32 fnv32(const void* key, usize num_bytes) -// { +inline u32 +fnv32(const void* key, usize num_bytes) +{ + u32 h = 0x811c9dc5; + const u8* buffer = static_cast<const u8*>(key); -// } + for (usize i = 0; i < num_bytes; i++) + { + h = (h * 0x01000193) ^ buffer[i]; + } -// u64 fnv64(const void* key, usize num_bytes) -// { + return h; +} -// } +inline u64 +fnv64(const void* key, usize num_bytes) +{ + u64 h = 0xcbf29ce484222325ull; + const u8* buffer = static_cast<const u8*>(key); -// u32 fnv32a(const void* key, usize num_bytes) -// { + for (usize i = 0; i < num_bytes; i++) + { + h = (h * 0x100000001B3ll) ^ buffer[i]; + } -// } + return h; +} -// u64 fnv64a(const void* key, usize num_bytes) -// { +inline u32 +fnv32a(const void* key, usize num_bytes) +{ + u32 h = 0x811c9dc5; + const u8* buffer = static_cast<const u8*>(key); -// } + for (usize i = 0; i < num_bytes; i++) + { + h = (h ^ buffer[i]) * 0x01000193; + } + + return h; +} + +inline u64 +fnv64a(const void* key, usize num_bytes) +{ + u64 h = 0xcbf29ce484222325ull; + const u8* buffer = static_cast<const u8*>(key); + + for (usize i = 0; i < num_bytes; i++) + { + h = (h ^ buffer[i]) * 0x100000001B3ll; + } + + return h; +} u32 murmur32(const void* key, u32 num_bytes, u32 seed) @@ -3681,116 +3715,116 @@ murmur32(const void* key, u32 num_bytes, u32 seed) } #if defined(GB_ARCH_64_BIT) -u64 -murmur64(const void* key, usize num_bytes, u64 seed) -{ - local_persist const u64 m = 0xc6a4a7935bd1e995ULL; - local_persist const s32 r = 47; + u64 + murmur64(const void* key, usize num_bytes, u64 seed) + { + local_persist const u64 m = 0xc6a4a7935bd1e995ULL; + local_persist const s32 r = 47; - u64 h = seed ^ (num_bytes * m); + u64 h = seed ^ (num_bytes * m); - const u64* data = static_cast<const u64*>(key); - const u64* end = data + (num_bytes / 8); + const u64* data = static_cast<const u64*>(key); + const u64* end = data + (num_bytes / 8); - while (data != end) - { - u64 k = *data++; + while (data != end) + { + u64 k = *data++; - k *= m; - k ^= k >> r; - k *= m; + k *= m; + k ^= k >> r; + k *= m; - h ^= k; - h *= m; - } + h ^= k; + h *= m; + } - const u8* data2 = reinterpret_cast<const u8*>(data); + const u8* data2 = reinterpret_cast<const u8*>(data); - switch (num_bytes & 7) - { - case 7: h ^= static_cast<u64>(data2[6]) << 48; - case 6: h ^= static_cast<u64>(data2[5]) << 40; - case 5: h ^= static_cast<u64>(data2[4]) << 32; - case 4: h ^= static_cast<u64>(data2[3]) << 24; - case 3: h ^= static_cast<u64>(data2[2]) << 16; - case 2: h ^= static_cast<u64>(data2[1]) << 8; - case 1: h ^= static_cast<u64>(data2[0]); + switch (num_bytes & 7) + { + case 7: h ^= static_cast<u64>(data2[6]) << 48; + case 6: h ^= static_cast<u64>(data2[5]) << 40; + case 5: h ^= static_cast<u64>(data2[4]) << 32; + case 4: h ^= static_cast<u64>(data2[3]) << 24; + case 3: h ^= static_cast<u64>(data2[2]) << 16; + case 2: h ^= static_cast<u64>(data2[1]) << 8; + case 1: h ^= static_cast<u64>(data2[0]); + h *= m; + }; + + h ^= h >> r; h *= m; - }; + h ^= h >> r; - h ^= h >> r; - h *= m; - h ^= h >> r; - - return h; -} + return h; + } #elif GB_ARCH_32_BIT -u64 -murmur64(const void* key, usize num_bytes, u64 seed) -{ - local_persist const u32 m = 0x5bd1e995; - local_persist const s32 r = 24; + u64 + murmur64(const void* key, usize num_bytes, u64 seed) + { + local_persist const u32 m = 0x5bd1e995; + local_persist const s32 r = 24; - u32 h1 = static_cast<u32>(seed) ^ static_cast<u32>(num_bytes); - u32 h2 = static_cast<u32>(seed >> 32); + u32 h1 = static_cast<u32>(seed) ^ static_cast<u32>(num_bytes); + u32 h2 = static_cast<u32>(seed >> 32); - const u32* data = static_cast<const u32*>(key); + const u32* data = static_cast<const u32*>(key); - while (num_bytes >= 8) - { - u32 k1 = *data++; - k1 *= m; - k1 ^= k1 >> r; - k1 *= m; - h1 *= m; - h1 ^= k1; - num_bytes -= 4; + while (num_bytes >= 8) + { + u32 k1 = *data++; + k1 *= m; + k1 ^= k1 >> r; + k1 *= m; + h1 *= m; + h1 ^= k1; + num_bytes -= 4; + + u32 k2 = *data++; + k2 *= m; + k2 ^= k2 >> r; + k2 *= m; + h2 *= m; + h2 ^= k2; + num_bytes -= 4; + } - u32 k2 = *data++; - k2 *= m; - k2 ^= k2 >> r; - k2 *= m; - h2 *= m; - h2 ^= k2; - num_bytes -= 4; - } + if (num_bytes >= 4) + { + u32 k1 = *data++; + k1 *= m; + k1 ^= k1 >> r; + k1 *= m; + h1 *= m; + h1 ^= k1; + num_bytes -= 4; + } - if (num_bytes >= 4) - { - u32 k1 = *data++; - k1 *= m; - k1 ^= k1 >> r; - k1 *= m; - h1 *= m; - h1 ^= k1; - num_bytes -= 4; - } + switch (num_bytes) + { + case 3: h2 ^= reinterpret_cast<const u8*>(data)[2] << 16; + case 2: h2 ^= reinterpret_cast<const u8*>(data)[1] << 8; + case 1: h2 ^= reinterpret_cast<const u8*>(data)[0] << 0; + h2 *= m; + }; - switch (num_bytes) - { - case 3: h2 ^= reinterpret_cast<const u8*>(data)[2] << 16; - case 2: h2 ^= reinterpret_cast<const u8*>(data)[1] << 8; - case 1: h2 ^= reinterpret_cast<const u8*>(data)[0] << 0; + h1 ^= h2 >> 18; + h1 *= m; + h2 ^= h1 >> 22; + h2 *= m; + h1 ^= h2 >> 17; + h1 *= m; + h2 ^= h1 >> 19; h2 *= m; - }; - - h1 ^= h2 >> 18; - h1 *= m; - h2 ^= h1 >> 22; - h2 *= m; - h1 ^= h2 >> 17; - h1 *= m; - h2 ^= h1 >> 19; - h2 *= m; - u64 h = h1; + u64 h = h1; - h = (h << 32) | h2; + h = (h << 32) | h2; - return h; -} + return h; + } #else -#error murmur64 function not supported on this architecture + #error murmur64 function not supported on this architecture #endif } // namespace hash @@ -3805,97 +3839,97 @@ const Time TIME_ZERO = time::seconds(0); namespace time { #if defined(GB_SYSTEM_WINDOWS) + internal_linkage LARGE_INTEGER + win32_get_frequency() + { + LARGE_INTEGER f; + QueryPerformanceFrequency(&f); + return f; + } -internal_linkage LARGE_INTEGER -win32_get_frequency() -{ - LARGE_INTEGER f; - QueryPerformanceFrequency(&f); - return f; -} - -Time -now() -{ - // NOTE(bill): std::chrono does not have a good enough precision in MSVC12 - // and below. This may have been fixed in MSVC14 but unsure as of yet. + Time + now() + { + // NOTE(bill): std::chrono does not have a good enough precision in MSVC12 + // and below. This may have been fixed in MSVC14 but unsure as of yet. - // Force the following code to run on first core - // NOTE(bill): See - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx - HANDLE currentThread = GetCurrentThread(); - DWORD_PTR previousMask = SetThreadAffinityMask(currentThread, 1); + // Force the following code to run on first core + // NOTE(bill): See + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx + HANDLE currentThread = GetCurrentThread(); + DWORD_PTR previousMask = SetThreadAffinityMask(currentThread, 1); - // Get the frequency of the performance counter - // It is constant across the program's lifetime - local_persist LARGE_INTEGER s_frequency = win32_get_frequency(); + // Get the frequency of the performance counter + // It is constant across the program's lifetime + local_persist LARGE_INTEGER s_frequency = win32_get_frequency(); - // Get the current time - LARGE_INTEGER t; - QueryPerformanceCounter(&t); + // Get the current time + LARGE_INTEGER t; + QueryPerformanceCounter(&t); - // Restore the thread affinity - SetThreadAffinityMask(currentThread, previousMask); + // Restore the thread affinity + SetThreadAffinityMask(currentThread, previousMask); - return time::microseconds(1000000ll * t.QuadPart / s_frequency.QuadPart); -} + return time::microseconds(1000000ll * t.QuadPart / s_frequency.QuadPart); + } -void -sleep(Time t) -{ - if (t.microseconds <= 0) - return; + void + sleep(Time t) + { + if (t.microseconds <= 0) + return; - // Get the supported timer resolutions on this system - TIMECAPS tc; - timeGetDevCaps(&tc, sizeof(TIMECAPS)); - // Set the timer resolution to the minimum for the Sleep call - timeBeginPeriod(tc.wPeriodMin); + // Get the supported timer resolutions on this system + TIMECAPS tc; + timeGetDevCaps(&tc, sizeof(TIMECAPS)); + // Set the timer resolution to the minimum for the Sleep call + timeBeginPeriod(tc.wPeriodMin); - // Wait... - ::Sleep(time::as_milliseconds(t)); + // Wait... + ::Sleep(time::as_milliseconds(t)); - // Reset the timer resolution back to the system default - timeBeginPeriod(tc.wPeriodMin); -} + // Reset the timer resolution back to the system default + timeBeginPeriod(tc.wPeriodMin); + } #else -Time -now() -{ -#if defined(GB_SYSTEM_OSX) - s64 t = static_cast<s64>(mach_absolute_time()); - return microseconds(t); -#else - struct timeval t; - gettimeofday(&t, nullptr); + Time + now() + { + #if defined(GB_SYSTEM_OSX) + s64 t = static_cast<s64>(mach_absolute_time()); + return microseconds(t); + #else + struct timeval t; + gettimeofday(&t, nullptr); - return microseconds((t.tv_sec * 1000000ll) + (t.tv_usec * 1ll)); -#endif -} + return microseconds((t.tv_sec * 1000000ll) + (t.tv_usec * 1ll)); + #endif + } -void -sleep(Time t) -{ - if (t.microseconds <= 0) - return; + void + sleep(Time t) + { + if (t.microseconds <= 0) + return; - struct timespec spec = {}; - spec.tv_sec = static_cast<s64>(as_seconds(t)); - spec.tv_nsec = 1000ll * (as_microseconds(t) % 1000000ll); + struct timespec spec = {}; + spec.tv_sec = static_cast<s64>(as_seconds(t)); + spec.tv_nsec = 1000ll * (as_microseconds(t) % 1000000ll); - nanosleep(&spec, nullptr); -} + nanosleep(&spec, nullptr); + } #endif Time seconds(f32 s) { return {static_cast<s64>(s * 1000000ll)}; } Time milliseconds(s32 ms) { return {static_cast<s64>(ms * 1000l)}; } Time microseconds(s64 us) { return {us}; } -f32 as_seconds(Time t) { return static_cast<f32>(t.microseconds / 1000000.0f); } -s32 as_milliseconds(Time t) { return static_cast<s32>(t.microseconds / 1000l); } -s64 as_microseconds(Time t) { return t.microseconds; } +f32 as_seconds(Time t) { return static_cast<f32>(t.microseconds / 1000000.0f); } +s32 as_milliseconds(Time t) { return static_cast<s32>(t.microseconds / 1000l); } +s64 as_microseconds(Time t) { return t.microseconds; } } // namespace time + bool operator==(Time left, Time right) { return left.microseconds == right.microseconds; } bool operator!=(Time left, Time right) { return !operator==(left, right); } @@ -3929,7 +3963,6 @@ f32 operator/(Time left, Time right) { return time::as_seconds(left) / time::as_ Time& operator/=(Time& left, f32 right) { return (left = left / right); } Time& operator/=(Time& left, s64 right) { return (left = left / right); } - Time operator%(Time left, Time right) { return time::microseconds(time::as_microseconds(left) % time::as_microseconds(right)); } Time& operator%=(Time& left, Time right) { return (left = left % right); } @@ -4131,6 +4164,7 @@ __GB_NAMESPACE_END /* Version History: + 0.27 - Dealloc to Free & More Hashing Functions 0.26a - Heap_Allocator Fix 0.26 - Better Allocation system 0.25a - Array bug fix |
