loosend restriction imposed by #final. a kernel class can inherit from a final class.
added an experimental class _KernelProcess for process management
This commit is contained in:
		@ -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,
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
		].
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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 } },
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								moo/lib/gc.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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,
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user