From f51fbd1a33f582da282140d684aeef040815b862 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Fri, 16 Aug 2019 15:29:36 +0000 Subject: [PATCH] added the vm_setsig vm primitive function to improve os signal handler changed System>>__os_signal_handelr and System>>startup for improved os signal handling --- moo/README.md | 25 ++++++++++++++++++++----- moo/kernel/Except.moo | 2 +- moo/kernel/Process.moo | 2 +- moo/kernel/System.moo | 32 +++++++++++++++++++------------- moo/lib/exec.c | 9 +++++---- moo/lib/gc.c | 2 +- moo/lib/moo-prv.h | 1 + moo/lib/moo.h | 11 ++++++++--- moo/lib/pf-sys.c | 18 ++++++++++++++++++ moo/lib/std.c | 14 +++++++++++++- 10 files changed, 87 insertions(+), 29 deletions(-) diff --git a/moo/README.md b/moo/README.md index bad09d5..3d13f47 100644 --- a/moo/README.md +++ b/moo/README.md @@ -215,9 +215,24 @@ what looks better as a shorthand expression for block value? ``` ffi := FFI new: 'libc.so.6'. - (ffi call: #printf signature: 's|sl>i' arguments: #("[%s ffi test %ld]\n" "sloppy" 12345678)) dump. - (ffi call: #printf signature: 's>i' arguments: #("[%% ffi test %%]\n")) dump. - (ffi call: #puts signature: 's>i' arguments: #("this is ffi test")) dump. - (ffi call: #time signature: 'p>l' arguments: #(#\p0)) dump. - ffi close. + [ + (ffi call: #printf signature: 's|sl>i' arguments: #("[%s ffi test %ld]\n" "sloppy" 12345678)) dump. + (ffi call: #printf signature: 's>i' arguments: #("[%% ffi test %%]\n")) dump. + (ffi call: #puts signature: 's>i' arguments: #("this is ffi test")) dump. + (ffi call: #time signature: 'p>l' arguments: #(#\p0)) dump. + ] + ensure: [ + ffi close. + ]. ``` + + + + +### Command line options + +``` +moo --log /dev/stderr ../kernel/test-001.moo +moo --log /dev/stderr,warn+ ../kernel/test-001.moo +``` + diff --git a/moo/kernel/Except.moo b/moo/kernel/Except.moo index 5334bf0..4f5d2db 100644 --- a/moo/kernel/Except.moo +++ b/moo/kernel/Except.moo @@ -161,7 +161,7 @@ extend Context // ------------------------------------------------------------------- // <> // private: called by VM upon unwinding as well as by - // Exception<>signal, Error>>signal, Process>>terminate // ------------------------------------------------------------------- | ctx stop eb pending_pos | diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 5c96d63..f2077e3 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -414,7 +414,7 @@ class SemaphoreHeap(Object) class(#final,#limited) ProcessScheduler(Object) { - var(#get) active, should_exit := false, total_count := 0. + var(#get) active, gcfin_should_exit := false, total_count := 0. var(#get) runnable_count := 0. var runnable_head, runnable_tail. var(#get) suspended_count := 0. diff --git a/moo/kernel/System.moo b/moo/kernel/System.moo index 36fedad..11f1853 100644 --- a/moo/kernel/System.moo +++ b/moo/kernel/System.moo @@ -55,11 +55,13 @@ class System(Apex) // start the gc finalizer process [ self __gc_finalizer ] fork. - [ self __os_sig_handler ] fork. + //[ self __os_sig_handler ] fork. + [ :caller | self __os_sig_handler: caller ] newProcess(thisProcess) resume. // TODO: change the method signature to variadic and pass extra arguments to perform??? ret := class perform: method_name. + self _setSig: 16rFF. //// System logNl: '======= END of startup ==============='. ^ret. } @@ -87,7 +89,7 @@ class System(Apex) }. //if (Processor total_count == 1) - if (Processor should_exit) + if (Processor gcfin_should_exit) { // exit from this loop when there are no other processes running except this finalizer process if (gc) @@ -113,9 +115,9 @@ class System(Apex) ]. } - method(#class) __os_sig_handler + method(#class) __os_sig_handler: caller { - | os_intr_sem tmp | + | os_intr_sem tmp terminate_process| os_intr_sem := Semaphore new. os_intr_sem signalOnInput: System _getSigfd. @@ -129,26 +131,30 @@ class System(Apex) //TODO: Execute Handler for tmp. System logNl: 'Interrupt dectected - signal no - ' & tmp asString. - if (tmp == 2) { /* TODO: terminate all processes??? */ }. - }. - - if (Processor should_exit) - { - System logNl: 'Exiting os interrupt handling process ' & (thisProcess id) asString. - break. + if (tmp == 16rFF or tmp == 2) { /* TODO: terminate all processes??? */ goto done }. }. os_intr_sem wait. - } + }. + done: + nil. ] ensure: [ os_intr_sem unsignal. - System logNl: 'End of OS signal handler process ' & (thisProcess id) asString. + + System logNl: '>>>>Requesting to terminate the caller process ' & (caller id) asString. + // the caller must request to terminate all its child processes.. + // TODO: to avoid this, this process must enumerate all proceses and terminate them. + caller terminate. + + System logNl: '>>>>End of OS signal handler process ' & (thisProcess id) asString. ]. } method(#class,#primitive) _getSig. method(#class,#primitive) _getSigfd. + method(#class,#primitive) _setSig: signo. + method(#class,#primitive) _popCollectable. method(#class,#primitive) collectGarbage. method(#class,#primitive) gc. diff --git a/moo/lib/exec.c b/moo/lib/exec.c index d8b55c6..8f70339 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -2180,7 +2180,7 @@ static moo_pfrc_t pf_context_find_exception_handler (moo_t* moo, moo_mod_t* mod, MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_method_context); except_class = (moo_oop_class_t)MOO_STACK_GETARG(moo, nargs, 0); - MOO_PF_CHECK_ARGS (moo, nargs, MOO_CLASSOF(moo,rcv) == moo->_class); + MOO_PF_CHECK_ARGS (moo, nargs, MOO_CLASSOF(moo,except_class) == moo->_class); preamble = MOO_OOP_TO_SMOOI(((moo_oop_method_t)rcv->method_or_nargs)->preamble); if (MOO_METHOD_GET_PREAMBLE_CODE(preamble) == MOO_METHOD_PREAMBLE_EXCEPTION) @@ -4189,6 +4189,7 @@ static pf_t pftab[] = { "System_putUint64", { moo_pf_system_put_uint64, 3, 3 } }, { "System_putUint8", { moo_pf_system_put_uint8, 3, 3 } }, { "System_return:to:", { pf_system_return_value_to_context, 2, 2 } }, + { "System_setSig:", { moo_pf_system_set_sig, 1, 1 } }, { "_dump", { pf_dump, 0, MA } }, @@ -4621,10 +4622,10 @@ static int send_message (moo_t* moo, moo_oop_char_t selector, moo_ooi_t nargs, i /* this must not happen as long as doesNotUnderstand: is implemented under Apex. * this check should indicate a very serious internal problem */ MOO_LOG4 (moo, MOO_LOG_IC | MOO_LOG_FATAL, - "Fatal error - unable to find a fallback method [%O<<%.*js] for receiver [%O]\n", + "Fatal error - unable to find a fallback method [%O>>%.*js] for receiver [%O]\n", MOO_CLASSOF(moo, receiver), MOO_OBJ_GET_SIZE(moo->does_not_understand_sym), MOO_OBJ_GET_CHAR_SLOT(moo->does_not_understand_sym), receiver); - moo_seterrbfmt (moo, MOO_EMSGSND, "unable to find a fallback method - %O<<%.*js", + moo_seterrbfmt (moo, MOO_EMSGSND, "unable to find a fallback method - %O>>%.*js", MOO_CLASSOF(moo, receiver), MOO_OBJ_GET_SIZE(moo->does_not_understand_sym), MOO_OBJ_GET_CHAR_SLOT(moo->does_not_understand_sym)); return -1; } @@ -4825,7 +4826,7 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo) { MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE)); MOO_ASSERT (moo, proc == moo->processor->runnable.first); - moo->processor->should_exit = moo->_true; /* prepare to inform the gc finalizer process */ + moo->processor->gcfin_should_exit = moo->_true; /* prepare to inform the gc finalizer process */ switch_to_process_from_nil (moo, proc); /* sechedule the gc finalizer process */ } } diff --git a/moo/lib/gc.c b/moo/lib/gc.c index f7c6183..2065735 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -552,7 +552,7 @@ static int ignite_2 (moo_t* moo) if (!tmp) return -1; moo->processor = (moo_oop_process_scheduler_t)tmp; moo->processor->active = moo->nil_process; - moo->processor->should_exit = moo->_false; + moo->processor->gcfin_should_exit = moo->_false; moo->processor->total_count = MOO_SMOOI_TO_OOP(0); moo->processor->runnable.count = MOO_SMOOI_TO_OOP(0); moo->processor->suspended.count = MOO_SMOOI_TO_OOP(0); diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index c30a412..0869807 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -1628,6 +1628,7 @@ moo_pfrc_t moo_pf_system_pop_collectable (moo_t* moo, moo_mod_t* mod, moo_ooi_t moo_pfrc_t moo_pf_system_get_sigfd (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs); moo_pfrc_t moo_pf_system_get_sig (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs); +moo_pfrc_t moo_pf_system_set_sig (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs); moo_pfrc_t moo_pf_system_malloc (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs); moo_pfrc_t moo_pf_system_calloc (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs); diff --git a/moo/lib/moo.h b/moo/lib/moo.h index d8b8bfb..bfa068b 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -873,7 +873,7 @@ struct moo_process_scheduler_t { MOO_OBJ_HEADER; moo_oop_process_t active; /* pointer to an active process in the runnable process list */ - moo_oop_t should_exit; /* Boolean */ + moo_oop_t gcfin_should_exit; /* Boolean */ moo_oop_t total_count; /* SmallIntger, total number of processes - runnable/running/suspended */ struct @@ -1216,6 +1216,11 @@ typedef int (*moo_vmprim_getsig_t) ( moo_uint8_t* sig ); +typedef int (*moo_vmprim_setsig_t) ( + moo_t* moo, + moo_uint8_t sig +); + struct moo_vmprim_t { moo_alloc_heap_t alloc_heap; @@ -1243,6 +1248,7 @@ struct moo_vmprim_t moo_vmprim_getsigfd_t vm_getsigfd; moo_vmprim_getsig_t vm_getsig; + moo_vmprim_setsig_t vm_setsig; }; typedef struct moo_vmprim_t moo_vmprim_t; @@ -1578,8 +1584,7 @@ struct moo_t moo_oop_char_t does_not_understand_sym; /* symbol doesNotUnderstand: */ moo_oop_char_t primitive_failed_sym; /* symbol primitiveFailed */ moo_oop_char_t unwindto_return_sym; /* symbol unwindTo:return: */ - - + /* pending asynchronous semaphores */ moo_oop_semaphore_t* sem_list; moo_oow_t sem_list_count; diff --git a/moo/lib/pf-sys.c b/moo/lib/pf-sys.c index 5a0d467..9ab70de 100644 --- a/moo/lib/pf-sys.c +++ b/moo/lib/pf-sys.c @@ -87,6 +87,24 @@ moo_pfrc_t moo_pf_system_get_sig (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) return MOO_PF_SUCCESS; } +moo_pfrc_t moo_pf_system_set_sig (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo_oop_t tmp; + moo_uint8_t sig; + int n; + + tmp = MOO_STACK_GETARG(moo, nargs, 0); + MOO_PF_CHECK_ARGS (moo, nargs, MOO_OOP_IS_SMOOI(tmp)); + + sig = (moo_uint8_t)MOO_OOP_TO_SMOOI(tmp); + n = moo->vmprim.vm_setsig(moo, sig); + if (n <= -1) return MOO_PF_FAILURE; + + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP((moo_ooi_t)sig)); + + return MOO_PF_SUCCESS; +} + /* ------------------------------------------------------------------------------------- */ static MOO_INLINE moo_pfrc_t _system_alloc (moo_t* moo, moo_ooi_t nargs, int clear) diff --git a/moo/lib/std.c b/moo/lib/std.c index 5c4e293..78483a8 100644 --- a/moo/lib/std.c +++ b/moo/lib/std.c @@ -2795,7 +2795,6 @@ static void vm_sleep (moo_t* moo, const moo_ntime_t* dur) #endif } - static moo_ooi_t vm_getsigfd (moo_t* moo) { xtn_t* xtn = GET_XTN(moo); @@ -2813,6 +2812,18 @@ static int vm_getsig (moo_t* moo, moo_uint8_t* u8) } return 1; } + +static int vm_setsig (moo_t* moo, moo_uint8_t u8) +{ + xtn_t* xtn = GET_XTN(moo); + if (write(xtn->sigfd.p[1], &u8, MOO_SIZEOF(u8)) == -1) + { + if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) return 0; + moo_seterrwithsyserr (moo, 0, errno); + return -1; + } + return 1; +} /* ========================================================================= */ #if defined(HAVE_SIGACTION) @@ -3708,6 +3719,7 @@ static void fini_moo (moo_t* moo) vmprim.vm_sleep = vm_sleep; vmprim.vm_getsigfd = vm_getsigfd; vmprim.vm_getsig = vm_getsig; + vmprim.vm_setsig = vm_setsig; moo = moo_open(&sys_mmgr, MOO_SIZEOF(xtn_t) + xtnsize, ((cfg && cfg->cmgr)? cfg->cmgr: moo_get_utf8_cmgr()), &vmprim, errinfo); if (!moo) return MOO_NULL;