changed the list manupluation style in managing process switching

This commit is contained in:
hyunghwan.chung 2016-02-19 15:52:56 +00:00
parent 734082db91
commit 351239bdf4
5 changed files with 258 additions and 172 deletions

View File

@ -28,7 +28,7 @@
#class(#pointer) Process(Object) #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 #method new
{ {
@ -58,7 +58,10 @@
#method resume #method resume
{ {
^Processor resume: self. <primitive: #_process_resume>
self primitiveFailed
##^Processor resume: self.
} }
#method terminate #method terminate
@ -67,6 +70,12 @@
self primitiveFailed self primitiveFailed
} }
#method yield
{
<primitive: #_process_yield>
self primitiveFailed
}
#method sp #method sp
{ {
^sp. ^sp.
@ -96,7 +105,7 @@
#class ProcessScheduler(Object) #class ProcessScheduler(Object)
{ {
#dcl tally head tail active. #dcl tally active runnable.
#method new #method new
{ {

View File

@ -140,7 +140,6 @@
#endif #endif
static stix_oop_process_t make_process (stix_t* stix, stix_oop_context_t c) static stix_oop_process_t make_process (stix_t* stix, stix_oop_context_t c)
{ {
stix_oop_process_t proc; 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->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED);
proc->initial_context = c; proc->initial_context = c;
proc->current_context = c;
proc->sp = STIX_SMOOI_TO_OOP(-1); proc->sp = STIX_SMOOI_TO_OOP(-1);
#if defined(STIX_DEBUG_PROCESSOR) #if defined(STIX_DEBUG_PROCESSOR)
@ -160,10 +160,12 @@ printf ("PROCESS %p SIZE => %ld\n", proc, (long int)STIX_OBJ_GET_SIZE(proc));
return 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) /* 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) || STIX_ASSERT (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE) ||
proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_WAITING)); proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_WAITING));
@ -171,91 +173,70 @@ static void switch_process (stix_t* stix, stix_oop_process_t proc)
printf ("ACTUAL PROCESS SWITCHING BF...%d %p\n", (int)stix->ip, stix->active_context); printf ("ACTUAL PROCESS SWITCHING BF...%d %p\n", (int)stix->ip, stix->active_context);
#endif #endif
#if defined(STIX_USE_PROCSTK) #if defined(STIX_USE_PROCSTK)
STORE_ACTIVE_SP(stix); STORE_ACTIVE_SP(stix);
#else #else
/* nothing special */ /* nothing special */
#endif #endif
/* store the current active context to the current process. /* store the current active context to the current process.
* it is the suspended context of the process to be suspended */ * it is the suspended context of the process to be suspended */
STIX_ASSERT ((stix_oop_t)stix->processor->active != stix->_nil); STIX_ASSERT ((stix_oop_t)stix->processor->active != stix->_nil);
stix->processor->active->runnable_context = stix->active_context; stix->processor->active->current_context = stix->active_context;
stix->processor->active->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE); stix->processor->active->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE);
/* activate the given process */ /* activate the given process */
proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING); proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING);
stix->processor->active = proc; stix->processor->active = proc;
#if defined(STIX_USE_PROCSTK) #if defined(STIX_USE_PROCSTK)
LOAD_ACTIVE_SP(stix); LOAD_ACTIVE_SP(stix);
#else #else
/* nothing special */ /* nothing special */
#endif #endif
/* activate the suspended context of the new process */ /* activate the suspended context of the new process */
SWITCH_ACTIVE_CONTEXT (stix, proc->runnable_context); SWITCH_ACTIVE_CONTEXT (stix, proc->current_context);
#if defined(STIX_DEBUG_PROCESSOR) #if defined(STIX_DEBUG_PROCESSOR)
printf ("ACTUAL PROCESS SWITCHING AF...%d %p\n", (int)stix->ip, stix->active_context); printf ("ACTUAL PROCESS SWITCHING AF...%d %p\n", (int)stix->ip, stix->active_context);
#endif #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 */ stix_oop_process_t npr;
if ((stix_oop_t)stix->processor->active->next == stix->_nil) STIX_ASSERT (stix->processor->active->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING));
{ npr = LIST_NEXT(p_, stix->processor->active);
#if defined(STIX_DEBUG_PROCESSOR) if (npr == stix->processor->runnable) npr = LIST_HEAD(p_, stix->processor->runnable);
printf ("SWITCHING TO THE HEAD PROCESS\n"); return npr;
#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);
}
} }
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. /* the process is not scheduled at all.
* link it to the processor's process list. */ * link it to the processor's process list. */
stix_ooi_t tally; stix_ooi_t tally;
STIX_ASSERT ((stix_oop_t)proc->prev == stix->_nil); STIX_ASSERT ((stix_oop_t)proc->p_prev == stix->_nil);
STIX_ASSERT ((stix_oop_t)proc->next == 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 (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); 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_ASSERT (tally >= 0);
stix->processor->tail = proc; if (tally >= STIX_SMOOI_MAX)
}
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
{ {
#if defined(STIX_DEBUG_PROCESSOR) #if defined(STIX_DEBUG_PROCESSOR)
printf ("TOO MANY PROCESS\n"); printf ("TOO MANY PROCESS\n");
@ -264,6 +245,9 @@ printf ("TOO MANY PROCESS\n");
return -1; return -1;
} }
/* append to the runnable list */
LIST_CHAIN (p_, LIST_TAIL(p_, stix->processor->runnable), proc, stix->processor->runnable);
tally++; tally++;
stix->processor->tally = STIX_SMOOI_TO_OOP(tally); stix->processor->tally = STIX_SMOOI_TO_OOP(tally);
#if defined(STIX_DEBUG_PROCESSOR) #if defined(STIX_DEBUG_PROCESSOR)
@ -273,7 +257,7 @@ printf ("INSERTED PROCESS %d TO PROCESSOR\n", (int)tally);
return 0; 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; 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); tally = STIX_OOP_TO_SMOOI(stix->processor->tally);
STIX_ASSERT (tally > 0); STIX_ASSERT (tally > 0);
if ((stix_oop_t)proc->prev != stix->_nil) proc->prev->next = proc->next; LIST_UNCHAIN (p_, proc);
else stix->processor->head = proc->next; proc->p_prev = (stix_oop_process_t)stix->_nil;
if ((stix_oop_t)proc->next != stix->_nil) proc->next->prev = proc->prev; proc->p_next = (stix_oop_process_t)stix->_nil;
else stix->processor->tail = proc->prev;
proc->prev = (stix_oop_process_t)stix->_nil;
proc->next = (stix_oop_process_t)stix->_nil;
tally--; tally--;
if (tally <= 0) stix->processor->active = stix->nil_process;
stix->processor->tally = STIX_SMOOI_TO_OOP(tally); stix->processor->tally = STIX_SMOOI_TO_OOP(tally);
} }
static void terminate_process (stix_t* stix, stix_oop_process_t proc) 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) || 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_RUNNABLE))
proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_WAITING)) /* TODO: is it safe to terminate a waiting process? */
{ {
stix_ooi_t tally; /* RUNNING/RUNNABLE ---> TERMINATED */
if (proc == stix->processor->active)
{
stix_oop_process_t nrp;
tally = STIX_OOP_TO_SMOOI(stix->processor->tally); nrp = find_next_runnable_process (stix);
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;
unchain_from_processor (stix, proc);
proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED); 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 */ proc->sp = STIX_SMOOI_TO_OOP(-1); /* invalidate the process stack */
proc->current_context = proc->initial_context; /* not needed but just in case */
tally--; if (proc->sem_next)
stix->processor->tally = STIX_SMOOI_TO_OOP(tally);
if (tally <= 0)
{ {
/* no more process left in the system */ /* it's in the semaphore */
stix->processor->active = stix->nil_process; /* TODO: remove it from the waiting list */
}
if (nrp == proc)
{
/* no runnable process after termination */
STIX_ASSERT (stix->processor->active == stix->nil_process);
} }
else else
{ {
stix_oop_process_t new_proc; switch_to_process (stix, nrp);
if ((stix_oop_t)proc->next == stix->_nil)
new_proc = stix->processor->head;
else new_proc = proc->next;
switch_process (stix, new_proc);
} }
proc->prev = (stix_oop_process_t)stix->_nil;
proc->next = (stix_oop_process_t)stix->_nil;
} }
} else
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 */ unchain_from_processor (stix, proc);
stix->errnum = STIX_EINVAL; /* TODO: more specialized error code? */ proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED);
return -1; proc->sp = STIX_SMOOI_TO_OOP(-1); /* invalidate the process stack */
}
} }
else if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED)) else if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED))
{ {
/* the process is not scheduled at all. it must not exist in the /* SUSPENDED ---> TERMINATED */
* process list of the process scheduler. */ proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED);
if (insert_into_processor (stix, proc) <= -1) return -1; proc->sp = STIX_SMOOI_TO_OOP(-1); /* invalid the proce stack */
/* SUSPENED -> RUNNING */
proc->runnable_context = proc->initial_context;
proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE);
switch_process (stix, proc);
} }
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) 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) || 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_RUNNABLE))
{ {
/* RUNNING/RUNNABLE -> SUSPENDED */ /* RUNNING/RUNNABLE ---> SUSPENDED */
delete_from_processor (stix, proc);
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->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);
} }
#if 0
else else
{ {
stix->errnum = STIX_EINVAL; /* TODO: more specialized error code? */ switch_to_process (stix, nrp);
return -1; }
}
else
{
unchain_from_processor (stix, proc);
proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED);
}
} }
#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) 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; sem->waiting_tail = (stix_oop_process_t)stix->_nil;
proc->sem_next = (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); proc = make_process (stix, c);
if (!proc) return STIX_NULL; if (!proc) return STIX_NULL;
if (insert_into_processor (stix, proc) <= -1) return STIX_NULL; if (chain_into_processor (stix, proc) <= -1) return STIX_NULL;
proc->runnable_context = proc->initial_context;
proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING); /* skip RUNNABLE and go to RUNNING */ proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING); /* skip RUNNABLE and go to RUNNING */
stix->processor->active = proc; stix->processor->active = proc;
/* do somthing that resume_process() would do with less overhead */ /* do somthing that resume_process() would do with less overhead */
STIX_ASSERT ((stix_oop_t)proc->runnable_context != stix->_nil); STIX_ASSERT ((stix_oop_t)proc->current_context != stix->_nil);
STIX_ASSERT (proc->runnable_context == proc->initial_context); STIX_ASSERT (proc->current_context == proc->initial_context);
SWITCH_ACTIVE_CONTEXT (stix, proc->initial_context); SWITCH_ACTIVE_CONTEXT (stix, proc->current_context);
return proc; return proc;
} }
@ -750,9 +766,10 @@ TODO: overcome this problem
STIX_ASSERT (stix->processor->active == proc); STIX_ASSERT (stix->processor->active == proc);
STIX_ASSERT (stix->processor->active->initial_context == ctx); 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); STIX_ASSERT (stix->active_context == ctx);
/* emulate the message sending */ /* emulate the message sending */
return activate_new_method (stix, mth); 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; 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) static int prim_process_terminate (stix_t* stix, stix_ooi_t nargs)
{ {
stix_oop_t rcv; stix_oop_t rcv;
@ -1304,6 +1335,20 @@ static int prim_process_terminate (stix_t* stix, stix_ooi_t nargs)
return 1; 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) static int prim_semaphore_signal (stix_t* stix, stix_ooi_t nargs)
{ {
stix_oop_t rcv; stix_oop_t rcv;
@ -1346,13 +1391,7 @@ static int prim_processor_schedule (stix_t* stix, stix_ooi_t nargs)
return 0; return 0;
} }
if (resume_process (stix, (stix_oop_process_t)arg) <= -1) resume_process (stix, (stix_oop_process_t)arg); /* TODO: error check */
{
printf ("PROCESS SCHEDULE FAILURE...\n");
/* TODO: Can this be a soft failure? */
return (stix->errnum == STIX_EPFULL)? 0: -1;
}
return 1; return 1;
} }
@ -2044,7 +2083,9 @@ static prim_t primitives[] =
{ -1, prim_block_value, "_block_value" }, { -1, prim_block_value, "_block_value" },
{ -1, prim_block_new_process, "_block_new_process" }, { -1, prim_block_new_process, "_block_new_process" },
{ 0, prim_process_resume, "_process_resume" },
{ 0, prim_process_terminate, "_process_terminate" }, { 0, prim_process_terminate, "_process_terminate" },
{ 0, prim_process_yield, "_process_yield" },
{ 0, prim_semaphore_signal, "_semaphore_signal" }, { 0, prim_semaphore_signal, "_semaphore_signal" },
{ 0, prim_semaphore_wait, "_semaphore_wait" }, { 0, prim_semaphore_wait, "_semaphore_wait" },
@ -2447,6 +2488,8 @@ int stix_execute (stix_t* stix)
STIX_ASSERT (stix->active_context != STIX_NULL); STIX_ASSERT (stix->active_context != STIX_NULL);
stix->proc_switched = 0;
while (1) while (1)
{ {
if (stix->processor->active == stix->nil_process) 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)); STIX_ASSERT (stix->processor->tally = STIX_SMOOI_TO_OOP(0));
break; 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); FETCH_BYTE_CODE_TO (stix, bcode);
/*while (bcode == BCODE_NOOP) FETCH_BYTE_CODE_TO (stix, bcode);*/ /*while (bcode == BCODE_NOOP) FETCH_BYTE_CODE_TO (stix, bcode);*/

