From 8f909348f15eb826e24f4a41221d2c328bb7fbd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kochma=C5=84ski?= Date: Sat, 14 Mar 2026 22:38:15 +0100 Subject: [PATCH] lwp: use si_pass to swtich context from both sides Add current continuation slot to process, and create the current process on demand. --- src/c/lwp.d | 60 ++++++++++++++++++++++-------------------- src/c/memory.d | 1 + src/c/threads/thread.d | 2 ++ src/h/object.h | 1 + 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/c/lwp.d b/src/c/lwp.d index 60f2f3bc5..f68f9a1ff 100644 --- a/src/c/lwp.d +++ b/src/c/lwp.d @@ -35,32 +35,31 @@ * * -------------------------------------------------------------------------- */ +static cl_object +ensure_cc(cl_env_ptr the_env) +{ + cl_object process = the_env->own_process; + cl_object cc = process->process.cont; + if(Null(cc)) { + cc = process->process.cont = si_make_continuation(ECL_NIL); + cc->cont.thread = si_make_thread(ECL_NIL); + } + return cc; +} + static void _lwp_entry(void) { const cl_env_ptr the_env = ecl_process_env(); cl_object process = the_env->own_process; - cl_object thread = process->process.function; /* kludge */ - cl_object cont = thread->thread.cont; - cl_object cc = si_make_continuation(ECL_NIL); + cl_object cc = process->process.cont; + cl_object thread = cc->cont.thread; - ucontext_t *top = &cc->cont.uc; - ucontext_t *sub = &cont->cont.uc; - - /* top = &ret; */ - /* own = top->uc_link; */ - printf("YYY this is an entry!\n"); ecl_print(@"ZZZ Hello!", ECL_T); - printf("YYY yield\n"); - thread->thread.cont = cc; - cc->cont.thread = thread; - ecl_set_process_env(cont->cont.env); - swapcontext(top, sub); - printf("YYY continue brrt!\n"); - ecl_print(@"ZZZ Bonjur!!", ECL_T); - printf("YYY return\n"); - ecl_set_process_env(cont->cont.env); - setcontext(&cont->cont.uc); + si_pass(thread->thread.cont); + ecl_print(@"ZZZ Bonjur!", ECL_T); + si_pass(thread->thread.cont); + ecl_print(@"ZZZ Salut!!", ECL_T); _ecl_unexpected_return(); } @@ -88,7 +87,6 @@ si_make_continuation(cl_object thread) cl_object cpu = the_env->own_process; char *stack = o->cont.stack; /* Configure the environment. */ - cpu->process.function = thread; /* kludge */ new_env->trap_fpe_bits = the_env->trap_fpe_bits; new_env->own_process = cpu; ecl_modules_init_env(new_env); @@ -107,23 +105,27 @@ cl_object si_pass(cl_object cont) { const cl_env_ptr the_env = ecl_process_env(); - cl_object cc = si_make_continuation(ECL_NIL);; + const cl_env_ptr new_env = cont->cont.env; + cl_object cc = ensure_cc(the_env); + cl_object process = new_env->own_process; cl_object thread = cont->cont.thread; + cl_object cc_thread = cc->cont.thread; ucontext_t *top, *sub; top = &cc->cont.uc; sub = &cont->cont.uc; - thread->thread.cont = cc; ecl_module_gc->module.disable(); - printf("XXX dispatch!\n"); - ecl_set_process_env(cont->cont.env); - swapcontext(top, sub); - printf("XXX returned!\n"); - ecl_module_gc->module.enable(); - printf("XXX finished!\n"); - ecl_return1(the_env, thread->thread.cont); + ecl_set_process_env(new_env); + process->process.cont = cont; + thread->thread.cont = cc; + swapcontext(top, sub); + + ecl_module_gc->module.enable(); + + ecl_return1(the_env, cc_thread->thread.cont); } /* (si:pass (si:make-continuation (si:make-thread nil))) */ +/* (si:pass (si:pass (si:make-continuation (si:make-thread nil)))) */ diff --git a/src/c/memory.d b/src/c/memory.d index 162e5a890..26f29ca19 100644 --- a/src/c/memory.d +++ b/src/c/memory.d @@ -244,6 +244,7 @@ init_type_info_database(void) to_bitmap(&o, &(o.process.name)) | to_bitmap(&o, &(o.process.function)) | to_bitmap(&o, &(o.process.args)) | + to_bitmap(&o, &(o.process.cont)) | to_bitmap(&o, &(o.process.inherit_bindings_p)) | to_bitmap(&o, &(o.process.exit_values)) | to_bitmap(&o, &(o.process.woken_up)) | diff --git a/src/c/threads/thread.d b/src/c/threads/thread.d index 2365adee4..b0f89b257 100644 --- a/src/c/threads/thread.d +++ b/src/c/threads/thread.d @@ -151,6 +151,7 @@ alloc_process(cl_object name, cl_object initial_bindings_p) process->process.name = name; process->process.function = ECL_NIL; process->process.args = ECL_NIL; + process->process.cont = ECL_NIL; process->process.woken_up = ECL_NIL; process->process.inherit_bindings_p = Null(initial_bindings_p)? ECL_T : ECL_NIL; ecl_disable_interrupts_env(env); @@ -498,6 +499,7 @@ create_thread() process->process.name = @'si::top-level'; process->process.function = ECL_NIL; process->process.args = ECL_NIL; + process->process.cont = ECL_NIL; process->process.env = the_env; ecl_mutex_init(&process->process.start_stop_lock, TRUE); ecl_cond_var_init(&process->process.exit_barrier); diff --git a/src/h/object.h b/src/h/object.h index ceec9cc48..126171e41 100644 --- a/src/h/object.h +++ b/src/h/object.h @@ -1124,6 +1124,7 @@ struct ecl_process { cl_object function; cl_objectfn entry; /* entry address (matches ecl_cfun offset) */ cl_object args; + cl_object cont; cl_object inherit_bindings_p; cl_object exit_values; cl_object woken_up;