diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 3052c82..fa7f1f5 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -77,6 +77,12 @@ 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, diff --git a/moo/kernel/System.moo b/moo/kernel/System.moo index 5370f38..aa5ce70 100644 --- a/moo/kernel/System.moo +++ b/moo/kernel/System.moo @@ -128,7 +128,7 @@ class System(Apex) method(#class) __os_sig_handler: caller { - | os_intr_sem tmp terminate_process| + | os_intr_sem tmp | os_intr_sem := Semaphore new. os_intr_sem signalOnInput: System _getSigfd. @@ -168,27 +168,32 @@ class System(Apex) 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. */ - //Processor _suspendAllUserProcesses. <--- keep kernel processes alive. + //Processor _suspendUserProcesses. <--- keep kernel processes alive. + pid := 3. + while (pid < 100) + { + 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 := 3. while (pid < 100) { - //proc := Processor processById: pid. proc := Processor _processById: pid. - if (proc notError) { System logNl: ("Requesting to terminate process of id - " & pid asString). proc terminate }. + 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. + caller terminate. // terminate the startup process. System logNl: '>>>>End of OS signal handler process ' & (thisProcess id) asString. - //(Processor _processById: 1) resume. //<---- i shouldn't do ths. but, this system causes VM assertion failure. fix it.... self.gcfin_should_exit := true. self.gcfin_sem signal. // wake the gcfin process. - System _halting. + System _halting. // inform VM that it should get ready for halting. ]. } diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 38c5ff1..522d5f7 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -8567,9 +8567,13 @@ static int process_class_superclass (moo_t* moo) if (MOO_CLASS_SELFSPEC_FLAGS(MOO_OOP_TO_SMOOI(((moo_oop_class_t)cc->super_oop)->selfspec)) & MOO_CLASS_SELFSPEC_FLAG_FINAL) { /* cannot inherit a #final class */ - moo_setsynerrbfmt (moo, MOO_SYNERR_INHERITBANNED, &cc->fqn_loc, &cc->fqn, - "the %.*js class cannot inherit from a final class", cc->fqn.len, cc->fqn.ptr); - return -1; + if (cc->self_oop == MOO_NULL) /* self_oop is not null if it's a predefined kernel class. */ + { + /* the restriction applies to non-kernel classes only */ + moo_setsynerrbfmt (moo, MOO_SYNERR_INHERITBANNED, &cc->fqn_loc, &cc->fqn, + "the %.*js class cannot inherit from a final class", cc->fqn.len, cc->fqn.ptr); + return -1; + } } } else diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 2c23a2e..bee2bc0 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1624,8 +1624,9 @@ static moo_oop_process_t start_initial_process (moo_t* moo, moo_oop_context_t c) MOO_ASSERT (moo, moo->processor->runnable.count == MOO_SMOOI_TO_OOP(0)); MOO_ASSERT (moo, moo->processor->active == moo->nil_process); - proc = make_process (moo, 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; @@ -2060,7 +2061,7 @@ TODO: overcome this problem - accept parameters.... * let's forcefully set active_context to ctx directly. */ moo->active_context = ctx; - proc = start_initial_process (moo, ctx); + proc = start_initial_process(moo, ctx); moo_popvolats (moo, tmp_count); tmp_count = 0; if (!proc) goto oops; @@ -2786,13 +2787,18 @@ static moo_pfrc_t pf_process_scheduler_process_by_id (moo_t* moo, moo_mod_t* mod return MOO_PF_FAILURE; } -static moo_pfrc_t pf_process_scheduler_suspend_all_user_processes (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +static moo_pfrc_t pf_process_scheduler_suspend_user_processes (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) { - /* TODO: must exclude special inner processes */ - while (moo->processor->runnable.first) + moo_oop_process_t proc; + + while ((moo_oop_t)(proc = moo->processor->runnable.first) != moo->_nil) { - suspend_process (moo, moo->processor->runnable.first); + /* 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; } /* ------------------------------------------------------------------ */ @@ -4327,8 +4333,8 @@ 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_suspendAllUserProcesses", { pf_process_scheduler_suspend_all_user_processes, 0, 0 } }, + { "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 } }, diff --git a/moo/lib/gc.c b/moo/lib/gc.c index fda379f..9a44dfd 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -254,7 +254,6 @@ static kernel_class_info_t kernel_classes[] = MOO_OBJ_TYPE_OOP, MOO_OFFSETOF(moo_t, _methsig) }, - { 13, { 'M','e','t','h','o','d','C','o','n','t','e','x','t' }, @@ -283,6 +282,15 @@ 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 133c78d..e332586 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -742,23 +742,23 @@ typedef struct moo_semaphore_group_t* moo_oop_semaphore_group_t; struct moo_process_t { MOO_OBJ_HEADER; - moo_oop_context_t initial_context; - moo_oop_context_t current_context; + moo_oop_context_t initial_context; + moo_oop_context_t current_context; - moo_oop_t id; /* SmallInteger */ - moo_oop_t state; /* SmallInteger */ - moo_oop_t sp; /* stack pointer. SmallInteger */ + moo_oop_t id; /* SmallInteger */ + moo_oop_t state; /* SmallInteger */ + moo_oop_t sp; /* stack pointer. SmallInteger */ struct { - moo_oop_process_t prev; - moo_oop_process_t next; + moo_oop_process_t prev; + moo_oop_process_t next; } ps; /* links to use with the process scheduler */ struct { - moo_oop_process_t prev; - moo_oop_process_t next; + moo_oop_process_t prev; + moo_oop_process_t next; } sem_wait; /* links to use with a semaphore */ moo_oop_t sem; /* nil, semaphore, or semaphore group */ @@ -1547,6 +1547,7 @@ 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 */