View File

@ -198,7 +198,6 @@ static int ignite_2 (stix_t* stix)
if (!tmp) return -1; if (!tmp) return -1;
stix->sysdic = (stix_oop_set_t)tmp; stix->sysdic = (stix_oop_set_t)tmp;
/* Create a nil process used to simplify nil check in GC. /* Create a nil process used to simplify nil check in GC.
* only accessible by VM. not exported via the global dictionary. */ * only accessible by VM. not exported via the global dictionary. */
tmp = (stix_oop_t)stix_instantiate (stix, stix->_process, STIX_NULL, 0); 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); tmp = (stix_oop_t)stix_instantiate (stix, stix->_process_scheduler, STIX_NULL, 0);
if (!tmp) return -1; if (!tmp) return -1;
stix->processor = (stix_oop_process_scheduler_t)tmp; 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->tally = STIX_SMOOI_TO_OOP(0);
stix->processor->active = stix->nil_process; 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 */ /* 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; ((stix_oop_class_t)stix->_apex)->slot[0] = (stix_oop_t)stix->sysdic;

View File

@ -237,6 +237,27 @@
#endif #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) #if defined(STIX_INCLUDE_COMPILER)
/* ========================================================================= */ /* ========================================================================= */

View File

@ -547,10 +547,10 @@ struct stix_process_t
{ {
STIX_OBJ_HEADER; STIX_OBJ_HEADER;
stix_oop_context_t initial_context; 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_t state; /* SmallInteger */
stix_oop_process_t prev; stix_oop_process_t p_prev;
stix_oop_process_t next; stix_oop_process_t p_next;
stix_oop_t sp; /* stack pointer. SmallInteger */ stix_oop_t sp; /* stack pointer. SmallInteger */
stix_oop_process_t sem_next; stix_oop_process_t sem_next;
@ -569,19 +569,17 @@ struct stix_semaphore_t
stix_oop_process_t waiting_tail; /* nil or Process */ 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_process_scheduler_t;
typedef struct stix_process_scheduler_t* stix_oop_process_scheduler_t; typedef struct stix_process_scheduler_t* stix_oop_process_scheduler_t;
struct stix_process_scheduler_t struct stix_process_scheduler_t
{ {
STIX_OBJ_HEADER; STIX_OBJ_HEADER;
stix_oop_t tally; stix_oop_t tally; /* SmallInteger, the number of runnable processes */
stix_oop_process_t head; stix_oop_process_t active; /* pointer to an active process in the runnable process list */
stix_oop_process_t tail; stix_oop_process_t runnable; /* runnable process list */
stix_oop_process_t active;
}; };
/** /**
* The STIX_CLASSOF() macro return the class of an object including a numeric * The STIX_CLASSOF() macro return the class of an object including a numeric
* object encoded into a pointer. * object encoded into a pointer.
@ -777,6 +775,7 @@ struct stix_t
stix_oob_t* active_code; stix_oob_t* active_code;
stix_ooi_t sp; stix_ooi_t sp;
stix_ooi_t ip; stix_ooi_t ip;
int proc_switched; /* TODO: this is temporary. implement something else to skip immediate context switching */
/* == END EXECUTION REGISTERS == */ /* == END EXECUTION REGISTERS == */
/* == BIGINT CONVERSION == */ /* == BIGINT CONVERSION == */