From da1f8cb67b45cd0b1f3445fec47f925bf6e3c7e9 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Mon, 9 Sep 2019 07:43:14 +0000 Subject: [PATCH] removed _KernelProcess. added System>>_findProcessById and System>>_findProcessByIdGreater touched os signal handler in System --- moo/kernel/Process.moo | 14 +--- moo/kernel/System.moo | 61 ++++++++--------- moo/lib/exec.c | 146 ++++++++++++++++++++++++----------------- moo/lib/gc.c | 9 --- moo/lib/moo.h | 2 +- 5 files changed, 119 insertions(+), 113 deletions(-) diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index fa7f1f5..485187b 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -7,10 +7,9 @@ class(#pointer,#final,#limited) Process(Object) var sem, perr, perrmsg. var asyncsg. - + method primError { ^self.perr } method primErrorMessage { ^self.perrmsg } - method(#primitive) sp. method(#primitive) resume. @@ -77,12 +76,6 @@ class(#pointer,#final,#limited) Process(Object) } } -class(#pointer,#limited,#final) _KernelProcess(Process) -{ - // _KernelProcess is a predefined kernel class. so it can inherit from a final class, Process. - // It must be exactly the same as Process other than inheritance and is used internally only. -} - class Semaphore(Object) { var waiting_head := nil, @@ -434,8 +427,5 @@ class(#final,#limited) ProcessScheduler(Object) var suspended_head, suspended_tail. method activeProcess { ^self.active } - method resume: aProcess { ^aProcess resume } - - method(#primitive,#lenient) _processById: id. - method(#primitive) processById: id. + method resume: proc { ^proc resume } } diff --git a/moo/kernel/System.moo b/moo/kernel/System.moo index aa5ce70..6d202d5 100644 --- a/moo/kernel/System.moo +++ b/moo/kernel/System.moo @@ -45,7 +45,7 @@ class System(Apex) method(#class) startup(class_name, method_name) { - | class ret | + | class ret gcfin_proc ossig_proc | self.asyncsg := SemaphoreGroup new. @@ -55,12 +55,14 @@ class System(Apex) self error: ('Cannot find the class - ' & class_name). }. - // start the gc finalizer process - [ self __gc_finalizer ] fork. - - // start the os signal handler process + // start the gc finalizer process and os signal handler process + //[ self __gc_finalizer ] fork. //[ self __os_sig_handler ] fork. - [ :caller | self __os_sig_handler: caller ] newProcess(thisProcess) resume. + gcfin_proc := [ self __gc_finalizer ] newProcess. + ossig_proc := [ :caller | self __os_sig_handler: caller ] newProcess(thisProcess). + + gcfin_proc resume. + ossig_proc resume. [ // TODO: change the method signature to variadic and pass extra arguments to perform??? @@ -159,41 +161,36 @@ class System(Apex) // the caller must request to terminate all its child processes.. // TODO: to avoid this, this process must enumerate all proceses and terminate them except this and gcfin process -/* TODO: redo the following process termination loop. - need to write a proper process enumeration methods. - 0 -> startup <--- this should also be stored in the 'caller' variable. - 1 -> __gc_finalizer - 2 -> __os_signal_handler - 3 -> application main - the following loops starts from pid 3 up to 100. this is POC only. i need to write a proper enumeration methods and use them. - */ + // this disables autonomous process switching only. + // TODO: check if the ensure block code can trigger process switching? + // whap happens if the ensure block creates new processes? this is likely to affect the termination loop below. + // even the id of the terminated process may get reused.... + self _disableProcessSwitching. - //Processor _suspendUserProcesses. <--- keep kernel processes alive. - pid := 3. - while (pid < 100) + /* + 0 -> startup <--- this should also be stored in the 'caller' variable. + 1 -> __gc_finalizer + 2 -> __os_signal_handler + 3 .. -> other processes started by application. + */ + proc := System _findProcessByIdGreaterThan: 2. + while (proc notError) { - proc := Processor _processById: pid. - if (proc notError and proc ~~ caller) { System logNl: ("Requesting to suspend process of id - " & pid asString). proc suspend }. - pid := pid + 1. + pid := proc id. + System logNl: ("Requesting to terminate process of id - " & pid asString). + proc terminate. + proc := System _findProcessByIdGreaterThan: pid. }. - pid := 3. - while (pid < 100) - { - proc := Processor _processById: pid. - if (proc notError and proc ~~ caller) { System logNl: ("Requesting to terminate process of id - " & pid asString). proc terminate }. - pid := pid + 1. - }. -/* TODO: end redo */ - caller terminate. // terminate the startup process. + self _enableProcessSwitching. System logNl: '>>>>End of OS signal handler process ' & (thisProcess id) asString. self.gcfin_should_exit := true. self.gcfin_sem signal. // wake the gcfin process. - System _halting. // inform VM that it should get ready for halting. + self _halting. // inform VM that it should get ready for halting. ]. } @@ -201,6 +198,10 @@ class System(Apex) method(#class,#primitive) _getSigfd. method(#class,#primitive) _setSig: signo. method(#class,#primitive) _halting. + method(#class,#primitive) _enableProcessSwitching. + method(#class,#primitive) _disableProcessSwitching. + method(#class,#primitive,#lenient) _findProcessById: id. + method(#class,#primitive,#lenient) _findProcessByIdGreaterThan: id. method(#class,#primitive) _popCollectable. method(#class,#primitive) collectGarbage. diff --git a/moo/lib/exec.c b/moo/lib/exec.c index bee2bc0..9ca6194 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -255,7 +255,7 @@ static MOO_INLINE int prepare_to_alloc_pid (moo_t* moo) new_capa = MOO_SMOOI_MAX; } - tmp = moo_reallocmem (moo, moo->proc_map, MOO_SIZEOF(moo_oop_t) * new_capa); + tmp = moo_reallocmem(moo, moo->proc_map, MOO_SIZEOF(moo_oop_t) * new_capa); if (!tmp) return -1; moo->proc_map_free_first = moo->proc_map_capa; @@ -1626,7 +1626,6 @@ static moo_oop_process_t start_initial_process (moo_t* moo, moo_oop_context_t c) proc = make_process(moo, c); if (!proc) return MOO_NULL; - MOO_OBJ_SET_CLASS(proc, moo->_kernel_process); /* the initial process is special */ chain_into_processor (moo, proc, PROC_STATE_RUNNING); moo->processor->active = proc; @@ -2746,61 +2745,6 @@ static moo_pfrc_t pf_process_suspend (moo_t* moo, moo_mod_t* mod, moo_ooi_t narg return MOO_PF_SUCCESS; } -static moo_pfrc_t pf_process_scheduler_process_by_id (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) -{ - moo_oop_t rcv, id; - moo_oop_process_t proc; - - rcv = MOO_STACK_GETRCV(moo, nargs); - id = MOO_STACK_GETARG(moo, nargs, 0); - - MOO_PF_CHECK_RCV (moo, rcv == (moo_oop_t)moo->processor); - - if (MOO_OOP_IS_SMOOI(id)) - { - proc = moo->processor->runnable.first; - while (proc) - { - if (proc->id == id) - { - MOO_STACK_SETRET (moo, nargs, (moo_oop_t)proc); - return MOO_PF_SUCCESS; - } - if (proc == moo->processor->runnable.last) break; - proc = proc->ps.next; - } - - proc = moo->processor->suspended.first; - while (proc) - { - if (proc->id == id) - { - MOO_STACK_SETRET (moo, nargs, (moo_oop_t)proc); - return MOO_PF_SUCCESS; - } - if (proc == moo->processor->suspended.last) break; - proc = proc->ps.next; - } - } - - MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ENOENT); - return MOO_PF_FAILURE; -} - -static moo_pfrc_t pf_process_scheduler_suspend_user_processes (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) -{ - moo_oop_process_t proc; - - while ((moo_oop_t)(proc = moo->processor->runnable.first) != moo->_nil) - { - /* exclude internal kernel classes. suspend user processes only */ - if (MOO_CLASSOF(moo, proc) == moo->_process) suspend_process (moo, proc); - } - - MOO_STACK_SETRETTORCV (moo, nargs); - return MOO_PF_SUCCESS; -} - /* ------------------------------------------------------------------ */ static moo_pfrc_t pf_semaphore_signal (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) { @@ -3281,6 +3225,20 @@ static moo_pfrc_t pf_system_return_value_to_context (moo_t* moo, moo_mod_t* mod, } /* ------------------------------------------------------------------ */ +static moo_pfrc_t pf_system_enable_process_switching (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo->no_proc_switch = 0; + MOO_STACK_SETRETTORCV (moo, nargs); + return MOO_PF_SUCCESS; +} + +static moo_pfrc_t pf_system_disable_process_switching (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo->no_proc_switch = 0; + MOO_STACK_SETRETTORCV (moo, nargs); + return MOO_PF_SUCCESS; +} + static moo_pfrc_t pf_system_halting (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) { moo_evtcb_t* cb; @@ -3292,6 +3250,71 @@ static moo_pfrc_t pf_system_halting (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs return MOO_PF_SUCCESS; } +static moo_pfrc_t pf_system_find_process_by_id (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo_oop_t rcv, id; + moo_oop_process_t proc; + + rcv = MOO_STACK_GETRCV(moo, nargs); + id = MOO_STACK_GETARG(moo, nargs, 0); + + /*MOO_PF_CHECK_RCV (moo, rcv == (moo_oop_t)moo->processor);*/ + + if (MOO_OOP_IS_SMOOI(id)) + { + moo_ooi_t index = MOO_OOP_TO_SMOOI(id); + if (index >= 0) + { + if (MOO_CLASSOF(moo, moo->proc_map[index]) == moo->_process) + { + MOO_STACK_SETRET (moo, nargs, moo->proc_map[index]); + return MOO_PF_SUCCESS; + } + + /* it must be in a free list since the pid slot is not allocated. see alloc_pid() and free_pid() */ + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(moo->proc_map[index])); + } + } + + MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ENOENT); + return MOO_PF_FAILURE; +} + +static moo_pfrc_t pf_system_find_process_by_id_gt (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo_oop_t rcv, id; + moo_oop_process_t proc; + + rcv = MOO_STACK_GETRCV(moo, nargs); + id = MOO_STACK_GETARG(moo, nargs, 0); + + /*MOO_PF_CHECK_RCV (moo, rcv == (moo_oop_t)moo->processor);*/ + + if (MOO_OOP_IS_SMOOI(id)) + { + moo_ooi_t index = MOO_OOP_TO_SMOOI(id); + if (index >= 0) + { +/* TOOD: enhance alloc_pid() and free_pid() to maintain the hightest pid number so that this loop can stop before reaching proc_map_capa */ + for (++index; index < moo->proc_map_capa; index++) + { + if (MOO_CLASSOF(moo, moo->proc_map[index]) == moo->_process) + { + MOO_STACK_SETRET (moo, nargs, moo->proc_map[index]); + return MOO_PF_SUCCESS; + } + + /* it must be in a free list since the pid slot is not allocated. see alloc_pid() and free_pid() */ + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(moo->proc_map[index])); + } + } + } + + MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ENOENT); + return MOO_PF_FAILURE; +} + + /* ------------------------------------------------------------------ */ static moo_pfrc_t pf_number_scale (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) { @@ -4333,9 +4356,6 @@ static pf_t pftab[] = { "MethodContext_findExceptionHandler:", { pf_context_find_exception_handler, 1, 1 } }, { "MethodContext_goto:", { pf_context_goto, 1, 1 } }, - { "ProcessScheduler_processById:", { pf_process_scheduler_process_by_id, 1, 1 } }, - { "ProcessScheduler_suspendUserProcesses", { pf_process_scheduler_suspend_user_processes, 0, 0 } }, - { "Process_resume", { pf_process_resume, 0, 0 } }, { "Process_sp", { pf_process_sp, 0, 0 } }, { "Process_suspend", { pf_process_suspend, 0, 0 } }, @@ -4386,6 +4406,10 @@ static pf_t pftab[] = { "System_calloc", { moo_pf_system_calloc, 1, 1 } }, { "System_calloc:", { moo_pf_system_calloc, 1, 1 } }, { "System_collectGarbage", { moo_pf_system_collect_garbage, 0, 0 } }, + { "System_disableProcessSwitching", { pf_system_disable_process_switching, 0, 0 } }, + { "System_enableProcessSwitching", { pf_system_enable_process_switching, 0, 0 } }, + { "System_findProcessById:", { pf_system_find_process_by_id, 1, 1 } }, + { "System_findProcessByIdGreaterThan:", { pf_system_find_process_by_id_gt, 1, 1 } }, { "System_free", { moo_pf_system_free, 1, 1 } }, { "System_free:", { moo_pf_system_free, 1, 1 } }, { "System_gc", { moo_pf_system_collect_garbage, 0, 0 } }, @@ -5472,7 +5496,7 @@ static int __execute (moo_t* moo) BEGIN_DISPATCH_LOOP() /* stop requested or no more runnable process */ - if (moo->abort_req || switch_process_if_needed(moo) == 0) EXIT_DISPATCH_LOOP(); + if (moo->abort_req || (!moo->no_proc_switch && switch_process_if_needed(moo) == 0)) EXIT_DISPATCH_LOOP(); #if defined(MOO_DEBUG_VM_EXEC) moo->last_inst_pointer = moo->ip; diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 9a44dfd..1e8e035 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -282,15 +282,6 @@ static kernel_class_info_t kernel_classes[] = MOO_OBJ_TYPE_OOP, MOO_OFFSETOF(moo_t, _process) }, - { 14, - { '_','K','e','r','n','e','l','P','r','o','c','e','s','s' }, - MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED, - 0, - MOO_PROCESS_NAMED_INSTVARS, - MOO_CLASS_SPEC_FLAG_INDEXED, - MOO_OBJ_TYPE_OOP, - MOO_OFFSETOF(moo_t, _kernel_process) }, - { 9, { 'S','e','m','a','p','h','o','r','e' }, 0, diff --git a/moo/lib/moo.h b/moo/lib/moo.h index e332586..7f2294e 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -1547,7 +1547,6 @@ struct moo_t moo_oop_class_t _method_context; /* MethodContext */ moo_oop_class_t _block_context; /* BlockContext */ moo_oop_class_t _process; /* Process */ - moo_oop_class_t _kernel_process; /* KernelProcess */ moo_oop_class_t _semaphore; /* Semaphore */ moo_oop_class_t _semaphore_group; /* SemaphoreGroup */ moo_oop_class_t _process_scheduler; /* ProcessScheduler */ @@ -1632,6 +1631,7 @@ struct moo_t moo_oob_t* active_code; moo_ooi_t sp; moo_ooi_t ip; + int no_proc_switch; /* process switching disabled */ int proc_switched; /* TODO: this is temporary. implement something else to skip immediate context switching */ int switch_proc; int abort_req;