From fcda88e1cda5d9c88b4d5ec2322f74ca71c73f5c Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Fri, 13 Aug 2021 10:03:28 -0700 Subject: [PATCH] reduce arena overrides; tidy up organization of default control macros; eliminate arena casts by directly relying on MD_IMPL_Arena in header --- samples/c_code_generation.c | 2 +- samples/node_errors/node_errors.c | 2 +- samples/old_style_custom_layer.c | 2 +- samples/output_parse/output_parse.c | 2 +- samples/parse_check.c | 2 +- .../static_site_generator.c | 2 +- samples/toy_language/toy_language.c | 2 +- source/md.c | 302 ++++++++---------- source/md.h | 94 +++++- source/md_c_helpers.c | 2 +- tests/cpp_build_test.cpp | 2 +- tests/sanity_tests.c | 2 +- tests/unicode_test.c | 2 +- 13 files changed, 230 insertions(+), 188 deletions(-) diff --git a/samples/c_code_generation.c b/samples/c_code_generation.c index ca0a170..454d9c3 100644 --- a/samples/c_code_generation.c +++ b/samples/c_code_generation.c @@ -14,7 +14,7 @@ int main(int argument_count, char **arguments) MD_ThreadContext tctx; MD_ThreadInit(&tctx); - arena = MD_ArenaNew(1ull << 40); + arena = MD_ArenaAlloc(1ull << 40); MD_String8 example_code = MD_S8Lit("@struct Foo:\n" "{\n" diff --git a/samples/node_errors/node_errors.c b/samples/node_errors/node_errors.c index 7850007..c0153c2 100644 --- a/samples/node_errors/node_errors.c +++ b/samples/node_errors/node_errors.c @@ -10,7 +10,7 @@ int main(int argument_count, char **arguments) MD_ThreadContext tctx; MD_ThreadInit(&tctx); - arena = MD_ArenaNew(1ull << 40); + arena = MD_ArenaAlloc(1ull << 40); // NOTE(rjf): Parse all the files passed in via command line. MD_Node *list = MD_MakeList(arena); diff --git a/samples/old_style_custom_layer.c b/samples/old_style_custom_layer.c index c5cc2a9..94bf681 100644 --- a/samples/old_style_custom_layer.c +++ b/samples/old_style_custom_layer.c @@ -28,7 +28,7 @@ int main(int argument_count, char **arguments) MD_ThreadContext tctx; MD_ThreadInit(&tctx); - arena = MD_ArenaNew(1ull << 40); + arena = MD_ArenaAlloc(1ull << 40); // NOTE(rjf): Parse all the files passed in via command line. MD_Node *list = MD_MakeList(arena); diff --git a/samples/output_parse/output_parse.c b/samples/output_parse/output_parse.c index 5f3771d..587a266 100644 --- a/samples/output_parse/output_parse.c +++ b/samples/output_parse/output_parse.c @@ -67,7 +67,7 @@ int main(int argument_count, char **arguments) MD_ThreadContext tctx; MD_ThreadInit(&tctx); - arena = MD_ArenaNew(1ull << 40); + arena = MD_ArenaAlloc(1ull << 40); // NOTE(pmh): Parse all the files passed in via command line. MD_Node *list = MD_MakeList(arena); diff --git a/samples/parse_check.c b/samples/parse_check.c index 25e92dd..6dcd20f 100644 --- a/samples/parse_check.c +++ b/samples/parse_check.c @@ -8,7 +8,7 @@ int main(int argument_count, char **arguments) MD_ThreadContext tctx; MD_ThreadInit(&tctx); - arena = MD_ArenaNew(1ull << 40); + arena = MD_ArenaAlloc(1ull << 40); MD_Node *list = MD_MakeList(arena); for(int i = 1; i < argument_count; i += 1) diff --git a/samples/static_site_generator/static_site_generator.c b/samples/static_site_generator/static_site_generator.c index fd1f210..8893c4e 100644 --- a/samples/static_site_generator/static_site_generator.c +++ b/samples/static_site_generator/static_site_generator.c @@ -37,7 +37,7 @@ int main(int argument_count, char **arguments) MD_ThreadContext tctx; MD_ThreadInit(&tctx); - arena = MD_ArenaNew(1ull << 40); + arena = MD_ArenaAlloc(1ull << 40); //~ NOTE(rjf): Parse command line arguments. MD_String8List arg_list = MD_StringListFromArgCV(arena, argument_count, arguments); diff --git a/samples/toy_language/toy_language.c b/samples/toy_language/toy_language.c index 785468b..7e8b691 100644 --- a/samples/toy_language/toy_language.c +++ b/samples/toy_language/toy_language.c @@ -185,7 +185,7 @@ int main(int argument_count, char **arguments) MD_ThreadContext tctx; MD_ThreadInit(&tctx); - arena = MD_ArenaNew(1ull << 40); + arena = MD_ArenaAlloc(1ull << 40); //- rjf: parse command line MD_String8List arg_list = MD_StringListFromArgCV(arena, argument_count, arguments); diff --git a/source/md.c b/source/md.c index 3fd00ce..7acb786 100644 --- a/source/md.c +++ b/source/md.c @@ -1,80 +1,16 @@ // LICENSE AT END OF FILE (MIT). -/* NOTE(allen): Notes on overrides/macro options: -** -** Individual Overridables: -** #define MD_IMPL_FileIterIncrement -** #define MD_IMPL_Reserve -** #define MD_IMPL_Commit -** #define MD_IMPL_Decommit -** #define MD_IMPL_Release -** -** #define MD_IMPL_Arena -** #define MD_IMPL_ArenaNew (MD_u64) -> MD_IMPL_Arena* -** #define MD_IMPL_ArenaRelease (MD_IMPL_Arena*) -> void -** #define MD_IMPL_ArenaGetPos (MD_IMPL_Arena*) -> MD_u64 -** #define MD_IMPL_ArenaGetCap (MD_IMPL_Arena*) -> MD_u64 -** #define MD_IMPL_ArenaPush (MD_IMPL_Arena*, MD_u64) -> void* -** #define MD_IMPL_ArenaPopTo (MD_IMPL_Arena*, MD_u64) -> void -** #define MD_IMPL_ArenaPushAlign (MD_IMPL_Arena*, MD_u64) -> void -** #define MD_IMPL_ArenaSetAutoAlign (MD_IMPL_Arena*, MD_u64) -> void -** #define MD_IMPL_ArenaMinPos (MD_IMPL_Arena*) -> MD_u64 -** -** #define MD_SCRATCH_SIZE -** -** Default Implementation Controls -** ~If no controls are set, then the system automatically enables all defaults~ -** #define MD_DEFAULT_FILE_ITER -> construct "file iteration" from OS -** #define MD_DEFAULT_MEMORY -> construct "low level memory" from OS -** #define MD_DEFAULT_ARENA -> construct "arena" from "low level memory" -** -*/ - -//~ Check for controls -#if defined(MD_DEFAULT_FILE_ITER) -# define MD_INTERNAL_CONTROL_SET 1 -#endif -#if defined(MD_DEFAULT_MEMORY) -# define MD_INTERNAL_CONTROL_SET 1 -#endif -#if defined(MD_DEFAULT_ARENA) -# define MD_INTERNAL_CONTROL_SET 1 -#endif -#if !defined(MD_INTERNAL_CONTROL_SET) -# define MD_INTERNAL_CONTROL_SET 0 -#endif - -#if !MD_INTERNAL_CONTROL_SET -# define MD_DEFAULT_FILE_ITER 1 -# define MD_DEFAULT_MEMORY 1 -# define MD_DEFAULT_ARENA 1 -#endif - -//~ Set default values for controls -#if !defined(MD_DEFAULT_FILE_ITER) -# define MD_DEFAULT_FILE_ITER 0 -#endif -#if !defined(MD_DEFAULT_MEMORY) -# define MD_DEFAULT_MEMORY 0 -#endif -#if !defined(MD_DEFAULT_ARENA) -# define MD_DEFAULT_ARENA 0 -#endif -#if !defined(MD_SCRATCH_SIZE) -# define MD_SCRATCH_SIZE (1 << 30) -#endif - //~///////////////////////////////////////////////////////////////////////////// /////////////////////////// Win32 Implementation /////////////////////////////// //////////////////////////////////////////////////////////////////////////////// +//- win32 header #if (MD_DEFAULT_FILE_ITER || MD_DEFAULT_MEMORY) && MD_OS_WINDOWS - -#include -#pragma comment(lib, "User32.lib") - +# include +# pragma comment(lib, "User32.lib") #endif +//- win32 "file iteration" #if MD_DEFAULT_FILE_ITER && MD_OS_WINDOWS #if !defined(MD_IMPL_FileIterIncrement) @@ -128,6 +64,7 @@ MD_WIN32_FileIterIncrement(MD_Arena *arena, MD_FileIter *it, MD_String8 path, #endif +//- win32 "low level memory" #if MD_DEFAULT_MEMORY && MD_OS_WINDOWS #if !defined(MD_IMPL_Reserve) @@ -170,23 +107,23 @@ MD_WIN32_Release(void *ptr, MD_u64 size){ ////////////////////////// Linux Implementation //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// +//- linux headers #if (MD_DEFAULT_FILE_ITER || MD_DEFAULT_MEMORY) && MD_OS_LINUX - -#include -#include -#include -#include -#include +# include +# include +# include +# include +# include // NOTE(mal): To get these constants I need to #define _GNU_SOURCE, // which invites non-POSIX behavior I'd rather avoid -#ifndef O_PATH -#define O_PATH 010000000 -#endif -#define AT_NO_AUTOMOUNT 0x800 -#define AT_SYMLINK_NOFOLLOW 0x100 - +# ifndef O_PATH +# define O_PATH 010000000 +# endif +# define AT_NO_AUTOMOUNT 0x800 +# define AT_SYMLINK_NOFOLLOW 0x100 #endif +//- linux "file iteration" #if MD_DEFAULT_FILE_ITER && MD_OS_LINUX #if !defined(MD_IMPL_FileIterIncrement) @@ -254,7 +191,23 @@ MD_LINUX_FileIterIncrement(MD_Arena *arena, MD_FileIter *opaque_it, MD_String8 p #endif +//- linux "low level memory" #if MD_DEFAULT_MEMORY && MD_OS_LINUX + +#if !defined(MD_IMPL_Reserve) +# define MD_IMPL_Reserve MD_LINUX_Reserve +#endif +#if !defined(MD_IMPL_Commit) +# define MD_IMPL_Commit MD_LINUX_Commit +#endif +#if !defined(MD_IMPL_Decommit) +# define MD_IMPL_Decommit MD_LINUX_Decommit +#endif +#if !defined(MD_IMPL_Release) +# define MD_IMPL_Release MD_LINUX_Release +#endif + +// TODO(allen): implement # error not implemented #endif @@ -264,37 +217,38 @@ MD_LINUX_FileIterIncrement(MD_Arena *arena, MD_FileIter *opaque_it, MD_String8 p #if MD_DEFAULT_ARENA -#define MD_ArenaDefault_HeaderSize 64 +#if !defined(MD_IMPL_Reserve) +# error Missing implementation for MD_IMPL_Reserve +#endif +#if !defined(MD_IMPL_Commit) +# error Missing implementation for MD_IMPL_Commit +#endif +#if !defined(MD_IMPL_Decommit) +# error Missing implementation for MD_IMPL_Decommit +#endif +#if !defined(MD_IMPL_Release) +# error Missing implementation for MD_IMPL_Release +#endif + +#define MD_IMPL_ArenaHeaderSize 64 #define MD_ArenaDefault_CommitSize (1 << 20) +MD_StaticAssert(sizeof(MD_ArenaDefault) <= MD_IMPL_ArenaHeaderSize, arena_def_size_check); -typedef struct MD_ArenaDefault MD_ArenaDefault; -struct MD_ArenaDefault{ - MD_u64 pos; - MD_u64 cmt; - MD_u64 cap; - MD_u64 align; -}; -MD_StaticAssert(sizeof(MD_ArenaDefault) <= MD_ArenaDefault_HeaderSize, arena_def_size_check); - -#define MD_IMPL_Arena MD_ArenaDefault -#define MD_IMPL_ArenaNew MD_ArenaDefaultNew +#define MD_IMPL_ArenaAlloc MD_ArenaDefaultAlloc #define MD_IMPL_ArenaRelease MD_ArenaDefaultRelease #define MD_IMPL_ArenaGetPos(a) ((a)->pos) -#define MD_IMPL_ArenaGetCap(a) ((a)->cap) #define MD_IMPL_ArenaPush MD_ArenaDefaultPush #define MD_IMPL_ArenaPopTo MD_ArenaDefaultPopTo -#define MD_IMPL_ArenaPushAlign MD_ArenaDefaultPushAlign #define MD_IMPL_ArenaSetAutoAlign(a,b) ((a)->align = (b)) -#define MD_IMPL_ArenaMinPos(a) MD_ArenaDefault_HeaderSize static MD_Arena* -MD_ArenaDefaultNew(MD_u64 cap){ +MD_ArenaDefaultAlloc(MD_u64 cap){ void *mem = MD_IMPL_Reserve(cap); MD_u64 cmt = ((MD_ArenaDefault_CommitSize < cap) ? MD_ArenaDefault_CommitSize : cap); MD_IMPL_Commit(mem, cmt); MD_ArenaDefault *arena = (MD_ArenaDefault*)mem; - arena->pos = MD_ArenaDefault_HeaderSize; + arena->pos = MD_IMPL_ArenaHeaderSize; arena->cmt = cmt; arena->cap = cap; arena->align = sizeof(void*); @@ -314,7 +268,7 @@ MD_ArenaDefaultPush(MD_ArenaDefault *arena, MD_u64 size){ MD_u8 *buf = (MD_u8*)arena; if (arena->pos + size <= arena->cap){ MD_u64 pos = arena->pos; - MD_u64 pos_clamped = ((pos > MD_ArenaDefault_HeaderSize) ? pos : MD_ArenaDefault_HeaderSize); + MD_u64 pos_clamped = ((pos > MD_IMPL_ArenaHeaderSize) ? pos : MD_IMPL_ArenaHeaderSize); MD_u64 new_pos = pos_clamped + size; MD_u64 align_m1 = arena->align - 1; MD_u64 new_pos_aligned = (new_pos + align_m1)&(~align_m1); @@ -335,34 +289,16 @@ MD_ArenaDefaultPush(MD_ArenaDefault *arena, MD_u64 size){ static void MD_ArenaDefaultPopTo(MD_ArenaDefault *arena, MD_u64 pos){ - MD_u64 pos_clamped = ((pos > MD_ArenaDefault_HeaderSize) ? pos : MD_ArenaDefault_HeaderSize); + MD_u64 pos_clamped = ((pos > MD_IMPL_ArenaHeaderSize) ? pos : MD_IMPL_ArenaHeaderSize); arena->pos = pos_clamped; } -static void -MD_ArenaDefaultPushAlign(MD_ArenaDefault *arena, MD_u64 boundary){ - MD_u64 pos = arena->pos; - MD_u64 pos_clamped = ((pos > MD_ArenaDefault_HeaderSize) ? pos : MD_ArenaDefault_HeaderSize); - MD_u64 align_m1 = boundary - 1; - MD_u64 new_pos_aligned = (pos_clamped + align_m1)&(~align_m1); - MD_u64 new_pos_clamped = ((arena->cap < new_pos_aligned) ? arena->cap : new_pos_aligned); - arena->pos = new_pos_clamped; -} - #endif //~///////////////////////////////////////////////////////////////////////////// //////////////////////// MD Library Implementation ///////////////////////////// //////////////////////////////////////////////////////////////////////////////// -// TODO(allen): update these -#if !defined(MD_IMPL_ArenaNew) -# error Missing implementation for MD_IMPL_ArenaNew -#endif -#if !defined(MD_IMPL_ArenaRelease) -# error Missing implementation for MD_IMPL_ArenaRelease -#endif - #define MD_FUNCTION_IMPL MD_FUNCTION #define MD_UNTERMINATED_TOKEN_LEN_CAP 20 @@ -411,49 +347,86 @@ MD_MemoryCopy(void *dest, void *src, MD_u64 size) //~ Arena Functions +#if !defined(MD_IMPL_ArenaAlloc) +# error Missing implementation for MD_IMPL_ArenaAlloc +#endif +#if !defined(MD_IMPL_ArenaRelease) +# error Missing implementation for MD_IMPL_ArenaRelease +#endif +#if !defined(MD_IMPL_ArenaGetPos) +# error Missing implementation for MD_IMPL_ArenaGetPos +#endif +#if !defined(MD_IMPL_ArenaPush) +# error Missing implementation for MD_IMPL_ArenaPush +#endif +#if !defined(MD_IMPL_ArenaPopTo) +# error Missing implementation for MD_IMPL_ArenaPopTo +#endif +#if !defined(MD_IMPL_ArenaSetAutoAlign) +# error Missing implementation for MD_IMPL_ArenaSetAutoAlign +#endif +#if !defined(MD_IMPL_ArenaHeaderSize) +# error Missing implementation for MD_IMPL_ArenaHeaderSize +#endif + +MD_FUNCTION_IMPL MD_Arena* +MD_ArenaAlloc(MD_u64 cap){ + return(MD_IMPL_ArenaAlloc(cap)); +} + +MD_FUNCTION_IMPL void +MD_ArenaRelease(MD_Arena *arena){ + MD_IMPL_ArenaRelease(arena); +} + MD_FUNCTION_IMPL void* MD_ArenaPush(MD_Arena *arena, MD_u64 size){ - void *result = MD_IMPL_ArenaPush((MD_IMPL_Arena*)arena, size); + void *result = MD_IMPL_ArenaPush(arena, size); return(result); } +MD_FUNCTION_IMPL void +MD_ArenaPutBack(MD_Arena *arena, MD_u64 size){ + MD_u64 pos = MD_IMPL_ArenaGetPos(arena); + MD_u64 new_pos = pos - size; + MD_u64 new_pos_clamped = ((new_pos < MD_IMPL_ArenaHeaderSize) ? + MD_IMPL_ArenaHeaderSize : new_pos); + MD_IMPL_ArenaPopTo(arena, new_pos_clamped); +} + +MD_FUNCTION_IMPL void +MD_ArenaSetAlign(MD_Arena *arena, MD_u64 boundary){ + MD_IMPL_ArenaSetAutoAlign(arena, boundary); +} + +MD_FUNCTION_IMPL void +MD_ArenaPushAlign(MD_Arena *arena, MD_u64 boundary){ + MD_u64 pos = MD_IMPL_ArenaGetPos(arena); + MD_u64 align_m1 = boundary - 1; + MD_u64 new_pos_aligned = (pos + align_m1)&(~align_m1); + MD_u64 new_pos_clamped = ((new_pos_aligned > arena->cap) ? new_pos_aligned : arena->cap); + if (new_pos_clamped > pos){ + MD_u64 amt = new_pos_clamped - pos; + MD_MemoryZero(MD_IMPL_ArenaPush(arena, amt), amt); + } +} + +MD_FUNCTION_IMPL void +MD_ArenaClear(MD_Arena *arena){ + MD_IMPL_ArenaPopTo(arena, MD_IMPL_ArenaHeaderSize); +} + MD_FUNCTION_IMPL MD_ArenaTemp MD_ArenaBeginTemp(MD_Arena *arena){ - MD_ArenaTemp result = MD_ZERO_STRUCT; + MD_ArenaTemp result; result.arena = arena; - result.pos = MD_IMPL_ArenaGetPos((MD_IMPL_Arena*)arena); + result.pos = MD_IMPL_ArenaGetPos(arena); return(result); } MD_FUNCTION_IMPL void MD_ArenaEndTemp(MD_ArenaTemp temp){ - MD_IMPL_ArenaPopTo((MD_IMPL_Arena*)temp.arena, temp.pos); -} - -MD_FUNCTION_IMPL void -MD_ArenaSetAlign(MD_Arena *arena, MD_u64 v){ - MD_IMPL_ArenaSetAutoAlign((MD_IMPL_Arena*)arena, v); -} - -MD_FUNCTION_IMPL void -MD_ArenaPushAlign(MD_Arena *arena, MD_u64 v){ - MD_IMPL_ArenaPushAlign((MD_IMPL_Arena*)arena, v); -} - -MD_FUNCTION_IMPL void -MD_ArenaClear(MD_Arena *arena){ - MD_u64 pos = MD_IMPL_ArenaMinPos((MD_IMPL_Arena*)arena); - MD_IMPL_ArenaPopTo((MD_IMPL_Arena*)arena, pos); -} - -MD_FUNCTION_IMPL MD_Arena* -MD_ArenaNew(MD_u64 cap){ - return((MD_Arena*)MD_IMPL_ArenaNew(cap)); -} - -MD_FUNCTION_IMPL void -MD_ArenaRelease(MD_Arena *arena){ - MD_IMPL_ArenaRelease((MD_IMPL_Arena*)arena); + MD_IMPL_ArenaPopTo(temp.arena, temp.pos); } //~ Thread Context Functions @@ -464,7 +437,7 @@ MD_FUNCTION_IMPL void MD_ThreadInit(MD_ThreadContext *tctx_mem){ md_thread_ctx = tctx_mem; for (MD_u32 i = 0; i < MD_ArrayCount(md_thread_ctx->scratch_pool); i += 1){ - tctx_mem->scratch_pool[i] = MD_ArenaNew(MD_SCRATCH_SIZE); + tctx_mem->scratch_pool[i] = MD_ArenaAlloc(MD_SCRATCH_SIZE); } } @@ -688,7 +661,7 @@ MD_S8Copy(MD_Arena *arena, MD_String8 string) { MD_String8 res; res.size = string.size; - res.str = MD_PushArrayAr(arena, MD_u8, string.size + 1); + res.str = MD_PushArray(arena, MD_u8, string.size + 1); MD_MemoryCopy(res.str, string.str, string.size); return(res); } @@ -700,7 +673,7 @@ MD_S8FmtV(MD_Arena *arena, char *fmt, va_list args) va_list args2; va_copy(args2, args); MD_u64 needed_bytes = md_stbsp_vsnprintf(0, 0, fmt, args)+1; - result.str = MD_PushArrayAr(arena, MD_u8, needed_bytes); + result.str = MD_PushArray(arena, MD_u8, needed_bytes); result.size = needed_bytes - 1; md_stbsp_vsnprintf((char*)result.str, needed_bytes, fmt, args2); return result; @@ -720,7 +693,7 @@ MD_S8Fmt(MD_Arena *arena, char *fmt, ...) MD_FUNCTION_IMPL void MD_S8ListPush(MD_Arena *arena, MD_String8List *list, MD_String8 string) { - MD_String8Node *node = MD_PushArrayAr(arena, MD_String8Node, 1); + MD_String8Node *node = MD_PushArray(arena, MD_String8Node, 1); node->string = string; MD_QueuePush(list->first, list->last, node); @@ -812,7 +785,7 @@ MD_S8ListJoin(MD_Arena *arena, MD_String8List list, MD_StringJoin *join_ptr) MD_String8 result = MD_ZERO_STRUCT; result.size = (list.total_size + join.pre.size + sep_count*join.mid.size + join.post.size); - result.str = MD_PushArrayAr(arena, MD_u8, result.size); + result.str = MD_PushArray(arena, MD_u8, result.size); // fill MD_u8 *ptr = result.str; @@ -895,7 +868,7 @@ MD_S8Stylize(MD_Arena *arena, MD_String8 string, MD_IdentifierStyle word_style, { result.size += separator.size*(words.node_count-1); } - result.str = MD_PushArrayAr(arena, MD_u8, result.size); + result.str = MD_PushArray(arena, MD_u8, result.size); { MD_u64 write_pos = 0; @@ -1123,7 +1096,7 @@ MD_FUNCTION MD_String8 MD_S8FromS16(MD_Arena *arena, MD_String16 in) { MD_u64 cap = in.size*3; - MD_u8 *str = MD_PushArrayAr(arena, MD_u8, cap + 1); + MD_u8 *str = MD_PushArray(arena, MD_u8, cap + 1); MD_u16 *ptr = in.str; MD_u16 *opl = ptr + in.size; MD_u64 size = 0; @@ -1142,7 +1115,7 @@ MD_FUNCTION MD_String16 MD_S16FromS8(MD_Arena *arena, MD_String8 in) { MD_u64 cap = in.size*2; - MD_u16 *str = MD_PushArrayAr(arena, MD_u16, (cap + 1)); + MD_u16 *str = MD_PushArray(arena, MD_u16, (cap + 1)); MD_u8 *ptr = in.str; MD_u8 *opl = ptr + in.size; MD_u64 size = 0; @@ -1162,7 +1135,7 @@ MD_FUNCTION MD_String8 MD_S8FromS32(MD_Arena *arena, MD_String32 in) { MD_u64 cap = in.size*4; - MD_u8 *str = MD_PushArrayAr(arena, MD_u8, cap + 1); + MD_u8 *str = MD_PushArray(arena, MD_u8, cap + 1); MD_u32 *ptr = in.str; MD_u32 *opl = ptr + in.size; MD_u64 size = 0; @@ -1179,7 +1152,7 @@ MD_FUNCTION MD_String32 MD_S32FromS8(MD_Arena *arena, MD_String8 in) { MD_u64 cap = in.size; - MD_u32 *str = MD_PushArrayAr(arena, MD_u32, (cap + 1)); + MD_u32 *str = MD_PushArray(arena, MD_u32, (cap + 1)); MD_u8 *ptr = in.str; MD_u8 *opl = ptr + in.size; MD_u64 size = 0; @@ -1364,7 +1337,7 @@ MD_CStyleHexStringFromU64(MD_Arena *arena, MD_u64 x, MD_b32 caps) MD_String8 result = MD_ZERO_STRUCT; result.size = (MD_u64)(ptr - buffer); - result.str = MD_PushArrayAr(arena, MD_u8, result.size); + result.str = MD_PushArray(arena, MD_u8, result.size); MD_MemoryCopy(result.str, buffer, result.size); return(result); } @@ -1460,10 +1433,9 @@ MD_HashPtr(void *p) MD_FUNCTION_IMPL MD_Map MD_MapMakeBucketCount(MD_Arena *arena, MD_u64 bucket_count){ - // TODO(allen): super arena? MD_Map result = {0}; result.bucket_count = bucket_count; - result.buckets = MD_PushArrayZeroAr(arena, MD_MapBucket, bucket_count); + result.buckets = MD_PushArrayZero(arena, MD_MapBucket, bucket_count); return(result); } @@ -1541,7 +1513,7 @@ MD_MapInsert(MD_Arena *arena, MD_Map *map, MD_MapKey key, void *val){ MD_MapSlot *result = 0; if (map->bucket_count > 0){ MD_u64 index = key.hash%map->bucket_count; - MD_MapSlot *slot = MD_PushArrayAr(arena, MD_MapSlot, 1); + MD_MapSlot *slot = MD_PushArray(arena, MD_MapSlot, 1); MD_MapBucket *bucket = &map->buckets[index]; MD_QueuePush(bucket->first, bucket->last, slot); slot->key = key; @@ -1842,7 +1814,7 @@ MD_LexAdvanceFromSkips(MD_String8 string, MD_TokenKind skip_kinds) MD_FUNCTION_IMPL MD_Message* MD_MakeNodeError(MD_Arena *arena, MD_Node *node, MD_MessageKind kind, MD_String8 str) { - MD_Message *error = MD_PushArrayZeroAr(arena, MD_Message, 1); + MD_Message *error = MD_PushArrayZero(arena, MD_Message, 1); error->node = node; error->kind = kind; error->string = str; @@ -2510,7 +2482,7 @@ MD_FUNCTION_IMPL MD_Node * MD_MakeNode(MD_Arena *arena, MD_NodeKind kind, MD_String8 string, MD_String8 raw_string, MD_u64 offset) { - MD_Node *node = MD_PushArrayZeroAr(arena, MD_Node, 1); + MD_Node *node = MD_PushArrayZero(arena, MD_Node, 1); node->kind = kind; node->string = string; node->raw_string = raw_string; @@ -2976,7 +2948,7 @@ MD_MakeCmdLineFromOptions(MD_Arena *arena, MD_String8List options) //- rjf: insert the fully parsed option { - MD_CmdLineOption *opt = MD_PushArrayAr(arena, MD_CmdLineOption, 1); + MD_CmdLineOption *opt = MD_PushArray(arena, MD_CmdLineOption, 1); MD_MemoryZero(opt, sizeof(*opt)); opt->name = option_name; opt->values = option_values; @@ -3056,7 +3028,7 @@ MD_LoadEntireFile(MD_Arena *arena, MD_String8 filename) fseek(file, 0, SEEK_END); MD_u64 file_size = ftell(file); fseek(file, 0, SEEK_SET); - file_contents.str = MD_PushArrayAr(arena, MD_u8, file_size+1); + file_contents.str = MD_PushArray(arena, MD_u8, file_size+1); if(file_contents.str) { file_contents.size = file_size; diff --git a/source/md.h b/source/md.h index 9186c90..8d9c925 100644 --- a/source/md.h +++ b/source/md.h @@ -5,6 +5,55 @@ #ifndef MD_H #define MD_H +/* NOTE(allen): Notes on overrides/macro options: +** +** Individual Overridables: +** "file iteration" ** OPTIONAL +** #define MD_IMPL_FileIterIncrement +** (MD_Arena*, MD_FileIter*, MD_String8, MD_FileInfo* out) -> MD_b32 +** +** "low level memory" ** OPTIONAL (required for default arena) +** #define MD_IMPL_Reserve (MD_u64) -> void* +** #define MD_IMPL_Commit (void*, MD_u64) -> void +** #define MD_IMPL_Decommit (void*, MD_u64) -> void +** #define MD_IMPL_Release (void*, MD_u64) -> void +** +** "arena" ** REQUIRED (default implementation available) +** #define MD_IMPL_Arena +** #define MD_IMPL_ArenaAlloc (MD_u64) -> MD_IMPL_Arena* +** #define MD_IMPL_ArenaRelease (MD_IMPL_Arena*) -> void +** #define MD_IMPL_ArenaGetPos (MD_IMPL_Arena*) -> MD_u64 +** #define MD_IMPL_ArenaPush (MD_IMPL_Arena*, MD_u64) -> void* +** #define MD_IMPL_ArenaPopTo (MD_IMPL_Arena*, MD_u64) -> void +** #define MD_IMPL_ArenaSetAutoAlign (MD_IMPL_Arena*, MD_u64) -> void +** #define MD_IMPL_ArenaHeaderSize MD_u64 +** +** "constants" ** REQUIRED (defaults to 1 gigabyte) +** #define MD_SCRATCH_SIZE MD_u64 +** +** Default Implementation Controls +** These controls default to '1' i.e. 'enabled' +** #define MD_DEFAULT_FILE_ITER -> construct "file iteration" from OS headers +** #define MD_DEFAULT_MEMORY -> construct "low level memory" from OS headers +** #define MD_DEFAULT_ARENA -> construct "arena" from "low level memory" +** +*/ + +//~ Set default values for controls +#if !defined(MD_DEFAULT_FILE_ITER) +# define MD_DEFAULT_FILE_ITER 1 +#endif +#if !defined(MD_DEFAULT_MEMORY) +# define MD_DEFAULT_MEMORY 1 +#endif +#if !defined(MD_DEFAULT_ARENA) +# define MD_DEFAULT_ARENA 1 +#endif +#if !defined(MD_SCRATCH_SIZE) +# define MD_SCRATCH_SIZE (1 << 30) +#endif + + // NOTE(rjf): Compiler cracking from the 4th dimension #if defined(__clang__) @@ -258,9 +307,28 @@ typedef int64_t MD_b64; typedef float MD_f32; typedef double MD_f64; -//~ Abstract Arena +//~ Default Arena -typedef void MD_Arena; +#if MD_DEFAULT_ARENA + +typedef struct MD_ArenaDefault MD_ArenaDefault; +struct MD_ArenaDefault{ + MD_u64 pos; + MD_u64 cmt; + MD_u64 cap; + MD_u64 align; +}; +#define MD_IMPL_Arena MD_ArenaDefault + +#endif + +//~ Abstract Arena Type + +#if !defined(MD_IMPL_Arena) +# error Missing implementation for MD_IMPL_Arena +#endif + +typedef MD_IMPL_Arena MD_Arena; //~ Arena Helpers @@ -272,6 +340,7 @@ struct MD_ArenaTemp{ //~ Thread Context +// TODO(allen): overrides for get scratch typedef struct MD_ThreadContext MD_ThreadContext; struct MD_ThreadContext{ MD_Arena *scratch_pool[2]; @@ -682,19 +751,20 @@ MD_FUNCTION void* MD_MemoryCopy(void *dst, void *src, MD_u64 size); //~ Arena Functions -MD_FUNCTION void* MD_ArenaPush(MD_Arena *arena, MD_u64 v); -MD_FUNCTION MD_ArenaTemp MD_ArenaBeginTemp(MD_Arena *arena); -MD_FUNCTION void MD_ArenaEndTemp(MD_ArenaTemp temp); -MD_FUNCTION void MD_ArenaSetAlign(MD_Arena *arena, MD_u64 v); -MD_FUNCTION void MD_ArenaPushAlign(MD_Arena *arena, MD_u64 v); +MD_FUNCTION MD_Arena* MD_ArenaAlloc(MD_u64 cap); +MD_FUNCTION void MD_ArenaRelease(MD_Arena *arena); + +MD_FUNCTION void* MD_ArenaPush(MD_Arena *arena, MD_u64 size); +MD_FUNCTION void MD_ArenaPutBack(MD_Arena *arena, MD_u64 size); +MD_FUNCTION void MD_ArenaSetAlign(MD_Arena *arena, MD_u64 boundary); +MD_FUNCTION void MD_ArenaPushAlign(MD_Arena *arena, MD_u64 boundary); MD_FUNCTION void MD_ArenaClear(MD_Arena *arena); -#define MD_PushArrayAr(a,T,c) (T*)(MD_ArenaPush((a), sizeof(T)*(c))) -#define MD_PushArrayZeroAr(a,T,c) (T*)(MD_MemoryZero(MD_ArenaPush((a), sizeof(T)*(c)),\ -sizeof(T)*(c))) +#define MD_PushArray(a,T,c) (T*)(MD_ArenaPush((a), sizeof(T)*(c))) +#define MD_PushArrayZero(a,T,c) (T*)(MD_MemoryZero(MD_PushArray(a,T,c), sizeof(T)*(c))) -MD_FUNCTION MD_Arena* MD_ArenaNew(MD_u64 cap); -MD_FUNCTION void MD_ArenaRelease(MD_Arena *arena); +MD_FUNCTION MD_ArenaTemp MD_ArenaBeginTemp(MD_Arena *arena); +MD_FUNCTION void MD_ArenaEndTemp(MD_ArenaTemp temp); //~ Thread Context Functions diff --git a/source/md_c_helpers.c b/source/md_c_helpers.c index e88087c..5a781df 100644 --- a/source/md_c_helpers.c +++ b/source/md_c_helpers.c @@ -174,7 +174,7 @@ MD_FUNCTION_IMPL MD_C_Expr * MD_C_MakeExpr(MD_Arena *arena, MD_Node *node, MD_C_ExprKind kind, MD_C_Expr *left, MD_C_Expr *right) { - MD_C_Expr *expr = MD_PushArrayAr(arena, MD_C_Expr, 1); + MD_C_Expr *expr = MD_PushArray(arena, MD_C_Expr, 1); if(left == 0) left = MD_C_NilExpr(); if(right == 0) right = MD_C_NilExpr(); expr->node = node; diff --git a/tests/cpp_build_test.cpp b/tests/cpp_build_test.cpp index 33b4634..1fa785b 100644 --- a/tests/cpp_build_test.cpp +++ b/tests/cpp_build_test.cpp @@ -8,7 +8,7 @@ int main(void) MD_ThreadContext tctx; MD_ThreadInit(&tctx); - arena = MD_ArenaNew(1ull << 40); + arena = MD_ArenaAlloc(1ull << 40); printf("%d\n", MD_CPP_VERSION); diff --git a/tests/sanity_tests.c b/tests/sanity_tests.c index 495c680..188fc4a 100644 --- a/tests/sanity_tests.c +++ b/tests/sanity_tests.c @@ -123,7 +123,7 @@ int main(void) MD_ThreadContext tctx; MD_ThreadInit(&tctx); - arena = MD_ArenaNew(1ull << 40); + arena = MD_ArenaAlloc(1ull << 40); Test("Lexer") { diff --git a/tests/unicode_test.c b/tests/unicode_test.c index d40220f..4886b09 100644 --- a/tests/unicode_test.c +++ b/tests/unicode_test.c @@ -19,7 +19,7 @@ int main(void) MD_ThreadContext tctx; MD_ThreadInit(&tctx); - arena = MD_ArenaNew(1ull << 40); + arena = MD_ArenaAlloc(1ull << 40); // TODO(allen): throw more at this.