From 732a90388d0a0f3826f5435a9fad4c7276e53b1c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Thu, 10 Sep 2020 19:52:25 +0200 Subject: [PATCH] :art: Improve forks --- include/object.h | 2 +- src/emit/emit.c | 3 +++ src/lib/func.c | 6 +----- src/lib/shred.c | 31 ++++++++++++++++++++++++------- src/vm/vm.c | 29 +++++++++++++---------------- 5 files changed, 42 insertions(+), 29 deletions(-) diff --git a/include/object.h b/include/object.h index c065c9fd..8b7d688a 100644 --- a/include/object.h +++ b/include/object.h @@ -16,7 +16,7 @@ ANN void fork_clean(const VM_Shred, const Vector); ANN ANEW M_Object new_array(MemPool, const Type t, const m_uint length); ANEW M_Object new_string(MemPool, const VM_Shred, const m_str); ANEW M_Object new_string2(const struct Gwion_*, const VM_Shred, const m_str); -ANEW M_Object new_shred(const VM_Shred, const m_bool); +ANEW M_Object new_shred(const VM_Shred); ANN void fork_launch(const M_Object, const m_uint); ANN void __release(const M_Object, const VM_Shred); ANN void exception(const VM_Shred, const m_str); diff --git a/src/emit/emit.c b/src/emit/emit.c index 67614f56..dcb4b580 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1179,6 +1179,7 @@ struct Sporker { const Stmt code; const Exp exp; VM_Code vm_code; + const Type type; const m_bool emit_var; const m_bool is_spork; }; @@ -1240,6 +1241,7 @@ ANN static Instr spork_ini(const Emitter emit, const struct Sporker *sp) { instr->m_val2 = sp->is_spork; return instr; } + regpushi(emit, (m_uint)sp->type); const Func f = !sp->code ? sp->exp->d.exp_call.m_func : NULL; const Instr instr = emit_add_instr(emit, ForkIni); instr->m_val = (m_uint)sp->vm_code; @@ -1251,6 +1253,7 @@ ANN Instr emit_exp_spork(const Emitter emit, const Exp_Unary* unary) { struct Sporker sporker = { .exp=unary->exp, .code=unary->code, + .type=exp_self(unary)->info->type, .is_spork=(unary->op == insert_symbol("spork")), .emit_var=exp_getvar(exp_self(unary)) }; diff --git a/src/lib/func.c b/src/lib/func.c index 8c0516d0..e1f3479b 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -315,11 +315,7 @@ static OP_CHECK(opck_spork) { static OP_EMIT(opem_spork) { const Exp_Unary* unary = (Exp_Unary*)data; - const Env env = emit->env; - const Instr ret = emit_exp_spork(emit, unary); - if(unary->op == insert_symbol("fork")) - emit_add_instr(emit, GcAdd); - return ret; + return emit_exp_spork(emit, unary); } static FREEARG(freearg_xork) { diff --git a/src/lib/shred.c b/src/lib/shred.c index 88375f8e..1c067f23 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -28,17 +28,34 @@ VM_Shred new_shred_base(const VM_Shred shred, const VM_Code code) { return sh; } -M_Object new_shred(const VM_Shred shred, m_bool is_spork) { +M_Object new_shred(const VM_Shred shred) { const M_Object obj = new_object(shred->info->mp, NULL, - shred->info->vm->gwion->type[is_spork ? et_shred :et_fork]); + shred->info->vm->gwion->type[et_shred]); ME(obj) = shred; - if(!is_spork) { - *(M_Object*)(obj->data + o_fork_ev) = new_object(shred->info->mp, NULL, shred->info->vm->gwion->type[et_event]); - EV_SHREDS(*(M_Object*)(obj->data + o_fork_ev)) = new_vector(shred->info->mp); - } return obj; } +ANN static inline M_Object fork_object(const VM_Shred shred, const Type t) { + const Gwion gwion = shred->info->vm->gwion; + const M_Object o = new_object(gwion->mp, shred, t); + *(M_Object*)(o->data + o_fork_ev) = new_object(gwion->mp, NULL, gwion->type[et_event]); + EV_SHREDS(*(M_Object*)(o->data + o_fork_ev)) = new_vector(gwion->mp); + return o; +} + +ANN M_Object new_fork(const VM_Shred shred, const VM_Code code, const Type t) { + VM* parent = shred->info->vm; + const VM_Shred sh = new_shred_base(shred, code); + VM* vm = (sh->info->vm = gwion_cpy(parent)); + vm->parent = parent; + const M_Object o = sh->info->me = fork_object(shred, t); + ME(o) = sh; + ++o->ref; + shreduler_add(vm->shreduler, sh); + return o; +} + + static MFUN(gw_shred_exit) { const VM_Shred s = ME(o); s->mem -= SZ_INT; @@ -296,7 +313,6 @@ ANN void fork_clean(const VM_Shred shred, const Vector v) { GWION_IMPORT(shred) { const Type t_shred = gwi_class_ini(gwi, "Shred", NULL); gwi_class_xtor(gwi, NULL, shred_dtor); - gwi->gwion->type[et_shred] = t_shred; gwi_item_ini(gwi, "@internal", "@me"); GWI_BB(gwi_item_end(gwi, ae_flag_const, NULL)) @@ -360,6 +376,7 @@ GWION_IMPORT(shred) { gwi_func_ini(gwi, "float", "get_now"); GWI_BB(gwi_func_end(gwi, shred_now, ae_flag_none)) GWI_BB(gwi_class_end(gwi)) + gwi_set_global_type(gwi, t_shred, et_shred); struct SpecialId_ spid = { .type=t_shred, .exec=RegPushMe, .is_const=1 }; gwi_specialid(gwi, "me", &spid); diff --git a/src/vm/vm.c b/src/vm/vm.c index 3e4d3490..b967991a 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -62,13 +62,13 @@ ANN void free_vm(VM* vm) { ANN void vm_add_shred(const VM* vm, const VM_Shred shred) { shred->info->vm = (VM*)vm; - shred->info->me = new_shred(shred, 1); + shred->info->me = new_shred(shred); shreduler_add(vm->shreduler, shred); } ANN void vm_ini_shred(const VM* vm, const VM_Shred shred) { shred->info->vm = (VM*)vm; - shred->info->me = new_shred(shred, 1); + shred->info->me = new_shred(shred); shreduler_ini(vm->shreduler, shred); } @@ -132,19 +132,15 @@ ANN static inline VM_Shred init_spork_shred(const VM_Shred shred, const VM_Code return sh; } -ANN static VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code, const m_uint retsz) { - VM* parent = shred->info->vm; - const VM_Shred sh = new_shred_base(shred, code); - VM* vm = (sh->info->vm = gwion_cpy(parent)); - vm->parent = parent; - const M_Object o = sh->info->me = new_shred(sh, 0); - ++sh->info->me->ref; - if(!parent->gwion->data->child.ptr) - vector_init(&parent->gwion->data->child); - vector_add(&parent->gwion->data->child, (vtype)o); - shreduler_add(vm->shreduler, sh); - fork_launch(sh->info->me, retsz); - return sh; +ANN M_Object new_fork(const VM_Shred, const VM_Code code, const Type); +ANN static VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code, const Type t, const m_uint retsz) { + const M_Object o = new_fork(shred, code, t); + VM* vm = shred->info->vm; + if(!vm->gwion->data->child.ptr) + vector_init(&vm->gwion->data->child); + vector_add(&vm->gwion->data->child, (vtype)o); + fork_launch(o, retsz); + return ME(o); } #define TEST0(t, pos) if(!*(t*)(reg-pos)){ shred->pc = PC; exception(shred, "ZeroDivideException"); break; } @@ -669,7 +665,8 @@ sporkini: child = init_spork_shred(shred, (VM_Code)VAL); DISPATCH() forkini: - child = init_fork_shred(shred, (VM_Code)VAL, VAL2), + reg -= SZ_INT; + child = init_fork_shred(shred, (VM_Code)VAL, *(Type*)reg, VAL2), DISPATCH() sporkfunc: // LOOP_OPTIM -- 2.43.0