coroutines on windows via fibers
parent
ba04801d6c
commit
f94151af2d
|
@ -254,6 +254,7 @@ extern "C"{
|
||||||
#define BUFFER_SEEK_DELIMITER_SIG(name) int name(void *cmd_context, Buffer_Summary *buffer, int start, char delim, int seek_forward, int *out)
|
#define BUFFER_SEEK_DELIMITER_SIG(name) int name(void *cmd_context, Buffer_Summary *buffer, int start, char delim, int seek_forward, int *out)
|
||||||
#define BUFFER_READ_RANGE_SIG(name) int name(void *cmd_context, Buffer_Summary *buffer, int start, int end, char *out)
|
#define BUFFER_READ_RANGE_SIG(name) int name(void *cmd_context, Buffer_Summary *buffer, int start, int end, char *out)
|
||||||
#define BUFFER_REPLACE_RANGE_SIG(name) int name(void *cmd_context, Buffer_Summary *buffer, int start, int end, char *str, int len)
|
#define BUFFER_REPLACE_RANGE_SIG(name) int name(void *cmd_context, Buffer_Summary *buffer, int start, int end, char *str, int len)
|
||||||
|
// TODO(allen): buffer save
|
||||||
|
|
||||||
// File view manipulation
|
// File view manipulation
|
||||||
#define GET_VIEW_MAX_INDEX_SIG(name) int name(void *cmd_context)
|
#define GET_VIEW_MAX_INDEX_SIG(name) int name(void *cmd_context)
|
||||||
|
|
2
4ed.cpp
2
4ed.cpp
|
@ -3280,7 +3280,7 @@ App_Init_Sig(app_init){
|
||||||
|
|
||||||
// NOTE(allen): file setup
|
// NOTE(allen): file setup
|
||||||
vars->working_set.file_index_count = 1;
|
vars->working_set.file_index_count = 1;
|
||||||
vars->working_set.file_max_count = 29;
|
vars->working_set.file_max_count = 120;
|
||||||
vars->working_set.files =
|
vars->working_set.files =
|
||||||
push_array(partition, Editing_File, vars->working_set.file_max_count);
|
push_array(partition, Editing_File, vars->working_set.file_max_count);
|
||||||
|
|
||||||
|
|
32
4ed_system.h
32
4ed_system.h
|
@ -61,6 +61,32 @@ typedef Sys_CLI_Update_Step_Sig(System_CLI_Update_Step);
|
||||||
#define Sys_CLI_End_Update_Sig(name) b32 name(CLI_Handles *cli)
|
#define Sys_CLI_End_Update_Sig(name) b32 name(CLI_Handles *cli)
|
||||||
typedef Sys_CLI_End_Update_Sig(System_CLI_End_Update);
|
typedef Sys_CLI_End_Update_Sig(System_CLI_End_Update);
|
||||||
|
|
||||||
|
// coroutine
|
||||||
|
|
||||||
|
#define Coroutine_Function_Sig(name) void name(struct Coroutine *coroutine)
|
||||||
|
typedef Coroutine_Function_Sig(Coroutine_Function);
|
||||||
|
|
||||||
|
struct Coroutine{
|
||||||
|
Plat_Handle plat_handle;
|
||||||
|
Coroutine_Function *func;
|
||||||
|
void *yield_handle;
|
||||||
|
void *in;
|
||||||
|
void *out;
|
||||||
|
i32 done;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define Sys_Launch_Coroutine_Sig(name) Coroutine *name(Coroutine_Function *func, void *in, void *out)
|
||||||
|
typedef Sys_Launch_Coroutine_Sig(System_Launch_Coroutine);
|
||||||
|
|
||||||
|
#define Sys_Resume_Coroutine_Sig(name) void name(Coroutine *coroutine, void *in, void *out)
|
||||||
|
typedef Sys_Resume_Coroutine_Sig(System_Resume_Coroutine);
|
||||||
|
|
||||||
|
#define Sys_Yield_Coroutine_Sig(name) void *name(Coroutine *coroutine)
|
||||||
|
typedef Sys_Yield_Coroutine_Sig(System_Yield_Coroutine);
|
||||||
|
|
||||||
|
#define Sys_Release_Coroutine_Sig(name) void name(Coroutine *coroutine)
|
||||||
|
typedef Sys_Release_Coroutine_Sig(System_Relase_Coroutine);
|
||||||
|
|
||||||
// thread
|
// thread
|
||||||
struct Thread_Context;
|
struct Thread_Context;
|
||||||
|
|
||||||
|
@ -171,6 +197,12 @@ struct System_Functions{
|
||||||
// time: 1
|
// time: 1
|
||||||
System_Time *time;
|
System_Time *time;
|
||||||
|
|
||||||
|
// coroutine: 4
|
||||||
|
System_Launch_Coroutine *launch_coroutine;
|
||||||
|
System_Resume_Coroutine *resume_coroutine;
|
||||||
|
System_Yield_Coroutine *yield_coroutine;
|
||||||
|
System_Relase_Coroutine *release_coroutine;
|
||||||
|
|
||||||
// cli: 4
|
// cli: 4
|
||||||
System_CLI_Call *cli_call;
|
System_CLI_Call *cli_call;
|
||||||
System_CLI_Begin_Update *cli_begin_update;
|
System_CLI_Begin_Update *cli_begin_update;
|
||||||
|
|
|
@ -433,10 +433,10 @@ buffer_seek_range_camel_left(Buffer_Type *buffer, int pos, int an_pos){
|
||||||
assert_4tech(an_pos <= pos);
|
assert_4tech(an_pos <= pos);
|
||||||
assert_4tech(0 <= an_pos);
|
assert_4tech(0 <= an_pos);
|
||||||
|
|
||||||
|
--pos;
|
||||||
loop = buffer_backify_loop(buffer, pos, an_pos+1);
|
loop = buffer_backify_loop(buffer, pos, an_pos+1);
|
||||||
if (buffer_backify_good(&loop)){
|
if (buffer_backify_good(&loop)){
|
||||||
prev_ch = loop.data[0];
|
prev_ch = loop.data[0];
|
||||||
--pos;
|
|
||||||
|
|
||||||
for (;buffer_backify_good(&loop);
|
for (;buffer_backify_good(&loop);
|
||||||
buffer_backify_next(&loop)){
|
buffer_backify_next(&loop)){
|
||||||
|
|
108
win32_4ed.cpp
108
win32_4ed.cpp
|
@ -99,6 +99,11 @@ struct Win32_Input_Chunk{
|
||||||
Win32_Input_Chunk_Persistent pers;
|
Win32_Input_Chunk_Persistent pers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Win32_Coroutine{
|
||||||
|
Coroutine coroutine;
|
||||||
|
Win32_Coroutine *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct Win32_Vars{
|
struct Win32_Vars{
|
||||||
HWND window_handle;
|
HWND window_handle;
|
||||||
HDC window_hdc;
|
HDC window_hdc;
|
||||||
|
@ -148,6 +153,12 @@ struct Win32_Vars{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Font_Load_System fnt;
|
Font_Load_System fnt;
|
||||||
|
|
||||||
|
// NOTE(allen): I don't expect to have many of these, but it pays
|
||||||
|
// to look a head a little so this is set up so that we can just bump
|
||||||
|
// it up if needed.
|
||||||
|
Win32_Coroutine coroutine_data[2];
|
||||||
|
Win32_Coroutine *coroutine_free;
|
||||||
};
|
};
|
||||||
|
|
||||||
globalvar Win32_Vars win32vars;
|
globalvar Win32_Vars win32vars;
|
||||||
|
@ -570,16 +581,22 @@ Win32Resize(i32 width, i32 height){
|
||||||
internal HANDLE
|
internal HANDLE
|
||||||
Win32Handle(Plat_Handle h){
|
Win32Handle(Plat_Handle h){
|
||||||
HANDLE result;
|
HANDLE result;
|
||||||
result = {};
|
memcpy(&result, &h, sizeof(result));
|
||||||
result = *(HANDLE*)(&h);
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void*
|
||||||
|
Win32Ptr(Plat_Handle h){
|
||||||
|
void *result;
|
||||||
|
memcpy(&result, &h, sizeof(result));
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Plat_Handle
|
internal Plat_Handle
|
||||||
Win32GenHandle(HANDLE h){
|
Win32GenHandle(HANDLE h){
|
||||||
Assert(sizeof(Plat_Handle) >= sizeof(HANDLE));
|
Plat_Handle result = {};
|
||||||
Plat_Handle result;
|
Assert(sizeof(Plat_Handle) >= sizeof(h));
|
||||||
result = *(Plat_Handle*)(&h);
|
memcpy(&result, &h, sizeof(h));
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,11 +722,11 @@ system_grow_thread_memory(Thread_Memory *memory){
|
||||||
old_data = memory->data;
|
old_data = memory->data;
|
||||||
old_size = memory->size;
|
old_size = memory->size;
|
||||||
new_size = LargeRoundUp(memory->size*2, Kbytes(4));
|
new_size = LargeRoundUp(memory->size*2, Kbytes(4));
|
||||||
memory->data = Win32GetMemory(new_size);
|
memory->data = system_get_memory(new_size);
|
||||||
memory->size = new_size;
|
memory->size = new_size;
|
||||||
if (old_data){
|
if (old_data){
|
||||||
memcpy(memory->data, old_data, old_size);
|
memcpy(memory->data, old_data, old_size);
|
||||||
Win32FreeMemory(old_data);
|
system_free_memory(old_data);
|
||||||
}
|
}
|
||||||
system_release_lock(CANCEL_LOCK0 + memory->id - 1);
|
system_release_lock(CANCEL_LOCK0 + memory->id - 1);
|
||||||
}
|
}
|
||||||
|
@ -730,6 +747,76 @@ INTERNAL_get_thread_states(Thread_Group_ID id, bool8 *running, i32 *pending){
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
internal Coroutine*
|
||||||
|
Win32AllocCoroutine(){
|
||||||
|
Win32_Coroutine *result = win32vars.coroutine_free;
|
||||||
|
Assert(result != 0);
|
||||||
|
win32vars.coroutine_free = result->next;
|
||||||
|
return(&result->coroutine);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Win32FreeCoroutine(Coroutine *coroutine){
|
||||||
|
Win32_Coroutine *data = (Win32_Coroutine*)coroutine;
|
||||||
|
data->next = win32vars.coroutine_free;
|
||||||
|
win32vars.coroutine_free = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Win32CoroutineMain(void *arg_){
|
||||||
|
Coroutine *coroutine = (Coroutine*)arg_;
|
||||||
|
coroutine->func(coroutine);
|
||||||
|
coroutine->done = 1;
|
||||||
|
SwitchToFiber(coroutine->yield_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
Sys_Launch_Coroutine_Sig(system_launch_coroutine){
|
||||||
|
Coroutine *coroutine;
|
||||||
|
void *fiber;
|
||||||
|
|
||||||
|
coroutine = Win32AllocCoroutine();
|
||||||
|
|
||||||
|
fiber = CreateFiber(0, Win32CoroutineMain, coroutine);
|
||||||
|
|
||||||
|
coroutine->plat_handle = Win32GenHandle(fiber);
|
||||||
|
coroutine->func = func;
|
||||||
|
coroutine->yield_handle = GetCurrentFiber();
|
||||||
|
coroutine->in = in;
|
||||||
|
coroutine->out = out;
|
||||||
|
coroutine->done = 0;
|
||||||
|
|
||||||
|
SwitchToFiber(fiber);
|
||||||
|
|
||||||
|
return(coroutine);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sys_Resume_Coroutine_Sig(system_resume_coroutine){
|
||||||
|
void *fiber;
|
||||||
|
|
||||||
|
Assert(coroutine->done == 0);
|
||||||
|
|
||||||
|
coroutine->yield_handle = GetCurrentFiber();
|
||||||
|
coroutine->in = in;
|
||||||
|
coroutine->out = out;
|
||||||
|
|
||||||
|
fiber = Win32Ptr(coroutine->plat_handle);
|
||||||
|
|
||||||
|
SwitchToFiber(fiber);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sys_Yield_Coroutine_Sig(system_yield_coroutine){
|
||||||
|
void *result;
|
||||||
|
SwitchToFiber(coroutine->yield_handle);
|
||||||
|
result = coroutine->in;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sys_Release_Coroutine_Sig(system_release_coroutine){
|
||||||
|
Assert(coroutine->done);
|
||||||
|
Win32FreeCoroutine(coroutine);
|
||||||
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
Sys_CLI_Call_Sig(system_cli_call){
|
Sys_CLI_Call_Sig(system_cli_call){
|
||||||
char cmd[] = "c:\\windows\\system32\\cmd.exe";
|
char cmd[] = "c:\\windows\\system32\\cmd.exe";
|
||||||
|
@ -947,6 +1034,11 @@ Win32LoadSystemCode(){
|
||||||
win32vars.system->post_clipboard = system_post_clipboard;
|
win32vars.system->post_clipboard = system_post_clipboard;
|
||||||
win32vars.system->time = system_time;
|
win32vars.system->time = system_time;
|
||||||
|
|
||||||
|
win32vars.system->launch_coroutine = system_launch_coroutine;
|
||||||
|
win32vars.system->resume_coroutine = system_resume_coroutine;
|
||||||
|
win32vars.system->yield_coroutine = system_yield_coroutine;
|
||||||
|
win32vars.system->release_coroutine = system_release_coroutine;
|
||||||
|
|
||||||
win32vars.system->cli_call = system_cli_call;
|
win32vars.system->cli_call = system_cli_call;
|
||||||
win32vars.system->cli_begin_update = system_cli_begin_update;
|
win32vars.system->cli_begin_update = system_cli_begin_update;
|
||||||
win32vars.system->cli_update_step = system_cli_update_step;
|
win32vars.system->cli_update_step = system_cli_update_step;
|
||||||
|
@ -1780,7 +1872,7 @@ main(int argc, char **argv){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
File_Slot file_slots[32];
|
File_Slot file_slots[120];
|
||||||
sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0);
|
sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0);
|
||||||
|
|
||||||
Font_Load_Parameters params[32];
|
Font_Load_Parameters params[32];
|
||||||
|
|
Loading…
Reference in New Issue