--- /dev/null
+fork {
+ <<<"start">>>;
+ 12::samp => now;
+ me.test_cancel();
+ <<<"stop">>>;
+} @=> Fork @f;
+
+1 => f.cancel;
+2::samp => now;
+0 => f.cancel;
+f.join();
f_drvdel del;
} DriverData;
-/*
-struct SoundInfo_ {
- uint32_t sr;
- uint8_t in, out;
- m_str arg;
-};
-*/
typedef void (*f_bbqset)(struct DriverData_*);
typedef void (*f_bbqrun)(const struct VM_*);
+
typedef struct BBQ_ {
uint64_t pos;
m_float* in;
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(MemPool, 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 M_Object, const m_uint);
ANN void __release(const M_Object, const VM_Shred);
ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) { GWDEBUG_EXE
if(GET_FLAG(exp->m_func, member))
SET_FLAG(emit->code, member);
- if(exp->m_func->code) {
- const Instr p = emit_add_instr(emit, RegPushImm);
- p->m_val = (m_uint)exp->m_func->code;
- } else {
- const Instr p = emit_add_instr(emit, PushStaticCode);
- p->m_val = (m_uint)exp->m_func;
- }
- return emit_exp_call1(emit, exp->m_func);
+ return emit_exp_call(emit, exp);
}
ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
if(unary->code) {
const Instr spork = emit_add_instr(emit, is_spork ? SporkExp : ForkEnd);
spork->m_val = emit->code->stack_depth;
- emit_add_instr(emit, is_spork ? SporkEnd : ForkEnd);
+// emit_add_instr(emit, is_spork ? SporkEnd : ForkEnd);
} else {
const Func f = unary->exp->d.exp_call.m_func;
const m_uint size = f->def->stack_depth - (GET_FLAG(f, member) ? SZ_INT : 0);
compile_filename(gwion, (m_str)vector_at(v, i));
}
-
+#include "shreduler_private.h"
ANN VM* gwion_cpy(const VM* src) {
const Gwion gwion = mp_alloc(src->gwion->p, Gwion);
gwion->vm = new_vm(src->gwion->p);
gwion->vm->gwion = gwion;
+//gwion->vm->shreduler->bbq->is_running = 1;
gwion->vm->bbq->si = soundinfo_cpy(src->gwion->p, src->bbq->si);
gwion->emit = src->gwion->emit;
gwion->env = src->gwion->env;
gwion->p = mempool_ini((sizeof(VM_Shred) + SIZEOF_REG + SIZEOF_MEM) / SZ_INT);
gwion->st = new_symbol_table(gwion->p, 65347);
gwion->vm = new_vm(gwion->p);
+printf("non fork vm: %p\n", gwion->vm->shreduler);
gwion->emit = new_emitter();
gwion->env = new_env(gwion->p);
gwion->emit->env = gwion->env;
return o;
}
+M_Object gwion_new_string(const struct Gwion_ *gwion, const m_str str) {
+ const M_Object o = new_object(gwion->p, NULL, t_string);
+ STRING(o) = s_name(insert_symbol(gwion->st, str));
+ return o;
+}
+
ANN void instantiate_object(const VM_Shred shred, const Type type) {
-// const M_Object object = new_object(NULL, type);
const M_Object object = new_object(shred->info->mp, shred, type);
*(M_Object*)REG(0) = object;
PUSH_REG(shred, SZ_INT);
#include "shreduler_private.h"
#include "gwion.h"
-static m_int o_fork_thread, o_fork_retsize, o_fork_retval;
+static m_int o_fork_thread, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsize, o_fork_retval;
#define FORK_THREAD(o) *(THREAD_TYPE*)(o->data + o_fork_thread)
#define FORK_RETSIZE(o) *(m_int*)(o->data + o_fork_retsize)
#define FORK_RETVAL(o) (o->data + o_fork_retval)
const M_Object obj = new_object(shred->info->mp, NULL, is_spork ? t_shred : t_fork);
ME(obj) = shred;
if(!is_spork) {
-// *(M_Object*)(obj->data + o_fork_ev) = new_object(NULL, t_event);
-// EV_SHREDS(*(M_Object*)(obj->data + o_fork_ev)) = new_vector();
+ *(M_Object*)(obj->data + o_fork_ev) = new_object(shred->info->mp, NULL, t_event);
+ EV_SHREDS(*(M_Object*)(obj->data + o_fork_ev)) = new_vector(shred->info->mp);
}
return obj;
}
static SFUN(vm_shred_from_id) {
const m_int index = *(m_int*)MEM(0);
const VM_Shred s = (VM_Shred)vector_at(&shred->tick->shreduler->shreds, (vtype)index);
- if(s) {
+ if(s)
*(M_Object*)RETURN = s->info->me;
-// s->info->me->ref++;
-// vector_add(&shred->gc, (vtype) s->info->me);
- } else
+ else
*(m_uint*)RETURN = 0;
}
static DTOR(shred_dtor) { free_vm_shred(*(VM_Shred*)o->data); }
static DTOR(fork_dtor) {
+// pthread_detach(FORK_THREAD(o));
+ THREAD_JOIN(FORK_THREAD(o));
mp_free(shred->info->mp, Gwion, ME(o)->info->vm->gwion);
free_vm(ME(o)->info->vm);
}
static MFUN(fork_join) {
- /* int pret = */ THREAD_JOIN(FORK_THREAD(o));
- release(o, shred);
+ if(*(m_int*)(o->data + o_fork_done))
+ return;
+ shreduler_remove(shred->tick->shreduler, shred, 0);
+ vector_add(EV_SHREDS(*(M_Object*)(o->data + o_fork_ev)), (vtype)shred);
+}
+
+//static MFUN(shred_cancel) {
+// ++*(m_int*)(o->data + o_shred_cancel);
+//}
+
+static MFUN(shred_test_cancel) {
+ if(*(m_int*)(o->data + o_shred_cancel))
+ vm_shred_exit(ME(o));
}
void fork_retval(const M_Object o) {
}
static ANN void* fork_run(void* data) {
- M_Object me = (M_Object)data;
+ const M_Object me = (M_Object)data;
VM *vm = ME(me)->info->vm;
- vm_run(vm);
+ do {
+ vm_run(vm);
+ ++vm->bbq->pos;
+ } while(vm->bbq->is_running);
fork_retval(me);
+ *(m_int*)(me->data + o_fork_done) = 1;
+ broadcast(*(M_Object*)(me->data + o_fork_ev));
+ _release(me, ME(me));
THREAD_RETURN(NULL);
}
gwi_item_ini(gwi, "int", "@me");
CHECK_BB(gwi_item_end(gwi, ae_flag_member, NULL))
+ gwi_item_ini(gwi, "int", "cancel");
+ CHECK_BB((o_shred_cancel = gwi_item_end(gwi, 0, NULL)))
+
gwi_func_ini(gwi, "void", "exit", gw_shred_exit);
CHECK_BB(gwi_func_end(gwi, 0))
gwi_func_ini(gwi, "string", "code_dir", shred_code_dir);
CHECK_BB(gwi_func_end(gwi, 0))
+// gwi_func_ini(gwi, "void", "cancel", shred_cancel);
+// CHECK_BB(gwi_func_end(gwi, 0))
+ gwi_func_ini(gwi, "void", "test_cancel", shred_test_cancel);
+ CHECK_BB(gwi_func_end(gwi, 0))
CHECK_BB(gwi_class_end(gwi))
gwi_item_ini(gwi, "Shred", "me");
CHECK_BB(gwi_class_ini(gwi, t_fork, NULL, fork_dtor))
gwi_item_ini(gwi, "int", "@thread");
CHECK_BB((o_fork_thread = gwi_item_end(gwi, ae_flag_const, NULL)))
+ gwi_item_ini(gwi, "int", "is_done");
+ CHECK_BB((o_fork_done = gwi_item_end(gwi, ae_flag_const, NULL)))
+ gwi_item_ini(gwi, "Event", "ev");
+ CHECK_BB((o_fork_ev = gwi_item_end(gwi, ae_flag_const, NULL)))
gwi_item_ini(gwi, "int", "retsize");
CHECK_BB((o_fork_retsize = gwi_item_end(gwi, ae_flag_const, NULL)))
o_fork_retval = t_fork->nspc->info->offset;
Driver *bbq = s->bbq;
struct ShredTick_ *tk = s->list;
if(!tk) {
+//printf("here %p %lu\n", s, s->bbq->pos);
if(!vector_size(&s->shreds) && !s->loop)
bbq->is_running = 0;
return NULL;
ANN m_uint vm_fork(const VM* src, const VM_Shred shred) {
VM* vm = shred->info->vm = gwion_cpy(src);
shred->info->me = new_shred(shred, 0);
+// shreduler_add(vm->shreduler, shred);
+// shredule(vm->shreduler, shred, .5);
shreduler_add(vm->shreduler, shred);
shredule(vm->shreduler, shred, .5);
return shred->tick->xid;
__attribute__ ((optimize("-O2")))
ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto]
- static const void* dispatch[] = {
+//printf("here %p\n", vm->shreduler);
+static const void* dispatch[] = {
&®setimm,
&®pushimm, &®pushfloat, &®pushother, &®pushaddr,
&®pushmem, &®pushmemfloat, &®pushmemother, &®pushmemaddr,
// LOOP_OPTIM
for(m_uint i = 0; i <= instr->m_val2; i+= SZ_INT) {
m_uint* m0 = __builtin_assume_aligned((m_bit*)mem+i, SZ_INT);
-printf("%p\n", m0);
+//printf("%p\n", m0);
// m_uint* m = __builtin_assume_aligned((m_bit*)mem+instr->m_val+i, SZ_INT);
m_uint* r = __builtin_assume_aligned(reg+i, SZ_INT);
// *(m_uint*)(reg+i) = *(m_uint*)((m_bit*)(mem + instr->m_val) + i);
{
register const m_float f = *(m_float*)(reg-SZ_FLOAT);
*(m_float*)(reg-SZ_FLOAT) = (shred->tick->wake_time += f);
+//printf("here adv %p %lu\n", s, s->bbq->is_running);
shredule(s, shred, f);
+//printf("here adv %p %p %lu\n", shred->tick->shreduler, s, s->bbq->is_running);
}
shred->code = code;
shred->reg = reg;
pc = shred->pc;
DISPATCH()
} while(s->curr);
+//printf("no more curr %p\n", vm->shreduler);
#ifdef VMBENCH
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_end);
timespecsub(&exec_end, &exec_ini, &exec_ret);
#endif
return;
}
+if(vector_size(&vm->ugen))
vm_ugen_init(vm);
}
//#pragma GCC pop_options
\ No newline at end of file
GWION_IMPORT(global_var_test) {
// ALLOC_PTR(i, m_uint, 1);
- M_Object i = new_string(gwi->gwion->p, NULL, "test");
+ const M_Object i = gwion_new_string(gwi->gwion, "test");
CHECK_BB(gwi_item_ini(gwi,"string", "i"))
CHECK_BB(gwi_item_end(gwi, 0, i))
return GW_OK;
#include "gwi.h"
GWION_IMPORT(static_string_test) {
+ const M_Object obj = gwion_new_string(gwi->gwion, "test static string");
CHECK_BB(gwi_item_ini(gwi, "string", "self"))
- M_Object obj = new_string(gwi->gwion->p, NULL, "test static string");
- CHECK_BB(gwi_item_end(gwi, ae_flag_global, obj))
+// CHECK_BB(gwi_item_end(gwi, ae_flag_global, obj))
+ CHECK_BB(gwi_item_end(gwi, 0, obj))
return GW_OK;
}