From 961da436f5694e63a99b63d45105a5dae8bd00d8 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Mon, 25 Sep 2023 10:39:32 +0200 Subject: [PATCH] :art: more threadpools --- include/arg.h | 2 + include/dict.h | 6 ++ include/env/type.h | 53 +++++++++-------- include/env/value.h | 3 +- include/gwion.h | 8 +++ include/gwiondata.h | 5 +- include/import.h | 18 +++--- include/shreduler_private.h | 2 +- include/vm.h | 2 +- src/arg.c | 12 ++++ src/compile.c | 9 ++- src/gwion.c | 2 +- src/gwiondata.c | 10 +++- src/import/import_prim.c | 1 + src/lib/closure.c | 7 ++- src/lib/dict.c | 5 +- src/lib/shred.c | 115 +++++++++++++++++------------------- src/main.c | 7 ++- src/vm/shreduler.c | 26 ++++---- src/vm/vm.c | 8 +-- src/vm/vm_shred.c | 4 +- 21 files changed, 173 insertions(+), 132 deletions(-) diff --git a/include/arg.h b/include/arg.h index 04cb1f57..d550620e 100644 --- a/include/arg.h +++ b/include/arg.h @@ -17,6 +17,8 @@ typedef struct CliArg_ { char** (*config_args)(int*, char**); void (*embed_libs)(Gwion); void (*embed_scripts)(Gwion); + uint32_t thread_count; + uint32_t queue_size; bool loop; bool quit; bool urc; diff --git a/include/dict.h b/include/dict.h index 84e830a9..ab6556df 100644 --- a/include/dict.h +++ b/include/dict.h @@ -19,4 +19,10 @@ typedef struct HMapInfo { m_uint sz; } HMapInfo; +ANN static inline void dict_alloc(MemPool mp, const M_Object o, const m_uint sz, const m_uint capacity) { + HMap *hmap = &*(struct HMap*)o->data; + hmap->data = (m_bit*)mp_calloc2(mp, sz * capacity); + hmap->state = (m_bit*)mp_calloc2(mp, sizeof(HState) * capacity); + hmap->capacity = capacity; +} #endif diff --git a/include/env/type.h b/include/env/type.h index d2cf0f41..32278ef1 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -17,32 +17,33 @@ struct TypeInfo_ { }; enum tflag { - tflag_none = 1 << 0, - tflag_scan0 = 1 << 1, // - tflag_scan1 = 1 << 2, // - tflag_scan2 = 1 << 3, // - tflag_check = 1 << 4, // - tflag_emit = 1 << 5, // - tflag_infer = 1 << 6, - tflag_empty = 1 << 7, - tflag_ftmpl = 1 << 8, - tflag_ntmpl = 1 << 9, // do NOT need types - tflag_udef = 1 << 10, - tflag_cdef = 1 << 11, - tflag_struct = 1 << 12, - tflag_ctor = 1 << 13, - tflag_dtor = 1 << 14, - tflag_tmpl = 1 << 15, - tflag_typedef = 1 << 16, - tflag_distinct = 1 << 17, - tflag_noret = 1 << 18, - tflag_contract = 1 << 19, - tflag_float = 1 << 20, - tflag_union = 1 << 21, - tflag_ref = 1 << 22, - tflag_packed = 1 << 23, - tflag_compound = 1 << 24, - tflag_release = 1 << 25, // mark structs that need release + tflag_none = 1 << 0, + tflag_scan0 = 1 << 1, // + tflag_scan1 = 1 << 2, // + tflag_scan2 = 1 << 3, // + tflag_check = 1 << 4, // + tflag_emit = 1 << 5, // + tflag_infer = 1 << 6, + tflag_empty = 1 << 7, + tflag_ftmpl = 1 << 8, + tflag_ntmpl = 1 << 9, // do NOT need types + tflag_udef = 1 << 10, + tflag_cdef = 1 << 11, + tflag_struct = 1 << 12, + tflag_ctor = 1 << 13, + tflag_dtor = 1 << 14, + tflag_tmpl = 1 << 15, + tflag_typedef = 1 << 16, + tflag_distinct = 1 << 17, + tflag_noret = 1 << 18, + tflag_contract = 1 << 19, + tflag_float = 1 << 20, + tflag_union = 1 << 21, + tflag_ref = 1 << 22, + tflag_packed = 1 << 23, + tflag_compound = 1 << 24, + tflag_release = 1 << 25, // mark structs that need release + tflag_primitive = 1 << 26, // mark structs that need release } __attribute__((packed)); struct Type_ { diff --git a/include/env/value.h b/include/env/value.h index 9e6c91b7..47ae58fd 100644 --- a/include/env/value.h +++ b/include/env/value.h @@ -49,7 +49,8 @@ ANN void valuefrom(const Env, ValueFrom *); ANN static inline void defined_here(const Value v) { if (v->from->filename) {// TODO: check why is that from check - char c[256] = {[255] = '\0'}; + char c[256]; + c[255] = '\0'; snprintf(c, 256, _("%.*s defined here"), 240, v->name); gwerr_secondary(c, v->from->filename, v->from->loc); } diff --git a/include/gwion.h b/include/gwion.h index 4f854245..7e6ec227 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -42,4 +42,12 @@ type_class(const Gwion gwion, const Type t) { ANN void gwion_set_debug(const Gwion gwion, const bool dbg); ANN void gwion_set_dump(const Gwion gwion, const bool dump); ANN void gwion_set_cdoc(const Gwion gwion, const bool dbg); + + +ANN static inline void shred_pool_run(const VM_Shred shred, void (*fun)(void*), void *arg) { + shreduler_remove(shred->tick->shreduler, shred, false); + threadpool_add(shred->info->vm->gwion->data->tpool, fun, arg); +} + + #endif diff --git a/include/gwiondata.h b/include/gwiondata.h index 3b0f3856..fec1d4e2 100644 --- a/include/gwiondata.h +++ b/include/gwiondata.h @@ -9,16 +9,17 @@ typedef struct Plugs { typedef struct GwionData_ { struct Map_ freearg; struct Map_ id; - MUTEX_TYPE mutex; + gwtlock_t mutex; struct Vector_ child; struct Vector_ child2; struct Passes_ *passes; Plugs *plugs; + threadpool_t *tpool; bool cdoc; bool errored; } GwionData; -ANN GwionData *new_gwiondata(const MemPool); +ANN GwionData *new_gwiondata(const MemPool, const uint32_t thread_count, const uint32_t queue_size); ANN GwionData *cpy_gwiondata(MemPool, const GwionData *); ANN void free_gwiondata(const Gwion); ANN void free_gwiondata_cpy(const MemPool, GwionData *); diff --git a/include/import.h b/include/import.h index ae35ef84..45b0fa40 100644 --- a/include/import.h +++ b/include/import.h @@ -1,28 +1,28 @@ #ifndef __IMPORT #define __IMPORT -typedef void (*f_xtor)(const M_Object, const m_bit *, const VM_Shred); -typedef void (*f_mfun)(const M_Object, const m_bit *, const VM_Shred); -typedef void (*f_sfun)(const m_bit *, const m_bit *, const VM_Shred); -typedef void (*f_gack)(const Type, const m_bit *, const VM_Shred); +typedef void (*f_xtor)(const M_Object, m_bit *const, const VM_Shred); +typedef void (*f_mfun)(const M_Object, m_bit *const, const VM_Shred); +typedef void (*f_sfun)(const m_bit *, m_bit *const, const VM_Shred); +typedef void (*f_gack)(const Type, m_bit *const, const VM_Shred); typedef void (*f_xfun)(); typedef struct Gwi_ *Gwi; #define MFUN(a) \ - ANN void a(const M_Object o NUSED, const m_bit *RETURN NUSED, \ + ANN void a(const M_Object o NUSED, m_bit *const RETURN NUSED, \ const VM_Shred shred NUSED) #define SFUN(a) \ - ANN void a(const M_Object o NUSED, const m_bit *RETURN NUSED, \ + ANN void a(const M_Object o NUSED, m_bit *const RETURN NUSED, \ const VM_Shred shred NUSED) #define CTOR(a) \ - ANN void a(const M_Object o NUSED, const m_bit *_ NUSED, \ + ANN void a(const M_Object o NUSED, m_bit *const _ NUSED, \ const VM_Shred shred NUSED) #define DTOR(a) \ - ANN void a(const M_Object o NUSED, const m_bit *_ NUSED, \ + ANN void a(const M_Object o NUSED, m_bit *const _ NUSED, \ const VM_Shred shred NUSED) #define GACK(a) \ ANN2(2) \ - void a(const Type t NUSED, const m_bit *VALUE NUSED, \ + void a(const Type t NUSED, m_bit *const VALUE NUSED, \ const VM_Shred shred NUSED) #define OP_CHECK(a) ANN Type a(const Env env NUSED, void *data NUSED) #define OP_EMIT(a) ANN m_bool a(const Emitter emit NUSED, void *data NUSED) diff --git a/include/shreduler_private.h b/include/shreduler_private.h index 9ba32f35..50e4b582 100644 --- a/include/shreduler_private.h +++ b/include/shreduler_private.h @@ -5,7 +5,7 @@ struct Shreduler_ { struct ShredTick_ *list; struct ShredTick_ *curr; struct Vector_ active_shreds; - MUTEX_TYPE mutex; + gwtlock_t mutex; size_t shred_ids; bool loop; }; diff --git a/include/vm.h b/include/vm.h index c1a7597a..d8632a67 100644 --- a/include/vm.h +++ b/include/vm.h @@ -89,7 +89,7 @@ struct VM_Shred_ { size_t pc; struct ShredTick_ *tick; struct ShredInfo_ *info; - MUTEX_TYPE mutex; + gwtlock_t mutex; }; REF_FUNC(VM_Code, vmcode) ANN2(1, 4) diff --git a/src/arg.c b/src/arg.c index 21c40d68..163ecd35 100644 --- a/src/arg.c +++ b/src/arg.c @@ -32,6 +32,8 @@ enum { DEBUG, DUMP, CDOC, + THREAD, + QUEUE, NOPTIONS }; @@ -208,6 +210,10 @@ static void setup_options(cmdapp_t *app, cmdopt_t *opt) { &opt[DUMP]); cmdapp_set(app, 'H', "cdoc", CMDOPT_MAYTAKEARG, NULL, "set/unset cdoc mode", "bool", &opt[CDOC]); + cmdapp_set(app, 't', "thread_count", CMDOPT_TAKESARG, NULL, "set number of threads", "integer", + &opt[THREAD]); + cmdapp_set(app, 'q', "queue_size", CMDOPT_TAKESARG, NULL, "set threadpool queue_size", "integer", + &opt[QUEUE]); } static inline void add2arg(CliArg *const arg, const char *data, @@ -338,6 +344,12 @@ static void myproc(void *data, cmdopt_t *option, const char *arg) { case 'H': get_cdoc(arg_int->gwion, option->value); break; + case 't': + _arg->thread_count = (uint32_t)ARG2INT(option->value); + break; + case 'q': + _arg->queue_size = (uint32_t)ARG2INT(option->value); + break; } } } diff --git a/src/compile.c b/src/compile.c index 145ebeb9..8eb79d32 100644 --- a/src/compile.c +++ b/src/compile.c @@ -99,7 +99,10 @@ ANN static inline m_bool _passes(struct Gwion_ *gwion, struct Compiler *c) { for (m_uint i = 0; i < vector_size(&gwion->data->passes->vec); ++i) { const compilation_pass pass = (compilation_pass)vector_at(&gwion->data->passes->vec, i); - CHECK_BB(pass(gwion->env, &c->ast)); + if(pass(gwion->env, &c->ast) < 0) { + gwion->data->errored = true; + return GW_ERROR; + } } return GW_OK; } @@ -160,9 +163,9 @@ ANN static m_uint _compile(struct Gwion_ *gwion, struct Compiler *c) { ANN static m_uint compile(struct Gwion_ *gwion, struct Compiler *c) { compiler_name(c); - MUTEX_LOCK(gwion->data->mutex); + gwt_lock(&gwion->data->mutex); const m_uint ret = _compile(gwion, c); - MUTEX_UNLOCK(gwion->data->mutex); + gwt_unlock(&gwion->data->mutex); compiler_clean(c); return ret; } diff --git a/src/gwion.c b/src/gwion.c index 26a9b6a0..b685f967 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -113,7 +113,7 @@ ANN m_bool gwion_ini(const Gwion gwion, CliArg *arg) { gwion->ppa = mp_calloc(gwion->mp, PPArg); pparg_ini(gwion->mp, gwion->ppa); gwion_core(gwion); - gwion->data = new_gwiondata(gwion->mp); + gwion->data = new_gwiondata(gwion->mp, arg->thread_count, arg->queue_size); gwion->type = (Type *)xcalloc(MAX_TYPE, sizeof(struct Type_ *)); arg->si = gwion->vm->bbq->si = new_soundinfo(gwion->mp); new_passes(gwion); diff --git a/src/gwiondata.c b/src/gwiondata.c index 4f6694bb..a9bebdbd 100644 --- a/src/gwiondata.c +++ b/src/gwiondata.c @@ -12,14 +12,16 @@ ANN static inline GwionData *gwiondata(MemPool mp) { struct GwionData_ *data = mp_calloc(mp, GwionData); - MUTEX_SETUP(data->mutex); + gwt_lock_ini(&data->mutex); // init lock return data; } -ANN GwionData *new_gwiondata(const MemPool mp) { +ANN GwionData *new_gwiondata(const MemPool mp, const uint32_t thread_count, + const uint32_t queue_size) { GwionData *data = gwiondata(mp); map_init(&data->freearg); map_init(&data->id); + data->tpool = new_threadpool(thread_count, queue_size); return data; } @@ -29,11 +31,12 @@ ANN GwionData *cpy_gwiondata(MemPool mp, const GwionData *src) { data->id = src->id; data->plugs = src->plugs; data->passes = src->passes; + data->tpool = src->tpool; return data; } ANN void free_gwiondata_cpy(const MemPool mp, GwionData *data) { - MUTEX_CLEANUP(data->mutex); + gwt_lock_end(&data->mutex); mp_free(mp, GwionData, data); } @@ -44,5 +47,6 @@ ANN void free_gwiondata(const Gwion gwion) { mp_free(gwion->mp, SpecialId, (struct SpecialId_ *)map_at(&data->id, i)); map_release(&data->id); free_passes(gwion->mp, data->passes); + free_threadpool(data->tpool); free_gwiondata_cpy(gwion->mp, data); } diff --git a/src/import/import_prim.c b/src/import/import_prim.c index 7678ae01..e648492d 100644 --- a/src/import/import_prim.c +++ b/src/import/import_prim.c @@ -199,6 +199,7 @@ ANN Type mk_primitive(const Env env, const m_str name, const m_uint size) { const Type t = new_type(env->gwion->mp, name, NULL); t->size = sz; t->actual_size = size; + set_tflag(t, tflag_primitive); scan_prim_op(env, t); scan_prim_op2(env, t); if(size < SZ_INT) { diff --git a/src/lib/closure.c b/src/lib/closure.c index b3922f78..73e5b3d9 100644 --- a/src/lib/closure.c +++ b/src/lib/closure.c @@ -382,6 +382,7 @@ ANN static Type partial2auto(const Env env, const Exp_Binary *bin) { const Type actual = fdef->base->func->value_ref->type; set_fbflag(fdef->base, fbflag_lambda); Var_Decl vd = bin->rhs->d.exp_decl.vd; +exp_setvar(bin->rhs, true); return vd.value->type = bin->rhs->type = bin->rhs->d.exp_decl.type = actual; } @@ -393,10 +394,14 @@ static OP_CHECK(opck_auto_fptr) { ERR_N(bin->lhs->pos, "invalid {G+}function{0} {+}:=>{0} {+G}function{0} assignment"); if (bin->lhs->exp_type == ae_exp_td) ERR_N(bin->lhs->pos, "can't use {/}type decl expressions{0} in auto function pointer declarations"); - if(!bin->lhs->type->info->func) +// if(!bin->lhs->type->info->func) + if(!bin->lhs->type->info->func || !strncmp(bin->lhs->type->name, "partial:", 8)) return partial2auto(env, bin); + // create a matching signature // TODO: we could check first if there a matching existing one + // we can maybe add it to the lhs type function namespace + // would make it easy enough to search Func_Base *const fbase = cpy_func_base(env->gwion->mp, bin->lhs->type->info->func->def->base); const Fptr_Def fptr_def = new_fptr_def(env->gwion->mp, fbase); diff --git a/src/lib/dict.c b/src/lib/dict.c index a111dbcd..9d5ba6a5 100644 --- a/src/lib/dict.c +++ b/src/lib/dict.c @@ -65,10 +65,7 @@ INSTR(dict_ctor_alt) { const Type t = (Type)instr->m_val2; const M_Object o = new_object(shred->info->mp, t); const HMapInfo *hinfo = (HMapInfo*)t->nspc->class_data; - HMap *a = &*(struct HMap*)o->data; - a->data = (m_bit*)mp_calloc2(shred->info->mp, hinfo->sz * instr->m_val); - a->state = (m_bit*)mp_calloc2(shred->info->mp, sizeof(HState) * instr->m_val); - a->capacity = instr->m_val; + dict_alloc(shred->info->mp, o, hinfo->sz, instr->m_val); shred->reg += SZ_INT; *(M_Object*)REG(-SZ_INT) = o; } diff --git a/src/lib/shred.c b/src/lib/shred.c index b9927140..006f45f9 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -156,22 +156,30 @@ static DTOR(shred_dtor) { free_vm_shred(s); } -static MFUN(shred_lock) { if(ME(o)->tick) MUTEX_LOCK(ME(o)->mutex); } +static MFUN(shred_lock) { if(ME(o)->tick) gwt_lock(&ME(o)->mutex); } -static MFUN(shred_unlock) { if(ME(o)->tick) MUTEX_UNLOCK(ME(o)->mutex); } +static MFUN(shred_unlock) { if(ME(o)->tick) gwt_unlock(&ME(o)->mutex); } static void stop(const M_Object o) { VM *vm = ME(o)->info->vm; - MUTEX_LOCK(vm->shreduler->mutex); - MUTEX_LOCK(ME(o)->mutex); + gwt_lock(&vm->shreduler->mutex); + gwt_lock(&ME(o)->mutex); vm->shreduler->bbq->is_running = 0; *(m_int *)(o->data + o_shred_cancel) = 1; - MUTEX_UNLOCK(ME(o)->mutex); - MUTEX_UNLOCK(vm->shreduler->mutex); + *(m_int *)(o->data + o_fork_done) = 1; + gwt_unlock(&ME(o)->mutex); + gwt_unlock(&vm->shreduler->mutex); } static inline void join(const M_Object o) { +// if(!ME(o)) return; +// gwt_lock(&ME(o)->mutex); +// const bool done = !*(m_int *)(o->data + o_fork_done); +// gwt_unlock(&ME(o)->mutex); +//// if (!*(m_int *)(o->data + o_fork_done)) { if (FORK_THREAD(o)) { +// if (!done) { +// *(m_int *)(o->data + o_fork_done) = 1; THREAD_JOIN(FORK_THREAD(o)); FORK_THREAD(o) = 0; } @@ -179,15 +187,12 @@ static inline void join(const M_Object o) { static DTOR(fork_dtor) { VM *parent = ME(o)->info->vm->parent; -// MUTEX_LOCK(parent->shreduler->mutex); - MUTEX_LOCK(ME(o)->mutex); + gwt_lock(&ME(o)->mutex); *(m_int *)(o->data + o_fork_done) = 1; - MUTEX_UNLOCK(ME(o)->mutex); + gwt_unlock(&ME(o)->mutex); stop(o); join(o); -// MUTEX_UNLOCK(parent->shreduler->mutex); - MUTEX_LOCK(parent->shreduler->mutex); -// MUTEX_LOCK(ME(o)->mutex); + gwt_lock(&parent->shreduler->mutex); if (parent->gwion->data->child.ptr) { const m_int idx = vector_find(&parent->gwion->data->child, (vtype)o); if (idx > -1) VPTR(&parent->gwion->data->child, idx) = 0; @@ -195,8 +200,7 @@ static DTOR(fork_dtor) { if (!parent->gwion->data->child2.ptr) vector_init(&parent->gwion->data->child2); vector_add(&parent->gwion->data->child2, (vtype)ME(o)->info->vm->gwion); -// MUTEX_UNLOCK(ME(o)->mutex); - MUTEX_UNLOCK(parent->shreduler->mutex); + gwt_unlock(&parent->shreduler->mutex); vmcode_remref(ME(o)->code, ME(o)->info->vm->gwion); } @@ -210,41 +214,37 @@ static MFUN(fork_join) { static MFUN(shred_cancel) { if(!ME(o)->tick)return; -// vm_lock(ME(o)->info->vm); - MUTEX_LOCK(ME(o)->mutex); + gwt_lock(&ME(o)->mutex); *(m_int *)(o->data + o_shred_cancel) = *(m_int *)MEM(SZ_INT); - MUTEX_UNLOCK(ME(o)->mutex); -// vm_unlock(ME(o)->info->vm); + gwt_unlock(&ME(o)->mutex); } static MFUN(shred_test_cancel) { - MUTEX_LOCK(ME(o)->mutex); + gwt_lock(&ME(o)->mutex); if (*(m_int *)(o->data + o_shred_cancel)) { - MUTEX_UNLOCK(ME(o)->mutex); + gwt_unlock(&ME(o)->mutex); vm_shred_exit(ME(o)); - } else - MUTEX_UNLOCK(ME(o)->mutex); + } else gwt_unlock(&ME(o)->mutex); } static MFUN(fork_test_cancel) { VM *parent = ME(o)->info->vm; - MUTEX_LOCK(parent->shreduler->mutex); + gwt_lock(&parent->shreduler->mutex); if (*(m_int *)(o->data + o_shred_cancel)) { - MUTEX_UNLOCK(parent->shreduler->mutex); + gwt_unlock(&parent->shreduler->mutex); stop(o); join(o); _release(o, ME(o)); vm_shred_exit(ME(o)); - } else - MUTEX_UNLOCK(parent->shreduler->mutex); + } else gwt_unlock(&parent->shreduler->mutex); } static MFUN(shred_now) { VM *vm = ME(o)->info->vm; while (vm->parent) vm = vm->parent; - MUTEX_LOCK(vm->shreduler->mutex); + gwt_lock(&vm->shreduler->mutex); *(m_float *)RETURN = vm->bbq->pos; - MUTEX_UNLOCK(vm->shreduler->mutex); + gwt_unlock(&vm->shreduler->mutex); } static MFUN(shred_blackhole) { @@ -257,69 +257,64 @@ static MFUN(shred_blackhole) { } struct ThreadLauncher { - MUTEX_TYPE mutex; - THREAD_COND_TYPE cond; + gwtlock_t *mutex; + gwtcond_t *cond; VM * vm; }; static inline int fork_running(VM *vm, const M_Object o) { - MUTEX_LOCK(ME(o)->mutex); + gwt_lock(&ME(o)->mutex); const int cancel = *(m_int *)(o->data + o_shred_cancel); - MUTEX_UNLOCK(ME(o)->mutex); + gwt_unlock(&ME(o)->mutex); if(cancel)return false; - MUTEX_LOCK(vm->shreduler->mutex); + gwt_lock(&vm->shreduler->mutex); const int ret = vm->bbq->is_running; - MUTEX_UNLOCK(vm->shreduler->mutex); + gwt_unlock(&vm->shreduler->mutex); return ret; } static ANN THREAD_FUNC(fork_run) { struct ThreadLauncher *tl = data; VM * vm = tl->vm; - MUTEX_TYPE mutex = tl->mutex; + gwtlock_t * mutex = tl->mutex; const M_Object me = vm->shreduler->list->self->info->me; - MUTEX_COND_LOCK(mutex); - THREAD_COND_SIGNAL(tl->cond); - MUTEX_COND_UNLOCK(mutex); -// THREAD_COND_CLEANUP(tl->cond); -// MUTEX_CLEANUP(tl->mutex); + gwt_lock(mutex); + gwt_signal(tl->cond); + gwt_unlock(mutex); while (fork_running(vm, me)) { vm_run_audio(vm); ++vm->bbq->pos; } gwion_end_child(ME(me), vm->gwion); -vm_lock(vm); -// MUTEX_LOCK(vm->shreduler->mutex); -// MUTEX_LOCK(vm->parent->shreduler->mutex); - MUTEX_LOCK(ME(me)->mutex); + vm_lock(vm); + gwt_lock(&ME(me)->mutex); if (!*(m_int *)(me->data + o_shred_cancel) && me->type_ref != vm->gwion->type[et_fork]) memcpy(me->data + vm->gwion->type[et_fork]->nspc->offset, ME(me)->reg, ((Type)vector_front(&me->type_ref->info->tuple->types))->size); *(m_int *)(me->data + o_fork_done) = 1; - MUTEX_UNLOCK(ME(me)->mutex); + gwt_unlock(&ME(me)->mutex); if (!*(m_int *)(me->data + o_shred_cancel)) broadcast(*(M_Object *)(me->data + o_fork_ev)); -vm_unlock(vm); -// MUTEX_UNLOCK(vm->parent->shreduler->mutex); -// MUTEX_UNLOCK(vm->shreduler->mutex); + vm_unlock(vm); THREAD_RETURN(0); } ANN void fork_launch(const M_Object o) { - MUTEX_TYPE mutex; - MUTEX_SETUP(mutex); - THREAD_COND_TYPE cond; - THREAD_COND_SETUP(cond); + gwtlock_t mutex; + gwt_lock_ini(&mutex); + gwtcond_t cond; + gwt_cond_ini(&cond); struct ThreadLauncher tl = { - .mutex = mutex, .cond = cond, .vm = ME(o)->info->vm}; + .mutex = &mutex, .cond = &cond, .vm = ME(o)->info->vm}; ++o->ref; - MUTEX_COND_LOCK(mutex); - THREAD_CREATE(FORK_THREAD(o), fork_run, &tl); - THREAD_COND_WAIT(cond, mutex); - MUTEX_COND_UNLOCK(mutex); - THREAD_COND_CLEANUP(cond); - MUTEX_CLEANUP(mutex); + gwt_lock(&mutex); +// THREAD_CREATE(FORK_THREAD(o), fork_run, &tl); + gwt_create(&FORK_THREAD(o), fork_run, &tl); + gwt_wait(&cond, &mutex); + gwt_unlock(&mutex); + gwt_cond_end(&cond); + gwt_lock_end(&mutex); } ANN void fork_clean(const VM_Shred shred, const Vector v) { @@ -422,7 +417,7 @@ GWION_IMPORT(shred) { gwi_class_xtor(gwi, NULL, fork_dtor); gwi->gwion->type[et_fork] = t_fork; o_fork_thread = t_fork->nspc->offset; - t_fork->nspc->offset += SZ_INT; + t_fork->nspc->offset += sizeof(gwtthread_t*); gwi_item_ini(gwi, "int", "is_done"); GWI_BB((o_fork_done = gwi_item_end(gwi, ae_flag_const, num, 0))) diff --git a/src/main.c b/src/main.c index 66a0ff70..9b5aa648 100644 --- a/src/main.c +++ b/src/main.c @@ -34,7 +34,10 @@ static void afl_run(const Gwion gwion) { } int main(int argc, char **argv) { - Arg arg = {}; + Arg arg = { + .thread_count = 4, + .queue_size = 16 + }; gwion_ini(&gwion, &arg); arg_release(&arg); afl_run(&gwion); @@ -84,6 +87,8 @@ int main(int argc, char **argv) { .config_args = gwion_config_args, .embed_libs = gwion_embed_libs, .embed_scripts = gwion_embed_scripts, + .thread_count = 4, + .queue_size = 16 }; const m_bool ini = gwion_ini(&gwion, &arg); arg_release(&arg); diff --git a/src/vm/shreduler.c b/src/vm/shreduler.c index 42ed83db..06e15aaa 100644 --- a/src/vm/shreduler.c +++ b/src/vm/shreduler.c @@ -13,7 +13,7 @@ ANN void shreduler_set_loop(const Shreduler s, const bool loop) { } ANN VM_Shred shreduler_get(const Shreduler s) { - MUTEX_LOCK(s->mutex); + gwt_lock(&s->mutex); Driver *const bbq = s->bbq; struct ShredTick_ *const tk = s->list; if (tk) { @@ -22,12 +22,12 @@ ANN VM_Shred shreduler_get(const Shreduler s) { if ((s->list = tk->next)) s->list->prev = NULL; tk->next = tk->prev = NULL; s->curr = tk; - MUTEX_UNLOCK(s->mutex); + gwt_unlock(&s->mutex); return tk->self; } } if (!s->loop && !vector_size(&s->active_shreds)) bbq->is_running = 0; - MUTEX_UNLOCK(s->mutex); + gwt_unlock(&s->mutex); return NULL; } @@ -53,9 +53,9 @@ ANN static void shreduler_erase(const Shreduler s, struct ShredTick_ *const tk) { const VM_Shred shred = tk->self; if (tk->child.ptr) child(s, &tk->child); - MUTEX_LOCK(shred->mutex); + gwt_lock(&shred->mutex); tk->prev = (struct ShredTick_*)-1; - MUTEX_UNLOCK(shred->mutex); + gwt_unlock(&shred->mutex); const m_uint size = shred->info->frame.ptr ? vector_size(&shred->info->frame) : 0; if(size) unwind(shred, (Symbol)-1, size); @@ -65,7 +65,7 @@ ANN static void shreduler_erase(const Shreduler s, ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const bool erase) { - MUTEX_LOCK(s->mutex); + gwt_lock(&s->mutex); struct ShredTick_ *const tk = out->tick; tk_remove(s, tk); if (likely(!erase)) tk->prev = tk->next = NULL; @@ -73,7 +73,7 @@ ANN void shreduler_remove(const Shreduler s, const VM_Shred out, if (tk->parent) vector_rem2(&tk->parent->child, (vtype)out); shreduler_erase(s, tk); } - MUTEX_UNLOCK(s->mutex); + gwt_unlock(&s->mutex); } ANN static void _shredule(const Shreduler s, struct ShredTick_ *tk, @@ -102,9 +102,9 @@ ANN static void _shredule(const Shreduler s, struct ShredTick_ *tk, ANN void shredule(const Shreduler s, const VM_Shred shred, const m_float wake_time) { struct ShredTick_ *tk = shred->tick; - MUTEX_LOCK(s->mutex); + gwt_lock(&s->mutex); _shredule(s, tk, wake_time); - MUTEX_UNLOCK(s->mutex); + gwt_unlock(&s->mutex); } ANN void shreduler_ini(const Shreduler s, const VM_Shred shred) { @@ -116,21 +116,21 @@ ANN void shreduler_ini(const Shreduler s, const VM_Shred shred) { ANN void shreduler_add(const Shreduler s, const VM_Shred shred) { shreduler_ini(s, shred); shred->tick->xid = ++s->shred_ids; - MUTEX_LOCK(s->mutex); + gwt_lock(&s->mutex); vector_add(&s->active_shreds, (vtype)shred); _shredule(s, shred->tick, GWION_EPSILON); - MUTEX_UNLOCK(s->mutex); + gwt_unlock(&s->mutex); } ANN Shreduler new_shreduler(const MemPool mp) { Shreduler s = (Shreduler)mp_calloc(mp, Shreduler); vector_init(&s->active_shreds); - MUTEX_SETUP(s->mutex); + gwt_lock_ini(&s->mutex); return s; } ANN void free_shreduler(const MemPool mp, const Shreduler s) { vector_release(&s->active_shreds); - MUTEX_CLEANUP(s->mutex); + gwt_lock_end(&s->mutex); mp_free(mp, Shreduler, s); } diff --git a/src/vm/vm.c b/src/vm/vm.c index 07f8fc5f..0b85d57b 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -201,11 +201,11 @@ ANN void vm_ini_shred(const VM *vm, const VM_Shred shred) { ANN void vm_lock(VM const *vm) { if (vm->parent) vm_lock(vm->parent); - MUTEX_LOCK(vm->shreduler->mutex); + gwt_lock(&vm->shreduler->mutex); } ANN void vm_unlock(VM const *vm) { - do MUTEX_UNLOCK(vm->shreduler->mutex); + do gwt_unlock(&vm->shreduler->mutex); while ((vm = vm->parent)); } @@ -1626,7 +1626,7 @@ return; // remove me ANN void next_bbq_pos(const VM *vm) { Driver *const di = vm->bbq; - MUTEX_LOCK(vm->shreduler->mutex); + gwt_lock(&vm->shreduler->mutex); if(++di->pos == 16777216-1) { const Vector v = &vm->shreduler->active_shreds; for(m_uint i = 0; i < vector_size(v); i++) { @@ -1635,7 +1635,7 @@ ANN void next_bbq_pos(const VM *vm) { } di->pos = 0; } - MUTEX_UNLOCK(vm->shreduler->mutex); + gwt_unlock(&vm->shreduler->mutex); } ANN void vm_run_audio(const VM *vm) { diff --git a/src/vm/vm_shred.c b/src/vm/vm_shred.c index 61e1c1a1..4a196a31 100644 --- a/src/vm/vm_shred.c +++ b/src/vm/vm_shred.c @@ -36,7 +36,7 @@ VM_Shred new_vm_shred(MemPool p, VM_Code c) { shred->reg = (m_bit *)shred + sizeof(struct VM_Shred_); shred->base = shred->mem = shred->reg + SIZEOF_REG; shred->info = new_shredinfo(p, c); - MUTEX_SETUP(shred->mutex); + gwt_lock_ini(&shred->mutex); return shred; } @@ -47,6 +47,6 @@ void free_vm_shred(VM_Shred shred) { const MemPool mp = shred->info->mp; mp_free(mp, ShredTick, shred->tick); free_shredinfo(mp, shred->info); - MUTEX_CLEANUP(shred->mutex); + gwt_lock_end(&shred->mutex); mp_free(mp, Stack, shred); } -- 2.43.0