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
This commit is contained in:
parent
f23a5bd22c
commit
f51fbd1a33
@ -215,9 +215,24 @@ what looks better as a shorthand expression for block value?
|
|||||||
|
|
||||||
```
|
```
|
||||||
ffi := FFI new: 'libc.so.6'.
|
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|sl>i' arguments: #("[%s ffi test %ld]\n" "sloppy" 12345678)) dump.
|
||||||
(ffi call: #printf signature: 's>i' arguments: #("[%% ffi test %%]\n")) 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: #puts signature: 's>i' arguments: #("this is ffi test")) dump.
|
||||||
(ffi call: #time signature: 'p>l' arguments: #(#\p0)) dump.
|
(ffi call: #time signature: 'p>l' arguments: #(#\p0)) dump.
|
||||||
|
]
|
||||||
|
ensure: [
|
||||||
ffi close.
|
ffi close.
|
||||||
|
].
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Command line options
|
||||||
|
|
||||||
|
```
|
||||||
|
moo --log /dev/stderr ../kernel/test-001.moo
|
||||||
|
moo --log /dev/stderr,warn+ ../kernel/test-001.moo
|
||||||
|
```
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ extend Context
|
|||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// <<private>>
|
// <<private>>
|
||||||
// private: called by VM upon unwinding as well as by
|
// private: called by VM upon unwinding as well as by
|
||||||
// Exception<<signal and Error<<signal
|
// Exception>>signal, Error>>signal, Process>>terminate
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
| ctx stop eb pending_pos |
|
| ctx stop eb pending_pos |
|
||||||
|
@ -414,7 +414,7 @@ class SemaphoreHeap(Object)
|
|||||||
|
|
||||||
class(#final,#limited) ProcessScheduler(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(#get) runnable_count := 0.
|
||||||
var runnable_head, runnable_tail.
|
var runnable_head, runnable_tail.
|
||||||
var(#get) suspended_count := 0.
|
var(#get) suspended_count := 0.
|
||||||
|
@ -55,11 +55,13 @@ class System(Apex)
|
|||||||
|
|
||||||
// start the gc finalizer process
|
// start the gc finalizer process
|
||||||
[ self __gc_finalizer ] fork.
|
[ 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???
|
// TODO: change the method signature to variadic and pass extra arguments to perform???
|
||||||
ret := class perform: method_name.
|
ret := class perform: method_name.
|
||||||
|
|
||||||
|
self _setSig: 16rFF.
|
||||||
//// System logNl: '======= END of startup ==============='.
|
//// System logNl: '======= END of startup ==============='.
|
||||||
^ret.
|
^ret.
|
||||||
}
|
}
|
||||||
@ -87,7 +89,7 @@ class System(Apex)
|
|||||||
}.
|
}.
|
||||||
|
|
||||||
//if (Processor total_count == 1)
|
//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
|
// exit from this loop when there are no other processes running except this finalizer process
|
||||||
if (gc)
|
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 := Semaphore new.
|
||||||
os_intr_sem signalOnInput: System _getSigfd.
|
os_intr_sem signalOnInput: System _getSigfd.
|
||||||
@ -129,26 +131,30 @@ class System(Apex)
|
|||||||
//TODO: Execute Handler for tmp.
|
//TODO: Execute Handler for tmp.
|
||||||
|
|
||||||
System logNl: 'Interrupt dectected - signal no - ' & tmp asString.
|
System logNl: 'Interrupt dectected - signal no - ' & tmp asString.
|
||||||
if (tmp == 2) { /* TODO: terminate all processes??? */ }.
|
if (tmp == 16rFF or tmp == 2) { /* TODO: terminate all processes??? */ goto done }.
|
||||||
}.
|
|
||||||
|
|
||||||
if (Processor should_exit)
|
|
||||||
{
|
|
||||||
System logNl: 'Exiting os interrupt handling process ' & (thisProcess id) asString.
|
|
||||||
break.
|
|
||||||
}.
|
}.
|
||||||
|
|
||||||
os_intr_sem wait.
|
os_intr_sem wait.
|
||||||
}
|
}.
|
||||||
|
done:
|
||||||
|
nil.
|
||||||
]
|
]
|
||||||
ensure: [
|
ensure: [
|
||||||
os_intr_sem unsignal.
|
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) _getSig.
|
||||||
method(#class,#primitive) _getSigfd.
|
method(#class,#primitive) _getSigfd.
|
||||||
|
method(#class,#primitive) _setSig: signo.
|
||||||
|
|
||||||
method(#class,#primitive) _popCollectable.
|
method(#class,#primitive) _popCollectable.
|
||||||
method(#class,#primitive) collectGarbage.
|
method(#class,#primitive) collectGarbage.
|
||||||
method(#class,#primitive) gc.
|
method(#class,#primitive) gc.
|
||||||
|
@ -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);
|
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_method_context);
|
||||||
|
|
||||||
except_class = (moo_oop_class_t)MOO_STACK_GETARG(moo, nargs, 0);
|
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);
|
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)
|
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_putUint64", { moo_pf_system_put_uint64, 3, 3 } },
|
||||||
{ "System_putUint8", { moo_pf_system_put_uint8, 3, 3 } },
|
{ "System_putUint8", { moo_pf_system_put_uint8, 3, 3 } },
|
||||||
{ "System_return:to:", { pf_system_return_value_to_context, 2, 2 } },
|
{ "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 } },
|
{ "_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 must not happen as long as doesNotUnderstand: is implemented under Apex.
|
||||||
* this check should indicate a very serious internal problem */
|
* this check should indicate a very serious internal problem */
|
||||||
MOO_LOG4 (moo, MOO_LOG_IC | MOO_LOG_FATAL,
|
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_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));
|
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;
|
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->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
|
||||||
MOO_ASSERT (moo, proc == moo->processor->runnable.first);
|
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 */
|
switch_to_process_from_nil (moo, proc); /* sechedule the gc finalizer process */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,7 +552,7 @@ static int ignite_2 (moo_t* moo)
|
|||||||
if (!tmp) return -1;
|
if (!tmp) return -1;
|
||||||
moo->processor = (moo_oop_process_scheduler_t)tmp;
|
moo->processor = (moo_oop_process_scheduler_t)tmp;
|
||||||
moo->processor->active = moo->nil_process;
|
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->total_count = MOO_SMOOI_TO_OOP(0);
|
||||||
moo->processor->runnable.count = MOO_SMOOI_TO_OOP(0);
|
moo->processor->runnable.count = MOO_SMOOI_TO_OOP(0);
|
||||||
moo->processor->suspended.count = MOO_SMOOI_TO_OOP(0);
|
moo->processor->suspended.count = MOO_SMOOI_TO_OOP(0);
|
||||||
|
@ -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_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_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_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);
|
moo_pfrc_t moo_pf_system_calloc (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs);
|
||||||
|
@ -873,7 +873,7 @@ struct moo_process_scheduler_t
|
|||||||
{
|
{
|
||||||
MOO_OBJ_HEADER;
|
MOO_OBJ_HEADER;
|
||||||
moo_oop_process_t active; /* pointer to an active process in the runnable process list */
|
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 */
|
moo_oop_t total_count; /* SmallIntger, total number of processes - runnable/running/suspended */
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -1216,6 +1216,11 @@ typedef int (*moo_vmprim_getsig_t) (
|
|||||||
moo_uint8_t* sig
|
moo_uint8_t* sig
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef int (*moo_vmprim_setsig_t) (
|
||||||
|
moo_t* moo,
|
||||||
|
moo_uint8_t sig
|
||||||
|
);
|
||||||
|
|
||||||
struct moo_vmprim_t
|
struct moo_vmprim_t
|
||||||
{
|
{
|
||||||
moo_alloc_heap_t alloc_heap;
|
moo_alloc_heap_t alloc_heap;
|
||||||
@ -1243,6 +1248,7 @@ struct moo_vmprim_t
|
|||||||
|
|
||||||
moo_vmprim_getsigfd_t vm_getsigfd;
|
moo_vmprim_getsigfd_t vm_getsigfd;
|
||||||
moo_vmprim_getsig_t vm_getsig;
|
moo_vmprim_getsig_t vm_getsig;
|
||||||
|
moo_vmprim_setsig_t vm_setsig;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct moo_vmprim_t moo_vmprim_t;
|
typedef struct moo_vmprim_t moo_vmprim_t;
|
||||||
@ -1579,7 +1585,6 @@ struct moo_t
|
|||||||
moo_oop_char_t primitive_failed_sym; /* symbol primitiveFailed */
|
moo_oop_char_t primitive_failed_sym; /* symbol primitiveFailed */
|
||||||
moo_oop_char_t unwindto_return_sym; /* symbol unwindTo:return: */
|
moo_oop_char_t unwindto_return_sym; /* symbol unwindTo:return: */
|
||||||
|
|
||||||
|
|
||||||
/* pending asynchronous semaphores */
|
/* pending asynchronous semaphores */
|
||||||
moo_oop_semaphore_t* sem_list;
|
moo_oop_semaphore_t* sem_list;
|
||||||
moo_oow_t sem_list_count;
|
moo_oow_t sem_list_count;
|
||||||
|
@ -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;
|
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)
|
static MOO_INLINE moo_pfrc_t _system_alloc (moo_t* moo, moo_ooi_t nargs, int clear)
|
||||||
|
@ -2795,7 +2795,6 @@ static void vm_sleep (moo_t* moo, const moo_ntime_t* dur)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static moo_ooi_t vm_getsigfd (moo_t* moo)
|
static moo_ooi_t vm_getsigfd (moo_t* moo)
|
||||||
{
|
{
|
||||||
xtn_t* xtn = GET_XTN(moo);
|
xtn_t* xtn = GET_XTN(moo);
|
||||||
@ -2813,6 +2812,18 @@ static int vm_getsig (moo_t* moo, moo_uint8_t* u8)
|
|||||||
}
|
}
|
||||||
return 1;
|
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)
|
#if defined(HAVE_SIGACTION)
|
||||||
@ -3708,6 +3719,7 @@ static void fini_moo (moo_t* moo)
|
|||||||
vmprim.vm_sleep = vm_sleep;
|
vmprim.vm_sleep = vm_sleep;
|
||||||
vmprim.vm_getsigfd = vm_getsigfd;
|
vmprim.vm_getsigfd = vm_getsigfd;
|
||||||
vmprim.vm_getsig = vm_getsig;
|
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);
|
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;
|
if (!moo) return MOO_NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user