memory arena and mem copy/compare functions for orca

This commit is contained in:
Martin Fouilleul 2023-04-17 18:13:07 +02:00
parent 4f90efbb22
commit d43afa2ac0
9 changed files with 195 additions and 193 deletions

@ -1 +1 @@
Subproject commit f36e144bc0fed66470aff0612098dba29c552604 Subproject commit e9e9ab68c250c597fd6b7552d97977b99b103d33

View File

@ -42,8 +42,11 @@ bool rightDown = false;
g_font font; g_font font;
mem_arena arena;
void OnInit(void) void OnInit(void)
{ {
mem_arena_init(&arena);
font = g_font_create_default(); font = g_font_create_default();
//log_string(str8_lit("init procedure\n")); //log_string(str8_lit("init procedure\n"));
} }
@ -95,6 +98,7 @@ void OnKeyUp(int key)
void OnFrameRefresh(void) void OnFrameRefresh(void)
{ {
char* tmp = mem_arena_alloc(&arena, 512);
//log_string(str8_lit("frame procedure\n")); //log_string(str8_lit("frame procedure\n"));
f32 aspect = frameSize.x/frameSize.y; f32 aspect = frameSize.x/frameSize.y;
@ -168,4 +172,6 @@ void OnFrameRefresh(void)
g_fill(); g_fill();
g_matrix_pop(); g_matrix_pop();
mem_arena_clear(&arena);
} }

View File

@ -6,4 +6,5 @@
* *
*****************************************************************/ *****************************************************************/
//#include"util/memory.c" #include"platform/orca_memory.c"
#include"util/memory.c"

View File

@ -10,5 +10,6 @@
#include"util/typedefs.h" #include"util/typedefs.h"
#include"util/lists.h" #include"util/lists.h"
#include"util/memory.h"
#endif //__ORCA_H_ #endif //__ORCA_H_

View File

@ -1,69 +0,0 @@
//*****************************************************************
//
// $file: typedefs.h $
// $author: Martin Fouilleul $
// $date: 23/36/2015 $
// $revision: $
//
//*****************************************************************
#ifndef __TYPEDEFS_H_
#define __TYPEDEFS_H_
#include<stdint.h>
#include<float.h> //FLT_MAX/MIN etc...
#ifndef __cplusplus
#include<stdbool.h>
#endif //__cplusplus
typedef uint8_t byte;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
typedef float f32;
typedef double f64;
typedef union
{
struct
{
f32 x;
f32 y;
};
f32 c[2];
} vec2;
typedef union
{
struct
{
f32 x;
f32 y;
f32 z;
f32 w;
};
f32 c[4];
} vec4;
#define vec4_expand_xyz(v) (v).x, (v).y, (v).z
typedef union
{
struct
{
f32 x;
f32 y;
f32 w;
f32 h;
};
f32 c[4];
} mp_rect;
#endif //__TYPEDEFS_H_

View File

@ -4,3 +4,5 @@ cosf f(f)
sinf f(f) sinf f(f)
floorf f(f) floorf f(f)
sqrtf f(f) sqrtf f(f)
orca_mem_grow i(I)
orca_assert v(i)

View File

