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);
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));
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);
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)
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;
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) {
}
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;
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) {
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) {
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)