From 461abb4fd096aab19678f30815100ee9e4f66308 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Tue, 15 Oct 2019 01:36:26 +0200 Subject: [PATCH] :art: Improve fork --- include/gwiondata.h | 1 + include/object.h | 2 +- src/gwion.c | 16 ++++++++++++++-- src/lib/shred.c | 33 +++++++++++++++++---------------- src/main.c | 4 ---- 5 files changed, 33 insertions(+), 23 deletions(-) diff --git a/include/gwiondata.h b/include/gwiondata.h index c21a27ac..fdae6fa5 100644 --- a/include/gwiondata.h +++ b/include/gwiondata.h @@ -5,6 +5,7 @@ typedef struct GwionData_ { struct Map_ id; MUTEX_TYPE mutex; struct Vector_ child; + struct Vector_ child2; struct Vector_ reserved; struct Map_ pass_map; struct Vector_ pass; diff --git a/include/object.h b/include/object.h index da09c027..f2ae1e52 100644 --- a/include/object.h +++ b/include/object.h @@ -12,13 +12,13 @@ ANN void instantiate_object(const VM_Shred, const Type); ANN void free_object(MemPool p, const M_Object); ANEW M_Object new_object(MemPool, const VM_Shred, const Type); ANEW M_Object new_M_UGen(const struct Gwion_*); +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 gwion_new_string(const struct Gwion_*, const m_str); ANEW M_Object new_shred(const VM_Shred, const m_bool); ANN void fork_launch(const VM*, const M_Object, const m_uint); -ANN void fork_clean(const VM *vm, const Vector v); ANN void __release(const M_Object, const VM_Shred); ANN void exception(const VM_Shred, const m_str); ANN void broadcast(const M_Object); diff --git a/src/gwion.c b/src/gwion.c index 32d92a9b..05c3954b 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -62,7 +62,7 @@ ANN VM* gwion_cpy(const VM* src) { } ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) { - gwion->mp = mempool_ini((sizeof(VM_Shred) + SIZEOF_REG + SIZEOF_MEM) / SZ_INT); + gwion->mp = mempool_ini((sizeof(struct VM_Shred_) + SIZEOF_REG + SIZEOF_MEM)); gwion->st = new_symbol_table(gwion->mp, 65347); gwion->vm = new_vm(gwion->mp, 1); gwion->emit = new_emitter(gwion->mp); @@ -95,13 +95,25 @@ ANN void gwion_run(const Gwion gwion) { vm->bbq->driver->run(vm, vm->bbq); } +ANN static void fork_clean2(const Vector v) { + for(m_uint i = 0; i < vector_size(v); ++i) { + VM* vm = (VM*)vector_at(v, i); + const Gwion gwion = vm->gwion; + free_vm(vm); + mp_free(gwion->mp, Gwion, gwion); + } + vector_release(v); +} + ANN void gwion_end(const Gwion gwion) { const VM_Code code = new_vm_code(gwion->mp, NULL, 0, ae_flag_builtin, "in code dtor"); gwion->vm->cleaner_shred = new_vm_shred(gwion->mp, code); vm_add_shred(gwion->vm, gwion->vm->cleaner_shred); MUTEX_LOCK(gwion->vm->shreduler->mutex); if(gwion->data->child.ptr) - fork_clean(gwion->vm, &gwion->data->child); + fork_clean(gwion->vm->cleaner_shred, &gwion->data->child); + if(gwion->data->child2.ptr) + fork_clean2(&gwion->data->child2); MUTEX_UNLOCK(gwion->vm->shreduler->mutex); free_env(gwion->env); free_vm_shred(gwion->vm->cleaner_shred); diff --git a/src/lib/shred.c b/src/lib/shred.c index 85d2bb66..4e7b3148 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -154,12 +154,11 @@ static MFUN(shred_unlock) { } static DTOR(fork_dtor) { - if(*(m_int*)(o->data + o_fork_done)) - vector_rem2(&FORK_ORIG(o)->gwion->data->child, (vtype)o); THREAD_JOIN(FORK_THREAD(o)); - VM *vm = ME(o)->info->vm; - free_vm(vm); - mp_free(shred->info->mp, Gwion, vm->gwion); + if(*(m_int*)(o->data + o_fork_done)) { + vector_rem2(&FORK_ORIG(o)->gwion->data->child, (vtype)o); + vector_add(&FORK_ORIG(o)->gwion->data->child2, (vtype)ME(o)->info->vm); + } else exit(6); } static MFUN(fork_join) { @@ -216,25 +215,27 @@ static ANN void* fork_run(void* data) { THREAD_RETURN(NULL); } -ANN void fork_clean(const VM *vm, const Vector v) { - for(m_uint i = 0; i < vector_size(v); ++i) { - const M_Object o = (M_Object)vector_at(v, i); - THREAD_JOIN(FORK_THREAD(o)); - release(o, vm->cleaner_shred); - } - vector_release(v); -} - -void fork_launch(const VM* vm, const M_Object o, const m_uint sz) { +ANN void fork_launch(const VM* vm, const M_Object o, const m_uint sz) { o->ref += 1; - if(!vm->gwion->data->child.ptr) + if(!vm->gwion->data->child.ptr) { vector_init(&vm->gwion->data->child); + vector_init(&vm->gwion->data->child2); + } vector_add(&vm->gwion->data->child, (vtype)o); FORK_ORIG(o) = (VM*)vm; FORK_RETSIZE(o) = sz; THREAD_CREATE(FORK_THREAD(o), fork_run, o); } + +ANN void fork_clean(const VM_Shred shred, const Vector v) { + for(m_uint i = 0; i < vector_size(v); ++i) { + const M_Object o = (M_Object)vector_at(v, i); + THREAD_JOIN(FORK_THREAD(o)); + release(o, shred); + } + vector_release(v); +} #include "nspc.h" GWION_IMPORT(shred) { const Type t_shred = gwi_mk_type(gwi, "Shred", SZ_INT, "Object"); diff --git a/src/main.c b/src/main.c index 6331d3e5..72a3a22f 100644 --- a/src/main.c +++ b/src/main.c @@ -25,10 +25,6 @@ int main(int argc, char** argv) { arg_release(&arg); if(ini > 0) gwion_run(&gwion); -#ifndef NDEBUG gwion_end(&gwion); -#else - free_plug(&gwion); -#endif THREAD_RETURN(EXIT_SUCCESS); } -- 2.43.0