@ -10,13 +10,13 @@
#include<pthread.h> #include<pthread.h>
#include<math.h> #include<math.h>
#include"wasm3.h"
#include"m3_env.h"
#include"m3_compile.h"
#define MG_INCLUDE_GL_API #define MG_INCLUDE_GL_API
#include"milepost.h" #include"milepost.h"
#include"orca_runtime.h"
#include"memory_impl.c"
#define LOG_SUBSYSTEM "Orca" #define LOG_SUBSYSTEM "Orca"
@ -37,6 +37,11 @@ void mg_matrix_push_flat(float a11, float a12, float a13,
mg_matrix_push(m); mg_matrix_push(m);
} }
void orca_assert(bool x)
{
ASSERT(x);
}
mg_font mg_font_create_default() mg_font mg_font_create_default()
{ {
//NOTE(martin): create default font //NOTE(martin): create default font
@ -82,40 +87,10 @@ typedef struct orca_app
mg_surface mtlSurface; mg_surface mtlSurface;
mg_canvas canvas; mg_canvas canvas;
orca_runtime runtime;
} orca_app; } orca_app;
#define G_EVENTS(X) \
X(G_EVENT_START, "OnInit", "", "") \
X(G_EVENT_MOUSE_DOWN, "OnMouseDown", "", "i") \
X(G_EVENT_MOUSE_UP, "OnMouseUp", "", "i") \
X(G_EVENT_MOUSE_ENTER, "OnMouseEnter", "", "") \
X(G_EVENT_MOUSE_LEAVE, "OnMouseLeave", "", "") \
X(G_EVENT_MOUSE_MOVE, "OnMouseMove", "", "ffff") \
X(G_EVENT_MOUSE_WHEEL, "OnMouseWheel", "", "ff") \
X(G_EVENT_KEY_DOWN, "OnKeyDown", "", "i") \
X(G_EVENT_KEY_UP, "OnKeyUp", "", "i") \
X(G_EVENT_FRAME_REFRESH, "OnFrameRefresh", "", "") \
X(G_EVENT_FRAME_RESIZE, "OnFrameResize", "", "ii")
typedef enum {
#define G_EVENT_KIND(kind, ...) kind,
G_EVENTS(G_EVENT_KIND)
G_EVENT_COUNT
} guest_event_kind;
typedef struct g_event_handler_desc
{
str8 name;
str8 retTags;
str8 argTags;
} g_event_handler_desc;
const g_event_handler_desc G_EVENT_HANDLER_DESC[] = {
#define G_EVENT_HANDLER_DESC_ENTRY(kind, name, rets, args) {STR8(name), STR8(rets), STR8(args)},
G_EVENTS(G_EVENT_HANDLER_DESC_ENTRY)
};
char m3_type_to_tag(M3ValueType type) char m3_type_to_tag(M3ValueType type)
{ {
switch(type) switch(type)
@ -136,59 +111,27 @@ char m3_type_to_tag(M3ValueType type)
} }
} }
typedef struct host_memory void orca_runtime_init(orca_runtime* runtime)
{
char* ptr;
u32 reserved;
u32 committed;
} host_memory;
void host_memory_init(host_memory* memory)
{ {
memset(runtime, 0, sizeof(orca_runtime));
mem_base_allocator* allocator = mem_base_allocator_default(); mem_base_allocator* allocator = mem_base_allocator_default();
memory->committed = 0; runtime->wasmMemory.committed = 0;
memory->reserved = 4<<20; runtime->wasmMemory.reserved = 4ULL<<30;
memory->ptr = mem_base_reserve(allocator, memory->reserved); runtime->wasmMemory.ptr = mem_base_reserve(allocator, runtime->wasmMemory.reserved);
} }
void* host_memory_resize_callback(void* p, unsigned long size, void* userData) orca_app __orcaApp;
orca_runtime* orca_runtime_get()
{ {
host_memory* memory = (host_memory*)userData; return(&__orcaApp.runtime);
if(memory->committed >= size)
{
return(memory->ptr);
}
else if(memory->committed < memory->reserved)
{
u32 commitSize = size - memory->committed;
mem_base_allocator* allocator = mem_base_allocator_default();
mem_base_commit(allocator, memory->ptr + memory->committed, commitSize);
memory->committed += commitSize;
return(memory->ptr);
}
else
{
DEBUG_ASSERT(0, "Out of memory");
return(0);
}
}
void host_memory_free_callback(void* p, void* userData)
{
host_memory* memory = (host_memory*)userData;
mem_base_allocator* allocator = mem_base_allocator_default();
mem_base_release(allocator, memory->ptr, memory->reserved);
memset(memory, 0, sizeof(host_memory));
} }
void* orca_runloop(void* user) void* orca_runloop(void* user)
{ {
orca_app* app = (orca_app*)user; orca_app* app = &__orcaApp;
mem_arena_init(mem_scratch());
orca_runtime_init(&app->runtime);
//NOTE: loads wasm module //NOTE: loads wasm module
const char* bundleNameCString = "module"; const char* bundleNameCString = "module";
@ -206,49 +149,46 @@ void* orca_runloop(void* user)
u64 wasmSize = ftell(file); u64 wasmSize = ftell(file);
rewind(file); rewind(file);
u8* wasmBytes = malloc_array(u8, wasmSize); app->runtime.wasmBytecode.len = wasmSize;
fread(wasmBytes, 1, wasmSize, file); app->runtime.wasmBytecode.ptr = malloc_array(char, wasmSize);
fread(app->runtime.wasmBytecode.ptr, 1, app->runtime.wasmBytecode.len, file);
fclose(file); fclose(file);
u32 stackSize = 65536; u32 stackSize = 65536;
IM3Environment env = m3_NewEnvironment(); app->runtime.m3Env = m3_NewEnvironment();
host_memory hostMemory = {}; app->runtime.m3Runtime = m3_NewRuntime(app->runtime.m3Env, stackSize, NULL);
host_memory_init(&hostMemory); m3_RuntimeSetMemoryCallbacks(app->runtime.m3Runtime, wasm_memory_resize_callback, wasm_memory_free_callback, &app->runtime.wasmMemory);
IM3Runtime runtime = m3_NewRuntime(env, stackSize, NULL);
m3_RuntimeSetMemoryCallbacks(runtime, host_memory_resize_callback, host_memory_free_callback, &hostMemory);
//NOTE: host memory will be freed when runtime is freed. //NOTE: host memory will be freed when runtime is freed.
IM3Module module = 0;
//TODO check errors //TODO check errors
m3_ParseModule(env, &module, wasmBytes, wasmSize); m3_ParseModule(app->runtime.m3Env, &app->runtime.m3Module, (u8*)app->runtime.wasmBytecode.ptr, app->runtime.wasmBytecode.len);
m3_LoadModule(runtime, module); m3_LoadModule(app->runtime.m3Runtime, app->runtime.m3Module);
m3_SetModuleName(module, bundleNameCString); m3_SetModuleName(app->runtime.m3Module, bundleNameCString);
mem_scratch_clear(); mem_scratch_clear();
//NOTE: bind orca APIs //NOTE: bind orca APIs
bindgen_link_core_api(module); bindgen_link_core_api(app->runtime.m3Module);
bindgen_link_canvas_api(module); bindgen_link_canvas_api(app->runtime.m3Module);
bindgen_link_gles_api(module); bindgen_link_gles_api(app->runtime.m3Module);
manual_link_gles_api(module); manual_link_gles_api(app->runtime.m3Module);
//NOTE: compile //NOTE: compile
M3Result res = m3_CompileModule(module); M3Result res = m3_CompileModule(app->runtime.m3Module);
if(res) if(res)
{ {
M3ErrorInfo errInfo = {}; M3ErrorInfo errInfo = {};
m3_GetErrorInfo(runtime, &errInfo); m3_GetErrorInfo(app->runtime.m3Runtime, &errInfo);
LOG_ERROR("wasm error: %s\n", errInfo.message); LOG_ERROR("wasm error: %s\n", errInfo.message);
return((void*)-1);
} }
//NOTE: Find heap base //NOTE: Find heap base
u32 heapBase = 0; u32 heapBase = 0;
{ {
IM3Global global = m3_FindGlobal(module, "__heap_base"); IM3Global global = m3_FindGlobal(app->runtime.m3Module, "__heap_base");
if(global) if(global)
{ {
M3TaggedValue val; M3TaggedValue val;
@ -271,15 +211,15 @@ void* orca_runloop(void* user)
} }
//NOTE: align heap base on 16Bytes //NOTE: align heap base on 16Bytes
heapBase = AlignUpOnPow2(heapBase, 16); heapBase = AlignUpOnPow2(heapBase, 16);
LOG_MESSAGE("mem_size = %u, __heap_base = %u\n", m3_GetMemorySize(runtime), heapBase); LOG_MESSAGE("mem_size = %u, __heap_base = %u\n", m3_GetMemorySize(app->runtime.m3Runtime), heapBase);
//NOTE: Find and type check event handlers. //NOTE: Find and type check event handlers.
IM3Function eventHandlers[G_EVENT_COUNT] = {0};
for(int i=0; i<G_EVENT_COUNT; i++) for(int i=0; i<G_EVENT_COUNT; i++)
{ {
const g_event_handler_desc* desc = &G_EVENT_HANDLER_DESC[i]; const g_event_handler_desc* desc = &G_EVENT_HANDLER_DESC[i];
IM3Function handler = 0; IM3Function handler = 0;
m3_FindFunction(&handler, runtime, desc->name.ptr); m3_FindFunction(&handler, app->runtime.m3Runtime, desc->name.ptr);
if(handler) if(handler)
{ {
@ -320,7 +260,7 @@ void* orca_runloop(void* user)
if(checked) if(checked)
{ {
eventHandlers[i] = handler; app->runtime.eventHandlers[i] = handler;
} }
else else
{ {
@ -334,6 +274,8 @@ void* orca_runloop(void* user)
//NOTE: prepare GL surface //NOTE: prepare GL surface
mg_surface_prepare(app->surface); mg_surface_prepare(app->surface);
IM3Function* eventHandlers = app->runtime.eventHandlers;
//NOTE: call init handler //NOTE: call init handler
if(eventHandlers[G_EVENT_START]) if(eventHandlers[G_EVENT_START])
{ {
@ -431,18 +373,6 @@ void* orca_runloop(void* user)
} }
} }
/* mg_surface_prepare(app->surface);
glClearColor(1, 0, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
if(eventHandlers[G_EVENT_FRAME_REFRESH])
{
m3_Call(eventHandlers[G_EVENT_FRAME_REFRESH], 0, 0);
}
mg_surface_present(app->surface);
*/
mg_canvas_prepare(app->canvas); mg_canvas_prepare(app->canvas);
if(eventHandlers[G_EVENT_FRAME_REFRESH]) if(eventHandlers[G_EVENT_FRAME_REFRESH])
@ -488,13 +418,13 @@ int main(int argc, char** argv)
mg_surface_swap_interval(mtlSurface, 1); mg_surface_swap_interval(mtlSurface, 1);
mg_canvas canvas = mg_canvas_create(mtlSurface); mg_canvas canvas = mg_canvas_create(mtlSurface);
orca_app app = {.window = window, __orcaApp = (orca_app){.window = window,
.surface = surface, .surface = surface,
.mtlSurface = mtlSurface, .mtlSurface = mtlSurface,
.canvas = canvas}; .canvas = canvas};
pthread_t runloopThread; pthread_t runloopThread;
pthread_create(&runloopThread, 0, orca_runloop, &app); pthread_create(&runloopThread, 0, orca_runloop, 0);
while(!mp_should_quit()) while(!mp_should_quit())
{ {

59
src/memory_impl.c Normal file
View File

@ -0,0 +1,59 @@
/************************************************************//**
*
* @file: memory_impl.c
* @author: Martin Fouilleul
* @date: 17/04/2023
*
*****************************************************************/
#include"orca_runtime.h"
void* wasm_memory_resize_callback(void* p, unsigned long size, void* userData)
{
wasm_memory* memory = (wasm_memory*)userData;
if(memory->committed >= size)
{
return(memory->ptr);
}
else if(memory->committed < memory->reserved)
{
u32 commitSize = size - memory->committed;
mem_base_allocator* allocator = mem_base_allocator_default();
mem_base_commit(allocator, memory->ptr + memory->committed, commitSize);
memory->committed += commitSize;
return(memory->ptr);
}
else
{
DEBUG_ASSERT(0, "Out of memory");
return(0);
}
}
void wasm_memory_free_callback(void* p, void* userData)
{
wasm_memory* memory = (wasm_memory*)userData;
mem_base_allocator* allocator = mem_base_allocator_default();
mem_base_release(allocator, memory->ptr, memory->reserved);
memset(memory, 0, sizeof(wasm_memory));
}
extern u32 orca_mem_grow(u64 size)
{
orca_runtime* runtime = orca_runtime_get();
wasm_memory* memory = &runtime->wasmMemory;
size = AlignUpOnPow2(size, d_m3MemPageSize);
u64 totalSize = size + m3_GetMemorySize(runtime->m3Runtime);
u32 addr = memory->committed;
//NOTE: call resize memory, which will call our custom resize callback... this is a bit involved because
// wasm3 doesn't allow resizing the memory directly
M3Result res = ResizeMemory(runtime->m3Runtime, totalSize/d_m3MemPageSize);
return(addr);
}

72
src/orca_runtime.h Normal file
View File

@ -0,0 +1,72 @@
/************************************************************//**
*
* @file: orca_runtime.h
* @author: Martin Fouilleul
* @date: 17/04/2023
*
*****************************************************************/
#ifndef __ORCA_RUNTIME_H_
#define __ORCA_RUNTIME_H_
#include"wasm3.h"
#include"m3_env.h"
#include"m3_compile.h"
#define G_EVENTS(X) \
X(G_EVENT_START, "OnInit", "", "") \
X(G_EVENT_MOUSE_DOWN, "OnMouseDown", "", "i") \
X(G_EVENT_MOUSE_UP, "OnMouseUp", "", "i") \
X(G_EVENT_MOUSE_ENTER, "OnMouseEnter", "", "") \
X(G_EVENT_MOUSE_LEAVE, "OnMouseLeave", "", "") \
X(G_EVENT_MOUSE_MOVE, "OnMouseMove", "", "ffff") \
X(G_EVENT_MOUSE_WHEEL, "OnMouseWheel", "", "ff") \
X(G_EVENT_KEY_DOWN, "OnKeyDown", "", "i") \
X(G_EVENT_KEY_UP, "OnKeyUp", "", "i") \
X(G_EVENT_FRAME_REFRESH, "OnFrameRefresh", "", "") \
X(G_EVENT_FRAME_RESIZE, "OnFrameResize", "", "ii")
typedef enum {
#define G_EVENT_KIND(kind, ...) kind,
G_EVENTS(G_EVENT_KIND)
G_EVENT_COUNT
} guest_event_kind;
typedef struct g_event_handler_desc
{
str8 name;
str8 retTags;
str8 argTags;
} g_event_handler_desc;
const g_event_handler_desc G_EVENT_HANDLER_DESC[] = {
#define G_EVENT_HANDLER_DESC_ENTRY(kind, name, rets, args) {STR8(name), STR8(rets), STR8(args)},
G_EVENTS(G_EVENT_HANDLER_DESC_ENTRY)
};
typedef struct wasm_memory
{
char* ptr;
u64 reserved;
u64 committed;
} wasm_memory;
typedef struct orca_runtime
{
str8 wasmBytecode;
wasm_memory wasmMemory;
// wasm3 data
IM3Environment m3Env;
IM3Runtime m3Runtime;
IM3Module m3Module;
IM3Function eventHandlers[G_EVENT_COUNT];
} orca_runtime;
orca_runtime* orca_runtime_get();
#endif //__ORCA_RUNTIME_H_