From 76fc93745f88e4dfeaff005f49350f7ebab3eb4b Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Thu, 5 Dec 2019 20:20:11 +0100 Subject: [PATCH] :art: Improve forking --- include/object.h | 2 +- include/vm.h | 3 +++ src/gwion.c | 5 +++-- src/lib/shred.c | 44 ++++++++++++++++++++++++++++++++++---------- src/vm/vm.c | 6 +++--- 5 files changed, 44 insertions(+), 16 deletions(-) diff --git a/include/object.h b/include/object.h index cfc2e90f..00f76e7f 100644 --- a/include/object.h +++ b/include/object.h @@ -17,7 +17,7 @@ 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); -ANN void fork_launch(const VM*, const M_Object, const m_uint); +ANN void fork_launch(VM const*, const M_Object, const m_uint); 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/include/vm.h b/include/vm.h index 47fecd79..58996dd6 100644 --- a/include/vm.h +++ b/include/vm.h @@ -76,6 +76,9 @@ void free_vm_shred(const VM_Shred shred)__attribute__((hot, nonnull)); ANN void vm_run(const VM* vm) __attribute__((hot)); ANEW VM* new_vm(MemPool, const m_bool); +ANN void vm_lock(VM const*); +ANN void vm_unlock(VM const*); +ANN m_bool vm_running(VM const*); ANN void free_vm(VM* vm); ANN void vm_add_shred(const VM* vm, const VM_Shred shred)__attribute__((hot)); ANN void vm_remove(const VM* vm, const m_uint index)__attribute__((hot)); diff --git a/src/gwion.c b/src/gwion.c index 07937ae6..b59b1634 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -102,7 +102,7 @@ ANN void gwion_run(const Gwion gwion) { vm->bbq->driver->run(vm, vm->bbq); } -ANN static void gwion_end_child(const VM_Shred shred, const Gwion gwion); +ANN void gwion_end_child(const VM_Shred shred, const Gwion gwion); ANN static inline void free_gwion_cpy(const Gwion gwion, const VM_Shred shred) { gwion_end_child(shred, gwion); @@ -117,9 +117,10 @@ ANN static void fork_clean2(const VM_Shred shred, const Vector v) { free_gwion_cpy(gwion, shred); } vector_release(v); + v->ptr = NULL; } -ANN static void gwion_end_child(const VM_Shred shred, const Gwion gwion) { +ANN void gwion_end_child(const VM_Shred shred, const Gwion gwion) { if(gwion->data->child.ptr) fork_clean(shred, &gwion->data->child); if(gwion->data->child2.ptr) diff --git a/src/lib/shred.c b/src/lib/shred.c index 7f974516..95db9001 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -145,9 +145,24 @@ static MFUN(shred_unlock) { MUTEX_UNLOCK(ME(o)->tick->shreduler->mutex); } -static DTOR(fork_dtor) { +static void stop(const M_Object o) { + VM *vm = ME(o)->info->vm->parent; + MUTEX_LOCK(vm->shreduler->mutex); + vm->shreduler->bbq->is_running = 0; + MUTEX_UNLOCK(vm->shreduler->mutex); +} + +static void join(const M_Object o) { + VM *vm = ME(o)->info->vm->parent; + MUTEX_LOCK(vm->shreduler->mutex); THREAD_JOIN(FORK_THREAD(o)); - const VM *vm = ME(o)->info->vm->parent; + MUTEX_UNLOCK(vm->shreduler->mutex); + pthread_yield(); +} + +static DTOR(fork_dtor) { + stop(o); + VM *vm = ME(o)->info->vm->parent; if(*(m_int*)(o->data + o_fork_done)) { const m_int idx = vector_find(&vm->gwion->data->child, (vtype)o); VPTR(&vm->gwion->data->child, idx) = 0; @@ -155,6 +170,8 @@ static DTOR(fork_dtor) { vector_init(&vm->gwion->data->child2); vector_add(&vm->gwion->data->child2, (vtype)ME(o)->info->vm->gwion); } + gwion_end_child(ME(o)->info->vm->gwion, shred); + join(o); } static MFUN(fork_join) { @@ -197,12 +214,13 @@ void fork_retval(const M_Object o) { } static ANN void* fork_run(void* data) { - const M_Object me = (M_Object)data; - VM *vm = ME(me)->info->vm; - do { + VM *vm = (VM*)data; + const M_Object me = vm->shreduler->list->self->info->me; + while(vm->bbq->is_running) { +// while(vm_running(vm)) { vm_run(vm); ++vm->bbq->pos; - } while(vm->bbq->is_running); + } fork_retval(me); MUTEX_LOCK(vm->shreduler->mutex); *(m_int*)(me->data + o_fork_done) = 1; @@ -211,9 +229,13 @@ static ANN void* fork_run(void* data) { THREAD_RETURN(NULL); } -ANN void fork_launch(const VM* vm, const M_Object o, const m_uint sz) { - FORK_RETSIZE(o) = sz; - THREAD_CREATE(FORK_THREAD(o), fork_run, o); +ANN void fork_launch(VM const* vm, const M_Object o, const m_uint sz) { + vm_lock(vm); + if(vm_running(vm)) { + FORK_RETSIZE(o) = sz; + THREAD_CREATE(FORK_THREAD(o), fork_run, ME(o)->info->vm); + } + vm_unlock(vm); } ANN void fork_clean(const VM_Shred shred, const Vector v) { @@ -221,10 +243,12 @@ ANN void fork_clean(const VM_Shred shred, const Vector v) { const M_Object o = (M_Object)vector_at(v, i); if(!o) continue; + stop(o); THREAD_JOIN(FORK_THREAD(o)); - release(o, shred); + _release(o, shred); } vector_release(v); + v->ptr = NULL; } GWION_IMPORT(shred) { diff --git a/src/vm/vm.c b/src/vm/vm.c index 9c8c4acc..19a80654 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -68,17 +68,17 @@ ANN void vm_add_shred(const VM* vm, const VM_Shred shred) { shreduler_add(vm->shreduler, shred); } -ANN void vm_lock(VM *vm) { +ANN void vm_lock(VM const *vm) { do MUTEX_LOCK(vm->shreduler->mutex); while((vm = vm->parent)); } -ANN void vm_unlock(VM *vm) { +ANN void vm_unlock(VM const *vm) { do MUTEX_UNLOCK(vm->shreduler->mutex); while((vm = vm->parent)); } -ANN m_bool vm_running(VM *vm) { +ANN m_bool vm_running(VM const *vm) { if(!vm->shreduler->bbq->is_running) return 0; if(!vm->parent) -- 2.43.0