changed the list manupluation style in managing process switching
This commit is contained in:
parent
734082db91
commit
351239bdf4
@ -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.
|
||||
<primitive: #_process_resume>
|
||||
self primitiveFailed
|
||||
|
||||
##^Processor resume: self.
|
||||
}
|
||||
|
||||
#method terminate
|
||||
@ -67,6 +70,12 @@
|
||||
self primitiveFailed
|
||||
}
|
||||
|
||||
#method yield
|
||||
{
|
||||
<primitive: #_process_yield>
|
||||
self primitiveFailed
|
||||
}
|
||||
|
||||
#method sp
|
||||
{
|
||||
^sp.
|
||||
@ -96,7 +105,7 @@
|
||||
|
||||
#class ProcessScheduler(Object)
|
||||
{
|
||||
#dcl tally head tail active.
|
||||
#dcl tally active runnable.
|
||||
|
||||
#method new
|
||||
{
|
||||
|
318
stix/lib/exec.c
318
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,10 +160,12 @@ 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)
|
||||
{
|
||||
/* 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));
|
||||
|
||||
@ -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);
|
||||
#endif
|
||||
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
STORE_ACTIVE_SP(stix);
|
||||
#else
|
||||
#else
|
||||
/* nothing special */
|
||||
#endif
|
||||
#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->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;
|
||||
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
LOAD_ACTIVE_SP(stix);
|
||||
#else
|
||||
#else
|
||||
/* nothing special */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* 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)
|
||||
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;
|
||||
/* RUNNING/RUNNABLE ---> TERMINATED */
|
||||
if (proc == stix->processor->active)
|
||||
{
|
||||
stix_oop_process_t nrp;
|
||||
|
||||
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;
|
||||
nrp = find_next_runnable_process (stix);
|
||||
|
||||
unchain_from_processor (stix, proc);
|
||||
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->current_context = proc->initial_context; /* not needed but just in case */
|
||||
|
||||
tally--;
|
||||
stix->processor->tally = STIX_SMOOI_TO_OOP(tally);
|
||||
if (tally <= 0)
|
||||
if (proc->sem_next)
|
||||
{
|
||||
/* no more process left in the system */
|
||||
stix->processor->active = stix->nil_process;
|
||||
/* 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
|
||||
{
|
||||
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);
|
||||
switch_to_process (stix, nrp);
|
||||
}
|
||||
|
||||
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))
|
||||
else
|
||||
{
|
||||
/* the process is terminated already */
|
||||
stix->errnum = STIX_EINVAL; /* TODO: more specialized error code? */
|
||||
return -1;
|
||||
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 */
|
||||
}
|
||||
}
|
||||
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);
|
||||
/* 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);
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
stix->errnum = STIX_EINVAL; /* TODO: more specialized error code? */
|
||||
return -1;
|
||||
switch_to_process (stix, nrp);
|
||||
}
|
||||
}
|
||||
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)
|
||||
@ -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);*/
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -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 == */
|
||||
|
Loading…
x
Reference in New Issue
Block a user