diff --git a/bin/run_examples.sh b/bin/run_examples.sh index 0bbd96e..5532d48 100755 --- a/bin/run_examples.sh +++ b/bin/run_examples.sh @@ -8,12 +8,21 @@ root_path=$PWD build_path=$root_path/build examps=$root_path/examples +# Setup a big list of files for a few of the examples +big_list= $examps/intro/hello_world.mdesk +bit_list=$big_list $examps/intro/labels.mdesk +bit_list=$big_list $examps/intro/sets.mdesk +bit_list=$big_list $examps/type_metadata/types.mdesk +bit_list=$big_list $examps/type_metadata/bad_types.mdesk +bit_list=$big_list $examps/expr/expr_intro.mdesk +bit_list=$big_list $examps/expr/expr_c_like.mdesk + echo ~~~ Running Memory Management Example ~~~ -$build_path/memory_management.exe $examps/intro/hello_world.mdesk $examps/intro/labels.mdesk $examps/intro/sets.mdesk +$build_path/memory_management.exe $big_list echo echo ~~~ Running Multi-Threaded Parse Example ~~~ -$build_path/multi_threaded.exe $examps/intro/hello_world.mdesk $examps/intro/labels.mdesk $examps/intro/sets.mdesk +$build_path/multi_threaded.exe $big_list echo echo ~~~ Running Type Metadata Generator Example ~~~ diff --git a/examples/integration/multi_threaded.c b/examples/integration/multi_threaded.c index a88c287..d9acecc 100644 --- a/examples/integration/multi_threaded.c +++ b/examples/integration/multi_threaded.c @@ -9,10 +9,140 @@ #include "md.h" #include "md.c" +#include + +//~ multi-threaded parse setup //////////////////////////////////////////////// + +#if MD_COMPILER_CL +# define atomic_inc_u64(p) InterlockedIncrement64((LONG64*)p) +#else +# error Not implemented for this compiler +#endif + +typedef struct TaskData +{ + MD_u64 task_max; + char **tasks; + + volatile MD_u64 task_counter; + volatile MD_u64 thread_counter; +} TaskData; + +typedef struct ThreadData +{ + TaskData *task; + MD_Arena *arena; + MD_Node *list; + MD_MessageList errors; +} ThreadData; + +void +parse_worker_loop(ThreadData *thread_data) +{ + TaskData *task = thread_data->task; + for (;;) + { + MD_u64 task_index = atomic_inc_u64(&task->task_counter); + if (task_index >= task->task_max) + { + break; + } + MD_String8 file_name = MD_S8CString(task->tasks[task_index]); + MD_ParseResult parse = MD_ParseWholeFile(thread_data->arena, file_name); + if (parse.errors.first != 0) + { + MD_MessageListConcat(&thread_data->errors, &parse.errors); + } + else + { + MD_PushNewReference(thread_data->arena, thread_data->list, parse.node); + } + } + + atomic_inc_u64(&task->thread_counter); +} + +#if MD_OS_WINDOWS +DWORD +parse_worker_win32(LPVOID parameter) +{ + parse_worker_loop((ThreadData*)parameter); + return(0); +} +#else +# error Not implemented for this OS +#endif + + //~ main ////////////////////////////////////////////////////////////////////// int main(int argc, char **argv) { - // TODO(allen) +#if 1 + char *argv_dummy[8] = { + 0, + "W:\\metadesk\\examples\\intro\\hello_world.mdesk", + "W:\\metadesk\\examples\\intro\\labels.mdesk", + "W:\\metadesk\\examples\\intro\\sets.mdesk", + "W:\\metadesk\\examples\\type_metadata\\types.mdesk", + "W:\\metadesk\\examples\\type_metadata\\bad_types.mdesk", + "W:\\metadesk\\examples\\expr\\expr_intro.mdesk", + "W:\\metadesk\\examples\\expr\\expr_c_like.mdesk", + }; + argc = 8; + argv = argv_dummy; +#endif + + // make sure we have something to parse + if (argc <= 1) + { + fprintf(stderr, "pass at least one input file"); + exit(1); + } + + // setup the shared task data + TaskData task = {0}; + task.task_max = argc - 1; + task.tasks = argv + 1; + + // setup the per-thread data +#define THREAD_COUNT 2 + ThreadData threads[THREAD_COUNT] = {0}; + for (int i = 0; i < THREAD_COUNT; i += 1) + { + threads[i].task = &task; + threads[i].arena = MD_ArenaAlloc(); + threads[i].list = MD_MakeList(threads[i].arena); + } + + // launch the worker threads + for (int i = 1; i < THREAD_COUNT; i += 1) + { +#if MD_OS_WINDOWS + HANDLE handle = CreateThread(0, 0, parse_worker_win32, threads + i, 0, 0); + CloseHandle(handle); +#else +# error Not implemented for this OS +#endif + } + + parse_worker_loop(&threads[0]); + + // wait for all threads to be finished + for (;;) + { + MD_u64 thread_counter = task.thread_counter; + if (thread_counter >= THREAD_COUNT) + { + break; + } +#if MD_OS_WINDOWS + Sleep(0); +#else +# error Not implemented for this OS +#endif + } + + // TODO(allen): combine results } diff --git a/examples/type_metadata/generated/meta_types.c b/examples/type_metadata/generated/meta_types.c index 448dbd5..a4b9503 100644 --- a/examples/type_metadata/generated/meta_types.c +++ b/examples/type_metadata/generated/meta_types.c @@ -1,4 +1,4 @@ -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:991 +// generated by W:\metadesk\examples\type_metadata\type_metadata.c:991 TypeInfoMember Circle_members[2] = { {"r", 1, -1, &F32_type_info}, {"pos", 3, -1, &V2F32_type_info}, @@ -14,14 +14,14 @@ TypeInfoMember RoundedPolygon_members[3] = { {"p", 1, 1, &V2F32_type_info}, }; -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:1030 +// generated by W:\metadesk\examples\type_metadata\type_metadata.c:1030 TypeInfoEnumerant Shape_members[3] = { {"Circle", 6, 1}, {"Segment", 7, 2}, {"Polygon", 7, 3}, }; -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:1066 +// generated by W:\metadesk\examples\type_metadata\type_metadata.c:1066 TypeInfo U32_type_info = {TypeKind_Basic, "U32", 3, 4, 0, 0}; TypeInfo F32_type_info = {TypeKind_Basic, "F32", 3, 4, 0, 0}; TypeInfo V2F32_type_info = {TypeKind_Basic, "V2F32", 5, 8, 0, 0}; @@ -30,7 +30,7 @@ TypeInfo RoundedSegment_type_info = {TypeKind_Struct, "RoundedSegment", 14, 3, R TypeInfo RoundedPolygon_type_info = {TypeKind_Struct, "RoundedPolygon", 14, 3, RoundedPolygon_members, 0}; TypeInfo Shape_type_info = {TypeKind_Enum, "Shape", 5, 3, Shape_members, &U32_type_info}; -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:1126 +// generated by W:\metadesk\examples\type_metadata\type_metadata.c:1126 TypeInfo* type_info_from_shape(Shape v) { diff --git a/examples/type_metadata/generated/meta_types.h b/examples/type_metadata/generated/meta_types.h index 789fcea..572c62d 100644 --- a/examples/type_metadata/generated/meta_types.h +++ b/examples/type_metadata/generated/meta_types.h @@ -1,6 +1,6 @@ #if !defined(META_TYPES_H) #define META_TYPES_H -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:868 +// generated by W:\metadesk\examples\type_metadata\type_metadata.c:868 typedef struct Circle Circle; struct Circle { @@ -29,11 +29,11 @@ Shape_Segment = 2, Shape_Polygon = 3, }; -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:952 +// generated by W:\metadesk\examples\type_metadata\type_metadata.c:952 TypeInfo* type_info_from_shape(Shape v); U32 max_slot_from_shape(Shape v); -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:975 +// generated by W:\metadesk\examples\type_metadata\type_metadata.c:975 extern TypeInfo U32_type_info; extern TypeInfo F32_type_info; extern TypeInfo V2F32_type_info; diff --git a/source/md.c b/source/md.c index b8754f6..377ed1b 100644 --- a/source/md.c +++ b/source/md.c @@ -597,6 +597,8 @@ MD_ArenaDefaultSetAutoAlign(MD_ArenaDefault *arena, MD_u64 align) arena->align = align; } +// TODO(allen): Arena absorb + #endif //- "arena" implementation checks