Specify ZeroMem on allocations, rewrite rect intersect, configurable asserts

This commit is contained in:
doyle 2020-06-02 22:48:20 +10:00
parent 419a505ea9
commit 0c55abd4c3

View File

@ -316,36 +316,30 @@ STBSP__PUBLICDEF void STB_SPRINTF_DECORATE(set_separators)(char comma, char peri
#define DQN_DEBUG_BREAK raise(SIGTRAP) #define DQN_DEBUG_BREAK raise(SIGTRAP)
#endif #endif
#define DQN_INVALID_CODE_PATH 0 #ifndef DQN_ASSERT_MSG
#if defined(DQN_ENABLE_ASSERTS)
#define DQN_ASSERT(expr) DQN_ASSERT_MSG(expr, "")
#define DQN_ASSERT_MSG(expr, fmt, ...) \ #define DQN_ASSERT_MSG(expr, fmt, ...) \
if (!(expr)) \ if (!(expr)) \
{ \ { \
DQN_LOG_E("Assert: [" #expr "] " fmt, ##__VA_ARGS__); \ DQN_LOG_E("Assert: [" #expr "] " fmt, ##__VA_ARGS__); \
DQN_DEBUG_BREAK; \ DQN_DEBUG_BREAK; \
} }
#define DQN_ASSERT_IF(expr) DQN_ASSERT_MSG_IF(expr, "")
#define DQN_ASSERT_MSG_IF(expr, fmt, ...) \
DQN_ASSERT_MSG(!(expr), fmt, ## __VA_ARGS__); \
if (0)
#else
#define DQN_ASSERT(expr)
#define DQN_ASSERT_MSG(expr, fmt, ...)
#define DQN_ASSERT_IF(expr) DQN_ASSERT_MSG_IF(expr, "")
#define DQN_ASSERT_MSG_IF(expr, fmt, ...) \
if (expr && DQN_LOG_E("Assert if failure: [!" #expr "] " fmt, ## __VA_ARGS__))
#endif #endif
#define DQN_SECONDS_TO_MS(val) ((val) * 1000.0f) #define DQN_ASSERT(expr) DQN_ASSERT_MSG(expr, "")
#define DQN_ASSERT_IF(expr) DQN_ASSERT_MSG_IF(expr, "")
#define DQN_ASSERT_MSG_IF(expr, fmt, ...) \
DQN_ASSERT_MSG(!(expr), fmt, ## __VA_ARGS__); \
if (0)
#define DQN_INVALID_CODE_PATH 0
#define DQN_SECONDS_TO_MS(val) ((val) * 1000.0f)
#define DQN_MATH_PI 3.14159265359f #define DQN_MATH_PI 3.14159265359f
#define DQN_DEGREE_TO_RADIAN(val) (val) * (DQN_MATH_PI / 180.0f) #define DQN_DEGREE_TO_RADIAN(val) (val) * (DQN_MATH_PI / 180.0f)
#define DQN_FILE_SCOPE static #define DQN_FILE_SCOPE static
#define DQN_LOCAL_PERSIST static #define DQN_LOCAL_PERSIST static
using Dqn_uintptr = uintptr_t;
using Dqn_usize = size_t; using Dqn_usize = size_t;
using Dqn_isize = ptrdiff_t; using Dqn_isize = ptrdiff_t;
@ -372,6 +366,7 @@ const Dqn_f32 DQN_F32_MAX = FLT_MAX;
const Dqn_isize DQN_ISIZE_MAX = PTRDIFF_MAX; const Dqn_isize DQN_ISIZE_MAX = PTRDIFF_MAX;
const Dqn_usize DQN_USIZE_MAX = SIZE_MAX; const Dqn_usize DQN_USIZE_MAX = SIZE_MAX;
template <typename T, Dqn_isize N> template <typename T, Dqn_isize N>
DQN_HEADER_COPY_PROTOTYPE(constexpr Dqn_usize, Dqn_ArrayCount(T const (&)[N])) { return N; } DQN_HEADER_COPY_PROTOTYPE(constexpr Dqn_usize, Dqn_ArrayCount(T const (&)[N])) { return N; }
@ -400,7 +395,7 @@ struct DqnDeferHelper
#define DQN_TOKEN_COMBINE2(x, y) x ## y #define DQN_TOKEN_COMBINE2(x, y) x ## y
#define DQN_TOKEN_COMBINE(x, y) DQN_TOKEN_COMBINE2(x, y) #define DQN_TOKEN_COMBINE(x, y) DQN_TOKEN_COMBINE2(x, y)
#define DQN_UNIQUE_NAME(prefix) DQN_TOKEN_COMBINE(prefix, __COUNTER__) #define DQN_UNIQUE_NAME(prefix) DQN_TOKEN_COMBINE(prefix, __LINE__)
#define DQN_DEFER const auto DQN_UNIQUE_NAME(defer_lambda_) = DqnDeferHelper() + [&]() #define DQN_DEFER const auto DQN_UNIQUE_NAME(defer_lambda_) = DqnDeferHelper() + [&]()
enum struct Dqn_ZeroMem { No, Yes }; enum struct Dqn_ZeroMem { No, Yes };
@ -774,7 +769,7 @@ struct Dqn_ArenaAllocatorScopedRegion
void * Dqn_ArenaAllocator_Allocate(Dqn_ArenaAllocator *arena, Dqn_isize size, Dqn_u8 alignment, Dqn_ZeroMem zero_mem); void * Dqn_ArenaAllocator_Allocate(Dqn_ArenaAllocator *arena, Dqn_isize size, Dqn_u8 alignment, Dqn_ZeroMem zero_mem);
Dqn_b32 Dqn_ArenaAllocator_Reserve(Dqn_ArenaAllocator *arena, Dqn_isize size); Dqn_b32 Dqn_ArenaAllocator_Reserve(Dqn_ArenaAllocator *arena, Dqn_isize size);
DQN_HEADER_COPY_PROTOTYPE(template <typename T> T *, Dqn_ArenaAllocator_AllocateType(Dqn_ArenaAllocator *arena, Dqn_isize num, Dqn_ZeroMem zero_mem = Dqn_ZeroMem::Yes)) DQN_HEADER_COPY_PROTOTYPE(template <typename T> T *, Dqn_ArenaAllocator_AllocateType(Dqn_ArenaAllocator *arena, Dqn_isize num = 1, Dqn_ZeroMem zero_mem = Dqn_ZeroMem::Yes))
{ {
auto *result = DQN_CAST(T *)Dqn_ArenaAllocator_Allocate(arena, sizeof(T) * num, alignof(T), zero_mem); auto *result = DQN_CAST(T *)Dqn_ArenaAllocator_Allocate(arena, sizeof(T) * num, alignof(T), zero_mem);
return result; return result;
@ -865,7 +860,7 @@ template <Dqn_isize N> DQN_FILE_SCOPE char *Dqn_StringBuilder_AllocateWriteBuffe
if (!block) return nullptr; if (!block) return nullptr;
*block = {}; *block = {};
block->mem = DQN_CAST(char *)Dqn_Allocator_Allocate(&builder->allocator, allocation_size, alignof(char)); block->mem = DQN_CAST(char *)Dqn_Allocator_Allocate(&builder->allocator, allocation_size, alignof(char), Dqn_ZeroMem::No);
block->size = allocation_size; block->size = allocation_size;
builder->last_mem_block->next = block; builder->last_mem_block->next = block;
builder->last_mem_block = builder->last_mem_block->next; builder->last_mem_block = builder->last_mem_block->next;
@ -917,7 +912,7 @@ DQN_HEADER_COPY_PROTOTYPE(template <Dqn_isize N> char *, Dqn_StringBuilder_Build
Dqn_isize len_ = 0; Dqn_isize len_ = 0;
if (!len) len = &len_; if (!len) len = &len_;
*len = Dqn_StringBuilder_BuildLength(builder); *len = Dqn_StringBuilder_BuildLength(builder);
auto *result = DQN_CAST(char *)Dqn_Allocator_Allocate(allocator, *len + 1, alignof(char)); auto *result = DQN_CAST(char *)Dqn_Allocator_Allocate(allocator, *len + 1, alignof(char), Dqn_ZeroMem::No);
Dqn_StringBuilder_BuildToDest(builder, result, *len + 1); Dqn_StringBuilder_BuildToDest(builder, result, *len + 1);
return result; return result;
} }
@ -1560,6 +1555,42 @@ DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Log(Dqn_LogType type, char const *file, D
return true; return true;
} }
// @ -------------------------------------------------------------------------------------------------
// @
// @ NOTE: Dqn_Align*
// @
// @ -------------------------------------------------------------------------------------------------
DQN_HEADER_COPY_PROTOTYPE(Dqn_uintptr, Dqn_AlignAddress(Dqn_uintptr address, Dqn_u8 alignment))
{
Dqn_uintptr result = address;
if (alignment > 0)
{
Dqn_uintptr remainder = result % alignment;
if (remainder > 0)
{
Dqn_uintptr offset_to_align = alignment - remainder;
result += offset_to_align;
}
}
return result;
}
// @ NOTE: Even if pointer is aligned, align it again, ensuring there's at minimum
// @ 1 byte and at most alignment bytes of space between the aligned pointer and
// @ raw pointer. We do this to keep metadata exactly 1 byte behind the aligned
// @ pointer.
DQN_HEADER_COPY_PROTOTYPE(Dqn_uintptr, Dqn_AlignAddressEnsuringSpace(Dqn_uintptr address, Dqn_u8 alignment))
{
Dqn_uintptr remainder = address % alignment;
Dqn_uintptr offset_to_align = alignment - remainder;
Dqn_uintptr result = address + offset_to_align;
DQN_ASSERT(result % alignment == 0);
DQN_ASSERT(result >= address);
DQN_ASSERT(offset_to_align >= 1 && offset_to_align <= alignment);
return result;
}
// @ ------------------------------------------------------------------------------------------------- // @ -------------------------------------------------------------------------------------------------
// @ // @
// @ NOTE: Dqn_AllocateMetadata // @ NOTE: Dqn_AllocateMetadata
@ -1816,7 +1847,7 @@ DQN_FILE_SCOPE void Dqn_ArenaAllocator__AttachBlock(Dqn_ArenaAllocator *arena, D
DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_ArenaAllocator_Allocate(Dqn_ArenaAllocator *arena, Dqn_isize size, Dqn_u8 alignment, Dqn_ZeroMem zero_mem = Dqn_ZeroMem::Yes)) DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_ArenaAllocator_Allocate(Dqn_ArenaAllocator *arena, Dqn_isize size, Dqn_u8 alignment, Dqn_ZeroMem zero_mem = Dqn_ZeroMem::Yes))
{ {
Dqn_isize allocation_size = Dqn_AllocateMetadata_SizeRequired(size, alignment); Dqn_isize allocation_size = size + (alignment - 1);
Dqn_b32 need_new_mem_block = true; Dqn_b32 need_new_mem_block = true;
for (Dqn_ArenaAllocatorBlock *mem_block = arena->curr_mem_block; mem_block; mem_block = mem_block->next) for (Dqn_ArenaAllocatorBlock *mem_block = arena->curr_mem_block; mem_block; mem_block = mem_block->next)
{ {
@ -1837,13 +1868,12 @@ DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_ArenaAllocator_Allocate(Dqn_ArenaAllocator
arena->curr_mem_block = arena->top_mem_block; arena->curr_mem_block = arena->top_mem_block;
} }
char *ptr = DQN_CAST(char *) arena->curr_mem_block->memory + arena->curr_mem_block->used; Dqn_uintptr address = DQN_CAST(Dqn_uintptr) arena->curr_mem_block->memory + arena->curr_mem_block->used;
char *result = Dqn_AllocateMetadata_Init(ptr, alignment); void *result = DQN_CAST(void *) Dqn_AlignAddress(address, alignment);
arena->curr_mem_block->used += allocation_size; arena->curr_mem_block->used += allocation_size;
DQN_ASSERT(arena->curr_mem_block->used <= arena->curr_mem_block->size); DQN_ASSERT(arena->curr_mem_block->used <= arena->curr_mem_block->size);
if (zero_mem == Dqn_ZeroMem::Yes) DQN_MEMSET(DQN_CAST(void *)address, 0, allocation_size);
if (zero_mem == Dqn_ZeroMem::Yes) DQN_MEMSET(result, 0, size);
return result; return result;
} }
@ -2106,24 +2136,24 @@ DQN_HEADER_COPY_PROTOTYPE(Dqn_Rect, Dqn_Rect_Move(Dqn_Rect src, Dqn_V2 move_amou
return result; return result;
} }
DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Rect_Intersects(Dqn_Rect a, Dqn_Rect b))
{
Dqn_b32 result = (a.min.x <= b.max.x && a.max.x >= b.min.x) &&
(a.min.y <= b.max.y && a.max.y >= b.min.y);
return result;
}
DQN_HEADER_COPY_PROTOTYPE(Dqn_Rect, Dqn_Rect_Intersection(Dqn_Rect a, Dqn_Rect b)) DQN_HEADER_COPY_PROTOTYPE(Dqn_Rect, Dqn_Rect_Intersection(Dqn_Rect a, Dqn_Rect b))
{ {
Dqn_Rect result = {}; Dqn_Rect result = {};
if (a.min.x >= b.min.x && a.min.x <= b.max.x) result.min.x = a.min.x; if (Dqn_Rect_Intersects(a, b))
else if (b.min.x >= a.min.x && b.min.x <= a.max.x) result.min.x = b.min.x;
else
{ {
return result; result.min.x = DQN_MAX(a.min.x, b.min.x);
result.min.y = DQN_MAX(a.min.y, b.min.y);
result.max.x = DQN_MIN(a.max.x, b.max.x);
result.max.y = DQN_MIN(a.max.y, b.max.y);
} }
if (a.max.x >= b.min.x && a.max.x <= b.max.x) result.max.x = a.max.x;
else if (b.max.x >= a.min.x && b.max.x <= a.max.x) result.max.x = b.max.x;
if (a.min.y >= b.min.y && a.min.y <= b.max.y) result.min.y = a.min.y;
else if (b.min.y >= a.min.y && b.min.y <= a.max.y) result.min.y = b.min.y;
if (a.max.y >= b.min.y && a.max.y <= b.max.y) result.max.y = a.max.y;
else if (b.max.y >= a.min.y && b.max.y <= a.max.y) result.max.y = b.max.y;
return result; return result;
} }