]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve forking
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Thu, 5 Dec 2019 19:20:11 +0000 (20:20 +0100)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Thu, 5 Dec 2019 19:20:11 +0000 (20:20 +0100)
include/object.h
include/vm.h
src/gwion.c
src/lib/shred.c
src/vm/vm.c

index cfc2e90f7affa90f5f494890dfcc27fe15c67129..00f76e7fa6dacb97524f993ba7cff8d436a49bf8 100644 (file)
@@ -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);
index 47fecd79963b9b20970fad11fb871358da7d029e..58996dd6e3d6f9ed6bcfeede2136ceea8763505f 100644 (file)
@@ -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));
index 07937ae6e3ef584eb7691504c9e7304188e4246e..b59b16343f6cee29b62a93885f71914221079d1e 100644 (file)
@@ -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)
index 7f974516f517fd769b3f057f948493bcf0bec330..95db9001bbedd69966c021cab9e6f0a94dabcd57 100644 (file)
@@ -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) {
index 9c8c4acce4d509e3f210bfec9e06541fdf5f040a..19a806541a60f8f3369d8ecd1b8e59bab4d765bd 100644 (file)
@@ -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)