added some more code for processing scheduling
This commit is contained in:
parent
3482c99ab7
commit
96011578c8
@ -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
|
||||
{
|
||||
<primitive: #_scheduler_add>
|
||||
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.
|
||||
<primitive: #_scheduler_add>
|
||||
self primitiveFailed.
|
||||
|
||||
"self add: aProcess.
|
||||
TODO: need to change state of a Process???
|
||||
self.active := aProcess."
|
||||
}
|
||||
|
||||
#method remove: aProcess
|
||||
|
@ -243,7 +243,7 @@
|
||||
|
||||
| p |
|
||||
'000000000000000000' dump.
|
||||
p := [ 'xxxxxxxxxxxxxxxxx' dump. 'yyyyyyyyyyyyyyyyyyyyyyyyyy' dump. ] newProcess.
|
||||
p := [ 'xxxxxxxxxxxxxxxxx' dump. 'yyyyyyyyyyyyyyyyyyyyyyyyyy' dump. ^10. ] newProcess.
|
||||
'999999999999999999' dump.
|
||||
p resume.
|
||||
|
||||
|
174
stix/lib/exec.c
174
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<BF> => %d\n", (int)stix->ip);
|
||||
#endif
|
||||
switch_to_next_process (stix);
|
||||
#if 1
|
||||
printf ("IP<AF> => %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 ("<<LEAVING>> 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 ("<<<RETURNIGN TO THE INITIAL CONTEXT>>>\n");
|
||||
#endif
|
||||
STIX_ASSERT (stix->sp == 0);
|
||||
goto done;
|
||||
STIX_ASSERT (stix->sp == 0);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
@ -2441,9 +2485,19 @@ printf ("<<<RETURNIGN TO THE INITIAL CONTEXT>>>\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:
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user