}
ANN static void gwion_end_child(const VM_Shred shred, const Gwion gwion) {
- MUTEX_LOCK(gwion->vm->shreduler->mutex);
if(gwion->data->child.ptr)
fork_clean(shred, &gwion->data->child);
if(gwion->data->child2.ptr)
fork_clean2(shred, &gwion->data->child2);
- MUTEX_UNLOCK(gwion->vm->shreduler->mutex);
}
ANN void gwion_end(const Gwion gwion) {
}
ANN void fork_launch(const VM* vm, const M_Object o, const m_uint sz) {
- o->ref += 1;
- if(!vm->gwion->data->child.ptr)
- vector_init(&vm->gwion->data->child);
- vector_add(&vm->gwion->data->child, (vtype)o);
FORK_RETSIZE(o) = sz;
THREAD_CREATE(FORK_THREAD(o), fork_run, o);
}
shreduler_add(vm->shreduler, shred);
}
-#include "gwion.h"
+ANN void vm_lock(VM *vm) {
+ do MUTEX_LOCK(vm->shreduler->mutex);
+ while((vm = vm->parent));
+}
+
+ANN void vm_unlock(VM *vm) {
+ do MUTEX_UNLOCK(vm->shreduler->mutex);
+ while((vm = vm->parent));
+}
+
+ANN m_bool vm_running(VM *vm) {
+ do if(!vm->shreduler->bbq->is_running) return 0;
+ while((vm = vm->parent));
+ return 1;
+}
+
ANN static void vm_fork(VM* src, const VM_Shred shred) {
- VM* vm = (shred->info->vm = gwion_cpy(src));
- vm->parent = src;
- shred->info->me = new_shred(shred, 0);
- shreduler_add(vm->shreduler, shred);
+ vm_lock(src);
+ if(vm_running(src)) {
+ VM* vm = (shred->info->vm = gwion_cpy(src));
+ vm->parent = src;
+ const M_Object o = shred->info->me = new_shred(shred, 0);
+ ++shred->info->me->ref;
+ if(!src->gwion->data->child.ptr)
+ vector_init(&src->gwion->data->child);
+ vector_add(&src->gwion->data->child, (vtype)o);
+ shreduler_add(vm->shreduler, shred);
+ }
+ vm_unlock(src);
}
__attribute__((hot))