diff --git a/stix/kernel/Process.st b/stix/kernel/Process.st index e81a7d1..38539df 100644 --- a/stix/kernel/Process.st +++ b/stix/kernel/Process.st @@ -1,6 +1,12 @@ #class(#pointer) Process(Object) { - #dcl context state prev next. + #dcl initial active state prev next. + + #method new + { + "instantiation is not allowed" + ^nil. "TODO: raise an exception" + } #method prev { @@ -47,6 +53,9 @@ #method add: aProcess { + self primitiveFailed. + + "The primitive does something like the following. (self.tally = 0) ifTrue: [ @@ -59,13 +68,17 @@ self.head prev: aProcess. self.head := aProcess. self.tally := self.tally + 1. - ]. + ]." } #method resume: aProcess { - self add: aProcess. - self.active := aProcess. + + self primitiveFailed. + + "self add: aProcess. + TODO: need to change state of a Process??? + self.active := aProcess." } #method remove: aProcess diff --git a/stix/kernel/test-005.st b/stix/kernel/test-005.st index c556f8f..8699d60 100644 --- a/stix/kernel/test-005.st +++ b/stix/kernel/test-005.st @@ -243,7 +243,7 @@ | p | '000000000000000000' dump. - p := [ 'xxxxxxxxxxxxxxxxx' dump. 'yyyyyyyyyyyyyyyyyyyyyyyyyy' dump. ] newProcess. + p := [ 'xxxxxxxxxxxxxxxxx' dump. 'yyyyyyyyyyyyyyyyyyyyyyyyyy' dump. ^10. ] newProcess. '999999999999999999' dump. p resume. diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 4e94c8f..39ee170 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -105,64 +105,32 @@ static stix_oop_process_t make_process (stix_t* stix, stix_oop_context_t c) stix_oop_process_t proc; /* TODO: do something about the stack. */ - stix_pushtmp (stix, &c); + stix_pushtmp (stix, (stix_oop_t*)&c); proc = (stix_oop_process_t)stix_instantiate (stix, stix->_process, STIX_NULL, stix->option.dfl_procstk_size); stix_poptmp (stix); if (!proc) return STIX_NULL; proc->state = STIX_OOP_FROM_SMINT(0); - proc->context = c; + proc->initial_context = c; return proc; } -static void resume_process (stix_t* stix, stix_oop_process_t proc) -{ - if (proc->state == STIX_OOP_FROM_SMINT(0)) - { - stix_ooi_t tally; - STIX_ASSERT (proc->prev == stix->_nil); - STIX_ASSERT (proc->next == stix->_nil); - - tally = STIX_OOP_TO_SMINT(stix->scheduler->tally); - if (tally <= 0) - { - stix->scheduler->head = proc; - stix->scheduler->tail = proc; - stix->scheduler->tally = STIX_OOP_FROM_SMINT(1); - } - else - { - /* TODO: over flow check or maximum number of process check? */ - proc->next = stix->scheduler->head; - stix->scheduler->head->prev = proc; - stix->scheduler->head = proc; - stix->scheduler->tally = STIX_OOP_FROM_SMINT(tally + 1); - } - } - - stix->scheduler->active = proc; - proc->state = STIX_OOP_FROM_SMINT(1); /* TODO: change the code properly... changing state alone doesn't help */ -} - -static stix_oop_process_t start_new_process (stix_t* stix, stix_oop_context_t c) -{ - stix_oop_process_t proc; - - proc = make_process (stix, c); - if (!proc) return STIX_NULL; - - resume_process (stix, proc); - return proc; -} static void switch_process (stix_t* stix, stix_oop_process_t proc) { if (stix->scheduler->active != proc) { - SWITCH_ACTIVE_CONTEXT (stix, proc->context); +printf ("ACTUAL PROCESS SWITCHING BF...%d %p\n", (int)stix->ip, stix->active_context); + +/* store the active context to the active process */ +stix->scheduler->active->active_context = stix->active_context; + + SWITCH_ACTIVE_CONTEXT (stix, proc->active_context); +printf ("ACTUAL PROCESS SWITCHING AF...%d %p\n", (int)stix->ip, stix->active_context); /*TODO: set the state to RUNNING */ stix->scheduler->active = proc; + } } @@ -179,6 +147,55 @@ static void switch_to_next_process (stix_t* stix) } } +static void schedule_process (stix_t* stix, stix_oop_process_t proc) +{ + if (proc->state == STIX_OOP_FROM_SMINT(0)) + { + stix_ooi_t tally; + STIX_ASSERT ((stix_oop_t)proc->prev == stix->_nil); + STIX_ASSERT ((stix_oop_t)proc->next == stix->_nil); + + tally = STIX_OOP_TO_SMINT(stix->scheduler->tally); + if (tally <= 0) + { + stix->scheduler->head = proc; + stix->scheduler->tail = proc; + stix->scheduler->tally = STIX_OOP_FROM_SMINT(1); +printf ("ADD NEW PROCESS X - %d\n", (int)1); + } + else + { + /* TODO: over flow check or maximum number of process check using the tally field? */ + proc->next = stix->scheduler->head; + stix->scheduler->head->prev = proc; + stix->scheduler->head = proc; + stix->scheduler->tally = STIX_OOP_FROM_SMINT(tally + 1); +printf ("ADD NEW PROCESS Y - %d\n", (int)tally + 1); + } + + proc->state = STIX_OOP_FROM_SMINT(1); /* TODO: change the code properly... changing state alone doesn't help */ + proc->active_context = proc->initial_context; + + switch_process (stix, proc); + } + else if (stix->scheduler->active != proc) + { + switch_process (stix, proc); + } +} + +static stix_oop_process_t start_new_process (stix_t* stix, stix_oop_context_t c) +{ + stix_oop_process_t proc; + + proc = make_process (stix, c); + if (!proc) return STIX_NULL; + + schedule_process (stix, proc); + return proc; +} + + static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth) { stix_oop_context_t ctx; @@ -1122,11 +1139,25 @@ static int prim_integer_ge (stix_t* stix, stix_ooi_t nargs) static int prim_scheduler_add (stix_t* stix, stix_ooi_t nargs) { - return 0; + stix_oop_t rcv, arg; + + STIX_ASSERT (nargs == 1); + + rcv = ACTIVE_STACK_GET(stix, stix->sp - 1); + arg = ACTIVE_STACK_GET(stix, stix->sp); + + if (rcv != (stix_oop_t)stix->scheduler || STIX_CLASSOF(stix,arg) != stix->_process) + { + return 0; + } + + schedule_process (stix, (stix_oop_process_t)arg); + return 1; } static int prim_scheduler_remove (stix_t* stix, stix_ooi_t nargs) { +/* TODO: */ return 0; } @@ -1631,10 +1662,15 @@ int stix_execute (stix_t* stix) { -switch_to_next_process (stix); -#if 0 -printf ("IP => %d ", (int)stix->ip); + +#if 1 +printf ("IP => %d\n", (int)stix->ip); #endif +switch_to_next_process (stix); +#if 1 +printf ("IP => %d\n", (int)stix->ip); +#endif + FETCH_BYTE_CODE_TO (stix, bcode); /*while (bcode == BCODE_NOOP) FETCH_BYTE_CODE_TO (stix, bcode);*/ @@ -2417,21 +2453,29 @@ printf ("<> SP=%d\n", (int)stix->sp); */ stix->ip--; - SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)stix->active_context->origin->sender); - - /* push the return value to the stack of the new active context */ - ACTIVE_STACK_PUSH (stix, return_value); - - if (stix->active_context->sender == stix->_nil) + if (stix->scheduler->active->initial_context == stix->active_context) { - /* the sending context of the intial context has been set to nil. - * use this fact to tell an initial context from a normal context. */ - STIX_ASSERT (stix->active_context->receiver_or_source == stix->_nil); +/* TODO: terminate a proces... */ +printf ("TERMINATING XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"); + } + else + { + SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)stix->active_context->origin->sender); + + /* push the return value to the stack of the new active context */ + ACTIVE_STACK_PUSH (stix, return_value); + + if (stix->active_context->sender == stix->_nil) + { + /* the sending context of the intial context has been set to nil. + * use this fact to tell an initial context from a normal context. */ + STIX_ASSERT (stix->active_context->receiver_or_source == stix->_nil); #if defined(STIX_DEBUG_EXEC) printf ("<<>>\n"); #endif - STIX_ASSERT (stix->sp == 0); - goto done; + STIX_ASSERT (stix->sp == 0); + goto done; + } } break; @@ -2441,9 +2485,19 @@ printf ("<<>>\n"); STIX_ASSERT(STIX_CLASSOF(stix, stix->active_context) == stix->_block_context); - return_value = ACTIVE_STACK_GETTOP(stix); - SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)stix->active_context->sender); - ACTIVE_STACK_PUSH (stix, return_value); + if (stix->active_context == stix->scheduler->active->initial_context) + { + /* TODO: terminate the process */ +printf ("TERMINATE A PROCESS............\n"); +/* **************************************** */ + } + else + { + return_value = ACTIVE_STACK_GETTOP(stix); + SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)stix->active_context->sender); + ACTIVE_STACK_PUSH (stix, return_value); + } + break; case BCODE_MAKE_BLOCK: diff --git a/stix/lib/ignite.c b/stix/lib/ignite.c index 5ed62fb..60c9668 100644 --- a/stix/lib/ignite.c +++ b/stix/lib/ignite.c @@ -192,9 +192,12 @@ static int ignite_2 (stix_t* stix) if (!tmp) return -1; stix->sysdic = (stix_oop_set_t)tmp; + /* Create a process scheduler */ tmp = (stix_oop_t)stix_instantiate (stix, stix->_process_scheduler, STIX_NULL, 0); if (!tmp) return -1; stix->scheduler = (stix_oop_process_scheduler_t)tmp; + /* initialize the tally field to 0, keep other fields as nils */ + stix->scheduler->tally = STIX_OOP_FROM_SMINT(0); /* Export the system dictionary via the first class variable of the Stix class */ ((stix_oop_class_t)stix->_apex)->slot[0] = (stix_oop_t)stix->sysdic; diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index cf27249..7faed37 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -50,7 +50,7 @@ #define STIX_USE_OBJECT_TRAILER /* this is for gc debugging */ -#define STIX_DEBUG_GC_001 +/*#define STIX_DEBUG_GC_001*/ /*#define STIX_DEBUG_EXEC*/ #define STIX_PROFILE_EXEC diff --git a/stix/lib/stix.h b/stix/lib/stix.h index d407db1..608deb4 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -468,13 +468,14 @@ struct stix_context_t }; -#define STIX_PROCESS_NAMED_INSTVARS 4 +#define STIX_PROCESS_NAMED_INSTVARS 5 typedef struct stix_process_t stix_process_t; typedef struct stix_process_t* stix_oop_process_t; struct stix_process_t { STIX_OBJ_HEADER; - stix_oop_context_t context; + stix_oop_context_t initial_context; + stix_oop_context_t active_context; stix_oop_t state; stix_oop_process_t prev; stix_oop_process_t next;