diff --git a/stix/kernel/Process.st b/stix/kernel/Process.st index b68dcfc..9d11bd8 100644 --- a/stix/kernel/Process.st +++ b/stix/kernel/Process.st @@ -28,7 +28,7 @@ #class(#pointer) Process(Object) { - #dcl initial_context runnable_context state prev next sp sem_next. + #dcl initial_context current_context state prev next sp sem_next. #method new { @@ -58,7 +58,10 @@ #method resume { - ^Processor resume: self. + + self primitiveFailed + + ##^Processor resume: self. } #method terminate @@ -67,6 +70,12 @@ self primitiveFailed } + #method yield + { + + self primitiveFailed + } + #method sp { ^sp. @@ -96,7 +105,7 @@ #class ProcessScheduler(Object) { - #dcl tally head tail active. + #dcl tally active runnable. #method new { diff --git a/stix/lib/exec.c b/stix/lib/exec.c index bb57f37..8378425 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -140,7 +140,6 @@ #endif - static stix_oop_process_t make_process (stix_t* stix, stix_oop_context_t c) { stix_oop_process_t proc; @@ -152,6 +151,7 @@ static stix_oop_process_t make_process (stix_t* stix, stix_oop_context_t c) proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED); proc->initial_context = c; + proc->current_context = c; proc->sp = STIX_SMOOI_TO_OOP(-1); #if defined(STIX_DEBUG_PROCESSOR) @@ -160,102 +160,83 @@ printf ("PROCESS %p SIZE => %ld\n", proc, (long int)STIX_OBJ_GET_SIZE(proc)); return proc; } -static void switch_process (stix_t* stix, stix_oop_process_t proc) +static void switch_to_process (stix_t* stix, stix_oop_process_t proc) { - if (stix->processor->active != proc) - { - STIX_ASSERT (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE) || - proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_WAITING)); + /* the new process must not be the currently active process */ + STIX_ASSERT (stix->processor->active != proc); + + /* the new process must be in the runnable state */ + STIX_ASSERT (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE) || + proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_WAITING)); #if defined(STIX_DEBUG_PROCESSOR) printf ("ACTUAL PROCESS SWITCHING BF...%d %p\n", (int)stix->ip, stix->active_context); #endif - #if defined(STIX_USE_PROCSTK) - STORE_ACTIVE_SP(stix); - #else - /* nothing special */ - #endif +#if defined(STIX_USE_PROCSTK) + STORE_ACTIVE_SP(stix); +#else + /* nothing special */ +#endif - /* store the current active context to the current process. - * it is the suspended context of the process to be suspended */ - STIX_ASSERT ((stix_oop_t)stix->processor->active != stix->_nil); - stix->processor->active->runnable_context = stix->active_context; - stix->processor->active->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE); + /* store the current active context to the current process. + * it is the suspended context of the process to be suspended */ + STIX_ASSERT ((stix_oop_t)stix->processor->active != stix->_nil); + stix->processor->active->current_context = stix->active_context; + stix->processor->active->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE); - /* activate the given process */ - proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING); - stix->processor->active = proc; + /* activate the given process */ + proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING); + stix->processor->active = proc; - #if defined(STIX_USE_PROCSTK) - LOAD_ACTIVE_SP(stix); - #else - /* nothing special */ - #endif +#if defined(STIX_USE_PROCSTK) + LOAD_ACTIVE_SP(stix); +#else + /* nothing special */ +#endif - /* activate the suspended context of the new process */ - SWITCH_ACTIVE_CONTEXT (stix, proc->runnable_context); + /* activate the suspended context of the new process */ + SWITCH_ACTIVE_CONTEXT (stix, proc->current_context); #if defined(STIX_DEBUG_PROCESSOR) printf ("ACTUAL PROCESS SWITCHING AF...%d %p\n", (int)stix->ip, stix->active_context); #endif - } + + stix->proc_switched = 1; } -static void switch_to_next_process (stix_t* stix) +static STIX_INLINE stix_oop_process_t find_next_runnable_process (stix_t* stix) { -/* TODO: this is experimental. rewrite it */ - if ((stix_oop_t)stix->processor->active->next == stix->_nil) - { -#if defined(STIX_DEBUG_PROCESSOR) -printf ("SWITCHING TO THE HEAD PROCESS\n"); -#endif - switch_process (stix, stix->processor->head); - } - else - { -#if defined(STIX_DEBUG_PROCESSOR) -printf ("SWITCHING TO THE NEXT PROCESS\n"); -#endif - switch_process (stix, stix->processor->active->next); - } + stix_oop_process_t npr; + STIX_ASSERT (stix->processor->active->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING)); + npr = LIST_NEXT(p_, stix->processor->active); + if (npr == stix->processor->runnable) npr = LIST_HEAD(p_, stix->processor->runnable); + return npr; } -static STIX_INLINE int insert_into_processor (stix_t* stix, stix_oop_process_t proc) +static STIX_INLINE void switch_to_next_runnable_process (stix_t* stix) +{ + stix_oop_process_t nrp; + + nrp = find_next_runnable_process (stix); + if (nrp != stix->processor->active) switch_to_process (stix, nrp); +} + +static STIX_INLINE int chain_into_processor (stix_t* stix, stix_oop_process_t proc) { /* the process is not scheduled at all. * link it to the processor's process list. */ stix_ooi_t tally; - STIX_ASSERT ((stix_oop_t)proc->prev == stix->_nil); - STIX_ASSERT ((stix_oop_t)proc->next == stix->_nil); + STIX_ASSERT ((stix_oop_t)proc->p_prev == stix->_nil); + STIX_ASSERT ((stix_oop_t)proc->p_next == stix->_nil); STIX_ASSERT (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED)); - STIX_ASSERT ((stix_oop_t)proc->runnable_context == stix->_nil); tally = STIX_OOP_TO_SMOOI(stix->processor->tally); - if (tally == 0) - { - /* the process schedule has no process. - * it is the first process */ - STIX_ASSERT (stix->processor->active == stix->nil_process); - stix->processor->head = proc; - stix->processor->tail = proc; - } - else if (tally < STIX_SMOOI_MAX) - { - proc->next = stix->processor->head; - stix->processor->head->prev = proc; - stix->processor->head = proc; - stix->processor->tally = STIX_SMOOI_TO_OOP(tally + 1); - } - else if (tally < 0) - { - stix->errnum = STIX_EINTERN; - return -1; - } - else + STIX_ASSERT (tally >= 0); + if (tally >= STIX_SMOOI_MAX) { #if defined(STIX_DEBUG_PROCESSOR) printf ("TOO MANY PROCESS\n"); @@ -264,6 +245,9 @@ printf ("TOO MANY PROCESS\n"); return -1; } + /* append to the runnable list */ + LIST_CHAIN (p_, LIST_TAIL(p_, stix->processor->runnable), proc, stix->processor->runnable); + tally++; stix->processor->tally = STIX_SMOOI_TO_OOP(tally); #if defined(STIX_DEBUG_PROCESSOR) @@ -273,7 +257,7 @@ printf ("INSERTED PROCESS %d TO PROCESSOR\n", (int)tally); return 0; } -static STIX_INLINE void delete_from_processor (stix_t* stix, stix_oop_process_t proc) +static STIX_INLINE void unchain_from_processor (stix_t* stix, stix_oop_process_t proc) { stix_ooi_t tally; @@ -283,89 +267,93 @@ static STIX_INLINE void delete_from_processor (stix_t* stix, stix_oop_process_t tally = STIX_OOP_TO_SMOOI(stix->processor->tally); STIX_ASSERT (tally > 0); - if ((stix_oop_t)proc->prev != stix->_nil) proc->prev->next = proc->next; - else stix->processor->head = proc->next; - if ((stix_oop_t)proc->next != stix->_nil) proc->next->prev = proc->prev; - else stix->processor->tail = proc->prev; - - proc->prev = (stix_oop_process_t)stix->_nil; - proc->next = (stix_oop_process_t)stix->_nil; + LIST_UNCHAIN (p_, proc); + proc->p_prev = (stix_oop_process_t)stix->_nil; + proc->p_next = (stix_oop_process_t)stix->_nil; tally--; + if (tally <= 0) stix->processor->active = stix->nil_process; stix->processor->tally = STIX_SMOOI_TO_OOP(tally); } static void terminate_process (stix_t* stix, stix_oop_process_t proc) { -/* TODO: - * can a main process be killed? - * can the only process be killed? if so, terminate VM??? */ - if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING) || - proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE) || - proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_WAITING)) /* TODO: is it safe to terminate a waiting process? */ + proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE)) { - stix_ooi_t tally; - - tally = STIX_OOP_TO_SMOOI(stix->processor->tally); - - if ((stix_oop_t)proc->prev != stix->_nil) proc->prev->next = proc->next; - else stix->processor->head = proc->next; - if ((stix_oop_t)proc->next != stix->_nil) proc->next->prev = proc->prev; - else stix->processor->tail = proc->prev; - - proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED); - if (proc == stix->processor->active) proc->runnable_context = stix->active_context; /* not needed but just in case */ - proc->sp = STIX_SMOOI_TO_OOP(-1); /* invalidate the process stack */ - - tally--; - stix->processor->tally = STIX_SMOOI_TO_OOP(tally); - if (tally <= 0) + /* RUNNING/RUNNABLE ---> TERMINATED */ + if (proc == stix->processor->active) { - /* no more process left in the system */ - stix->processor->active = stix->nil_process; + stix_oop_process_t nrp; + + nrp = find_next_runnable_process (stix); + + unchain_from_processor (stix, proc); + proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED); + proc->sp = STIX_SMOOI_TO_OOP(-1); /* invalidate the process stack */ + proc->current_context = proc->initial_context; /* not needed but just in case */ + + if (proc->sem_next) + { + /* it's in the semaphore */ + /* TODO: remove it from the waiting list */ + } + + if (nrp == proc) + { + /* no runnable process after termination */ + STIX_ASSERT (stix->processor->active == stix->nil_process); + } + else + { + switch_to_process (stix, nrp); + } } else { - stix_oop_process_t new_proc; - - if ((stix_oop_t)proc->next == stix->_nil) - new_proc = stix->processor->head; - else new_proc = proc->next; - - switch_process (stix, new_proc); + unchain_from_processor (stix, proc); + proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED); + proc->sp = STIX_SMOOI_TO_OOP(-1); /* invalidate the process stack */ } - - proc->prev = (stix_oop_process_t)stix->_nil; - proc->next = (stix_oop_process_t)stix->_nil; - } -} - -static int resume_process (stix_t* stix, stix_oop_process_t proc) -{ - if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED)) - { - /* the process is terminated already */ - stix->errnum = STIX_EINVAL; /* TODO: more specialized error code? */ - return -1; } else if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED)) { - /* the process is not scheduled at all. it must not exist in the - * process list of the process scheduler. */ - if (insert_into_processor (stix, proc) <= -1) return -1; - - /* SUSPENED -> RUNNING */ - proc->runnable_context = proc->initial_context; - proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE); - switch_process (stix, proc); + /* SUSPENDED ---> TERMINATED */ + proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED); + proc->sp = STIX_SMOOI_TO_OOP(-1); /* invalid the proce stack */ } - else if (stix->processor->active != proc) + else if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_WAITING)) { - switch_process (stix, proc); + /* WAITING ---> TERMINATED */ + /* TODO: */ } +} - return 0; +static void resume_process (stix_t* stix, stix_oop_process_t proc) +{ + if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED)) + { + /* SUSPENED ---> RUNNING */ + + STIX_ASSERT ((stix_oop_t)proc->p_prev == stix->_nil); + STIX_ASSERT ((stix_oop_t)proc->p_next == stix->_nil); + + chain_into_processor (stix, proc); /* TODO: error check */ + + proc->current_context = proc->initial_context; + proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE); + + /*switch_to_process (stix, proc);*/ + } +#if 0 + else if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE)) + { + /* RUNNABLE ---> RUNNING */ + /* TODO: should i allow this? */ + STIX_ASSERT (stix->processor->active != proc); + switch_to_process (stix, proc); + } +#endif } static void suspend_process (stix_t* stix, stix_oop_process_t proc) @@ -373,22 +361,51 @@ static void suspend_process (stix_t* stix, stix_oop_process_t proc) if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING) || proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE)) { - /* RUNNING/RUNNABLE -> SUSPENDED */ - delete_from_processor (stix, proc); - proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED); + /* RUNNING/RUNNABLE ---> SUSPENDED */ + + if (proc == stix->processor->active) + { + stix_oop_process_t nrp; + + nrp = find_next_runnable_process (stix); + + unchain_from_processor (stix, proc); + proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED); + proc->current_context = stix->active_context; + + if (nrp == proc) + { + /* no runnable process after suspension */ + STIX_ASSERT (stix->processor->active == stix->nil_process); + } + else + { + switch_to_process (stix, nrp); + } + } + else + { + unchain_from_processor (stix, proc); + proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED); + } } -#if 0 - else - { - stix->errnum = STIX_EINVAL; /* TODO: more specialized error code? */ - return -1; - } -#endif } -static void schedule_process (stix_t* stix, stix_oop_process_t proc) +static void yield_process (stix_t* stix, stix_oop_process_t proc) { - /* RUNNABLE -> RUNNING */ + if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING)) + { + /* RUNNING --> RUNNABLE */ + + stix_oop_process_t nrp; + + STIX_ASSERT (proc == stix->processor->active); + + nrp = find_next_runnable_process (stix); + /* if there are more than 1 runnable processes, the next + * runnable process must be different from proc */ + if (nrp != proc) switch_to_process (stix, proc); + } } static void signal_semaphore (stix_t* stix, stix_oop_semaphore_t sem) @@ -410,7 +427,7 @@ static void signal_semaphore (stix_t* stix, stix_oop_semaphore_t sem) sem->waiting_tail = (stix_oop_process_t)stix->_nil; proc->sem_next = (stix_oop_process_t)stix->_nil; - resume_process (stix, proc); + resume_process (stix, proc); /* TODO: error check */ } } @@ -458,15 +475,14 @@ static stix_oop_process_t start_initial_process (stix_t* stix, stix_oop_context_ proc = make_process (stix, c); if (!proc) return STIX_NULL; - if (insert_into_processor (stix, proc) <= -1) return STIX_NULL; - proc->runnable_context = proc->initial_context; + if (chain_into_processor (stix, proc) <= -1) return STIX_NULL; proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING); /* skip RUNNABLE and go to RUNNING */ stix->processor->active = proc; /* do somthing that resume_process() would do with less overhead */ - STIX_ASSERT ((stix_oop_t)proc->runnable_context != stix->_nil); - STIX_ASSERT (proc->runnable_context == proc->initial_context); - SWITCH_ACTIVE_CONTEXT (stix, proc->initial_context); + STIX_ASSERT ((stix_oop_t)proc->current_context != stix->_nil); + STIX_ASSERT (proc->current_context == proc->initial_context); + SWITCH_ACTIVE_CONTEXT (stix, proc->current_context); return proc; } @@ -750,9 +766,10 @@ TODO: overcome this problem STIX_ASSERT (stix->processor->active == proc); STIX_ASSERT (stix->processor->active->initial_context == ctx); - STIX_ASSERT (stix->processor->active->runnable_context == ctx); + STIX_ASSERT (stix->processor->active->current_context == ctx); STIX_ASSERT (stix->active_context == ctx); + /* emulate the message sending */ return activate_new_method (stix, mth); } @@ -1290,6 +1307,20 @@ static int prim_block_new_process (stix_t* stix, stix_ooi_t nargs) return 1; } +static int prim_process_resume (stix_t* stix, stix_ooi_t nargs) +{ + stix_oop_t rcv; + STIX_ASSERT (nargs == 0); + + rcv = ACTIVE_STACK_GET(stix, stix->sp); + if (STIX_CLASSOF(stix,rcv) != stix->_process) return 0; + + resume_process (stix, (stix_oop_process_t)rcv); /* TODO: error check */ + + /* keep the receiver in the stack top */ + return 1; +} + static int prim_process_terminate (stix_t* stix, stix_ooi_t nargs) { stix_oop_t rcv; @@ -1304,6 +1335,20 @@ static int prim_process_terminate (stix_t* stix, stix_ooi_t nargs) return 1; } +static int prim_process_yield (stix_t* stix, stix_ooi_t nargs) +{ + stix_oop_t rcv; + STIX_ASSERT (nargs == 0); + + rcv = ACTIVE_STACK_GET(stix, stix->sp); + if (STIX_CLASSOF(stix,rcv) != stix->_process) return 0; + + yield_process (stix, (stix_oop_process_t)rcv); + + /* keep the receiver in the stack top */ + return 1; +} + static int prim_semaphore_signal (stix_t* stix, stix_ooi_t nargs) { stix_oop_t rcv; @@ -1346,13 +1391,7 @@ static int prim_processor_schedule (stix_t* stix, stix_ooi_t nargs) return 0; } - if (resume_process (stix, (stix_oop_process_t)arg) <= -1) - { -printf ("PROCESS SCHEDULE FAILURE...\n"); -/* TODO: Can this be a soft failure? */ - return (stix->errnum == STIX_EPFULL)? 0: -1; - } - + resume_process (stix, (stix_oop_process_t)arg); /* TODO: error check */ return 1; } @@ -2044,7 +2083,9 @@ static prim_t primitives[] = { -1, prim_block_value, "_block_value" }, { -1, prim_block_new_process, "_block_new_process" }, + { 0, prim_process_resume, "_process_resume" }, { 0, prim_process_terminate, "_process_terminate" }, + { 0, prim_process_yield, "_process_yield" }, { 0, prim_semaphore_signal, "_semaphore_signal" }, { 0, prim_semaphore_wait, "_semaphore_wait" }, @@ -2447,6 +2488,8 @@ int stix_execute (stix_t* stix) STIX_ASSERT (stix->active_context != STIX_NULL); + stix->proc_switched = 0; + while (1) { if (stix->processor->active == stix->nil_process) @@ -2455,7 +2498,16 @@ int stix_execute (stix_t* stix) STIX_ASSERT (stix->processor->tally = STIX_SMOOI_TO_OOP(0)); break; } - switch_to_next_process (stix); +/* + else if (stix->processor->active == stix->idle_process) + { +IDLEING WAITING FOR PROCESS WAKE-UP... + } +*/ + + /* TODO: implement different process switching scheme - time-slice or clock based??? */ + if (!stix->proc_switched) { switch_to_next_runnable_process (stix); } + stix->proc_switched = 0; FETCH_BYTE_CODE_TO (stix, bcode); /*while (bcode == BCODE_NOOP) FETCH_BYTE_CODE_TO (stix, bcode);*/ diff --git a/stix/lib/ignite.c b/stix/lib/ignite.c index 30b927e..87707af 100644 --- a/stix/lib/ignite.c +++ b/stix/lib/ignite.c @@ -198,7 +198,6 @@ static int ignite_2 (stix_t* stix) if (!tmp) return -1; stix->sysdic = (stix_oop_set_t)tmp; - /* Create a nil process used to simplify nil check in GC. * only accessible by VM. not exported via the global dictionary. */ tmp = (stix_oop_t)stix_instantiate (stix, stix->_process, STIX_NULL, 0); @@ -210,10 +209,16 @@ static int ignite_2 (stix_t* stix) tmp = (stix_oop_t)stix_instantiate (stix, stix->_process_scheduler, STIX_NULL, 0); if (!tmp) return -1; stix->processor = (stix_oop_process_scheduler_t)tmp; - /* initialize the tally field to 0, keep other fields as nils */ stix->processor->tally = STIX_SMOOI_TO_OOP(0); stix->processor->active = stix->nil_process; + /* Initialize a runnbale process list */ + tmp = (stix_oop_t)stix_instantiate (stix, stix->_process, STIX_NULL, 0); + if (!tmp) return -1; + stix->processor->runnable = (stix_oop_process_t)tmp; + stix->processor->runnable->sp = STIX_SMOOI_TO_OOP(-1); + LIST_INIT (p_, stix->processor->runnable); + /* 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 bf19870..114d2ae 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -237,6 +237,27 @@ #endif +#define LIST_INIT(prefix,pl) ((pl)->prefix ## prev = (pl)->prefix ## next = (pl)) +#define LIST_HEAD(prefix,pl) ((pl)->prefix ## next) +#define LIST_TAIL(prefix,pl) ((pl)->prefix ## prev) +#define LIST_NEXT(prefix,pl) ((pl)->prefix ## next) +#define LIST_PREV(prefix,pl) ((pl)->prefix ## prev) +#define LIST_ISEMPTY(prefix,pl) (LIST_HEAD(prefix,pl) == (pl)) + +#define LIST_CHAIN(prefix,p,x,n) do { \ + stix_oop_process_t pp = (p), nn = (n); \ + (x)->prefix ## prev = (p); \ + (x)->prefix ## next = (n); \ + nn->prefix ## prev = (x); \ + pp->prefix ## next = (x); \ +} while(0) + +#define LIST_UNCHAIN(prefix,x) do { \ + stix_oop_process_t pp = (x)->prefix ## prev, nn = (x)->prefix ## next; \ + nn->prefix ## prev = pp; pp->prefix ## next = nn; \ +} while (0) + + #if defined(STIX_INCLUDE_COMPILER) /* ========================================================================= */ diff --git a/stix/lib/stix.h b/stix/lib/stix.h index 2563cee..1757db6 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -547,10 +547,10 @@ struct stix_process_t { STIX_OBJ_HEADER; stix_oop_context_t initial_context; - stix_oop_context_t runnable_context; + stix_oop_context_t current_context; stix_oop_t state; /* SmallInteger */ - stix_oop_process_t prev; - stix_oop_process_t next; + stix_oop_process_t p_prev; + stix_oop_process_t p_next; stix_oop_t sp; /* stack pointer. SmallInteger */ stix_oop_process_t sem_next; @@ -569,19 +569,17 @@ struct stix_semaphore_t stix_oop_process_t waiting_tail; /* nil or Process */ }; -#define STIX_PROCESS_SCHEDULER_NAMED_INSTVARS 4 +#define STIX_PROCESS_SCHEDULER_NAMED_INSTVARS 3 typedef struct stix_process_scheduler_t stix_process_scheduler_t; typedef struct stix_process_scheduler_t* stix_oop_process_scheduler_t; struct stix_process_scheduler_t { STIX_OBJ_HEADER; - stix_oop_t tally; - stix_oop_process_t head; - stix_oop_process_t tail; - stix_oop_process_t active; + stix_oop_t tally; /* SmallInteger, the number of runnable processes */ + stix_oop_process_t active; /* pointer to an active process in the runnable process list */ + stix_oop_process_t runnable; /* runnable process list */ }; - /** * The STIX_CLASSOF() macro return the class of an object including a numeric * object encoded into a pointer. @@ -777,6 +775,7 @@ struct stix_t stix_oob_t* active_code; stix_ooi_t sp; stix_ooi_t ip; + int proc_switched; /* TODO: this is temporary. implement something else to skip immediate context switching */ /* == END EXECUTION REGISTERS == */ /* == BIGINT CONVERSION == */