]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve forks
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Thu, 10 Sep 2020 17:52:25 +0000 (19:52 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Thu, 10 Sep 2020 17:52:25 +0000 (19:52 +0200)
include/object.h
src/emit/emit.c
src/lib/func.c
src/lib/shred.c
src/vm/vm.c

index c065c9fdefb09c046308ff2a8c2fe557fc656182..8b7d688a4121fa043bce720de84ab47d241161b3 100644 (file)
@@ -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);
index 67614f56ddbafeddcac467878bc7309283c5214d..dcb4b58094864aa3d251ded124099ddd79ecde08 100644 (file)
@@ -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))
   };
index 8c0516d05c500a312f79bf6c317b4eb2f86a242d..e1f3479b89a97f6c76b524cbae578279364a40b8 100644 (file)
@@ -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) {
index 88375f8eff63fed805e77968c79e51ce73f342ac..1c067f237d16d31dbe95f69fc32e2ac129ddaa6d 100644 (file)
@@ -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);
index 3e4d34903c60ca5dcd992f45ffad0ff1c28940a9..b967991a9e469699818cf4ec972da9dc40eef18d 100644 (file)
@@ -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