added more code for process scheduling
This commit is contained in:
parent
f52356e8c8
commit
3482c99ab7
@ -1,6 +1,5 @@
|
|||||||
#class Boolean(Object)
|
#class Boolean(Object)
|
||||||
{
|
{
|
||||||
|
|
||||||
"TODO: do i need to really define methods defined in True and False here?
|
"TODO: do i need to really define methods defined in True and False here?
|
||||||
and call subclassResponsibiltiy?"
|
and call subclassResponsibiltiy?"
|
||||||
}
|
}
|
||||||
@ -75,7 +74,6 @@
|
|||||||
^aBlock value
|
^aBlock value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#method ifTrue: trueBlock ifFalse: falseBlock
|
#method ifTrue: trueBlock ifFalse: falseBlock
|
||||||
{
|
{
|
||||||
^falseBlock value.
|
^falseBlock value.
|
||||||
|
@ -42,13 +42,14 @@
|
|||||||
#method fork
|
#method fork
|
||||||
{
|
{
|
||||||
"crate a new process in the runnable state"
|
"crate a new process in the runnable state"
|
||||||
## TODO
|
^self newProcess resume.
|
||||||
}
|
}
|
||||||
|
|
||||||
#method newProcess
|
#method newProcess
|
||||||
{
|
{
|
||||||
"create a new process in the suspended state"
|
"create a new process in the suspended state"
|
||||||
## TODO
|
<primitive: #_block_new_process>
|
||||||
|
self primitiveFailed.
|
||||||
}
|
}
|
||||||
|
|
||||||
#method newProcessWith: anArray
|
#method newProcessWith: anArray
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#class(#pointer) Process(Object)
|
#class(#pointer) Process(Object)
|
||||||
{
|
{
|
||||||
#dcl sp state prev next.
|
#dcl context state prev next.
|
||||||
|
|
||||||
#method prev
|
#method prev
|
||||||
{
|
{
|
||||||
@ -21,6 +21,12 @@
|
|||||||
{
|
{
|
||||||
self.prev := aProcess.
|
self.prev := aProcess.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#method resume
|
||||||
|
{
|
||||||
|
^Scheduler resume: self.
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#class ProcessScheduler(Object)
|
#class ProcessScheduler(Object)
|
||||||
@ -56,12 +62,22 @@
|
|||||||
].
|
].
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#method resume: aProcess
|
||||||
|
{
|
||||||
|
self add: aProcess.
|
||||||
|
self.active := aProcess.
|
||||||
|
}
|
||||||
|
|
||||||
#method remove: aProcess
|
#method remove: aProcess
|
||||||
{
|
{
|
||||||
"<primitive: #_scheduler_remove>"
|
"<primitive: #_scheduler_remove>"
|
||||||
|
|
||||||
"TODO: "
|
"TODO: "
|
||||||
|
}
|
||||||
|
|
||||||
|
#method suspendActive
|
||||||
|
{
|
||||||
|
" TODO: .........."
|
||||||
}
|
}
|
||||||
|
|
||||||
"
|
"
|
||||||
|
@ -241,9 +241,16 @@
|
|||||||
ffi close.
|
ffi close.
|
||||||
"
|
"
|
||||||
|
|
||||||
self abc.
|
| p |
|
||||||
self abc.
|
'000000000000000000' dump.
|
||||||
self abc.
|
p := [ 'xxxxxxxxxxxxxxxxx' dump. 'yyyyyyyyyyyyyyyyyyyyyyyyyy' dump. ] newProcess.
|
||||||
|
'999999999999999999' dump.
|
||||||
|
p resume.
|
||||||
|
|
||||||
|
'111111111111111111' dump.
|
||||||
|
'222222222222222222' dump.
|
||||||
|
'333333333333333333' dump.
|
||||||
|
'444444444444444444' dump.
|
||||||
|
|
||||||
"
|
"
|
||||||
FFI isNil dump.
|
FFI isNil dump.
|
||||||
|
122
stix/lib/exec.c
122
stix/lib/exec.c
@ -100,6 +100,84 @@
|
|||||||
# define DBGOUT_EXEC_3(fmt,a1,a2,a3)
|
# define DBGOUT_EXEC_3(fmt,a1,a2,a3)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
/*TODO: set the state to RUNNING */
|
||||||
|
stix->scheduler->active = proc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void switch_to_next_process (stix_t* stix)
|
||||||
|
{
|
||||||
|
/* TODO: this is experimental. rewrite it */
|
||||||
|
if (stix->scheduler->active->next == stix->_nil)
|
||||||
|
{
|
||||||
|
switch_process (stix, stix->scheduler->head);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch_process (stix, stix->scheduler->active->next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth)
|
static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth)
|
||||||
{
|
{
|
||||||
@ -337,6 +415,7 @@ static int activate_initial_context (stix_t* stix, const stix_ucs_t* objname, co
|
|||||||
stix_oop_context_t ctx;
|
stix_oop_context_t ctx;
|
||||||
stix_oop_association_t ass;
|
stix_oop_association_t ass;
|
||||||
stix_oop_method_t mth;
|
stix_oop_method_t mth;
|
||||||
|
stix_oop_process_t proc;
|
||||||
|
|
||||||
/* create a fake initial context */
|
/* create a fake initial context */
|
||||||
ctx = (stix_oop_context_t)stix_instantiate (stix, stix->_method_context, STIX_NULL, 1);
|
ctx = (stix_oop_context_t)stix_instantiate (stix, stix->_method_context, STIX_NULL, 1);
|
||||||
@ -369,20 +448,30 @@ TODO: overcome this problem
|
|||||||
|
|
||||||
ctx->origin = ctx;
|
ctx->origin = ctx;
|
||||||
ctx->method_or_nargs = (stix_oop_t)mth; /* fake. help SWITCH_ACTIVE_CONTEXT() not fail*/
|
ctx->method_or_nargs = (stix_oop_t)mth; /* fake. help SWITCH_ACTIVE_CONTEXT() not fail*/
|
||||||
/* receiver, sender of ctx are nils */
|
|
||||||
|
/* [NOTE]
|
||||||
|
* the receiver field and the sender field of ctx are nils.
|
||||||
|
* especially, the fact that the sender field is nil is used by
|
||||||
|
* the main execution loop for breaking out of the loop */
|
||||||
|
|
||||||
STIX_ASSERT (stix->active_context == STIX_NULL);
|
STIX_ASSERT (stix->active_context == STIX_NULL);
|
||||||
/* i can't use SWITCH_ACTIVE_CONTEXT() macro as there is no active context before switching */
|
/* i can't use SWITCH_ACTIVE_CONTEXT() macro as there is no active
|
||||||
|
* context before switching. let's force set active_context to ctx
|
||||||
|
* directly. */
|
||||||
stix->active_context = ctx;
|
stix->active_context = ctx;
|
||||||
ACTIVE_STACK_PUSH (stix, ass->value); /* push the receiver */
|
ACTIVE_STACK_PUSH (stix, ass->value); /* push the receiver */
|
||||||
|
|
||||||
STORE_ACTIVE_IP (stix);
|
STORE_ACTIVE_IP (stix);
|
||||||
STORE_ACTIVE_SP (stix);
|
STORE_ACTIVE_SP (stix);
|
||||||
|
|
||||||
|
stix_pushtmp (stix, (stix_oop_t*)&mth);
|
||||||
|
proc = start_new_process (stix, ctx);
|
||||||
|
stix_poptmp (stix);
|
||||||
|
if (!proc) return -1;
|
||||||
|
|
||||||
return activate_new_method (stix, mth);
|
return activate_new_method (stix, mth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
static int prim_dump (stix_t* stix, stix_ooi_t nargs)
|
static int prim_dump (stix_t* stix, stix_ooi_t nargs)
|
||||||
{
|
{
|
||||||
@ -771,6 +860,27 @@ printf ("<<ENTERING BLOCK>>\n");
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int prim_block_new_process (stix_t* stix, stix_ooi_t nargs)
|
||||||
|
{
|
||||||
|
stix_oop_process_t proc;
|
||||||
|
stix_oop_context_t rcv;
|
||||||
|
|
||||||
|
rcv = (stix_oop_context_t)ACTIVE_STACK_GETTOP(stix);
|
||||||
|
if (STIX_CLASSOF(stix, rcv) != stix->_block_context)
|
||||||
|
{
|
||||||
|
#if defined(STIX_DEBUG_EXEC)
|
||||||
|
printf ("PRIMITVE VALUE RECEIVER IS NOT A BLOCK CONTEXT\n");
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc = make_process (stix, rcv);
|
||||||
|
if (!proc) return -1; /* hard failure */ /* TOOD: can't this be a soft failure? */
|
||||||
|
|
||||||
|
ACTIVE_STACK_SETTOP (stix, (stix_oop_t)proc);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int prim_integer_add (stix_t* stix, stix_ooi_t nargs)
|
static int prim_integer_add (stix_t* stix, stix_ooi_t nargs)
|
||||||
{
|
{
|
||||||
stix_ooi_t tmp;
|
stix_ooi_t tmp;
|
||||||
@ -1319,6 +1429,7 @@ static prim_t primitives[] =
|
|||||||
{ 2, prim_basic_at_put, "_basic_at_put" },
|
{ 2, prim_basic_at_put, "_basic_at_put" },
|
||||||
|
|
||||||
{ -1, prim_block_value, "_block_value" },
|
{ -1, prim_block_value, "_block_value" },
|
||||||
|
{ 0, prim_block_new_process, "_block_new_process" },
|
||||||
|
|
||||||
{ 1, prim_integer_add, "_integer_add" },
|
{ 1, prim_integer_add, "_integer_add" },
|
||||||
{ 1, prim_integer_sub, "_integer_sub" },
|
{ 1, prim_integer_sub, "_integer_sub" },
|
||||||
@ -1519,6 +1630,8 @@ int stix_execute (stix_t* stix)
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
switch_to_next_process (stix);
|
||||||
#if 0
|
#if 0
|
||||||
printf ("IP => %d ", (int)stix->ip);
|
printf ("IP => %d ", (int)stix->ip);
|
||||||
#endif
|
#endif
|
||||||
@ -2498,11 +2611,8 @@ oops:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int stix_invoke (stix_t* stix, const stix_ucs_t* objname, const stix_ucs_t* mthname)
|
int stix_invoke (stix_t* stix, const stix_ucs_t* objname, const stix_ucs_t* mthname)
|
||||||
{
|
{
|
||||||
/*stix_oop_process_t proc;*/
|
|
||||||
|
|
||||||
if (activate_initial_context (stix, objname, mthname) <= -1) return -1;
|
if (activate_initial_context (stix, objname, mthname) <= -1) return -1;
|
||||||
return stix_execute (stix);
|
return stix_execute (stix);
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ static int ignite_3 (stix_t* stix)
|
|||||||
if (!stix_putatsysdic(stix, sym, (stix_oop_t)stix->sysdic)) return -1;
|
if (!stix_putatsysdic(stix, sym, (stix_oop_t)stix->sysdic)) return -1;
|
||||||
|
|
||||||
/* Make the process scheduler avaialble as the global name 'Scheduler' */
|
/* Make the process scheduler avaialble as the global name 'Scheduler' */
|
||||||
sym = stix_makesymbol (stix, str_scheduler, 4);
|
sym = stix_makesymbol (stix, str_scheduler, 9);
|
||||||
if (!sym) return -1;
|
if (!sym) return -1;
|
||||||
if (!stix_putatsysdic(stix, sym, (stix_oop_t)stix->scheduler)) return -1;
|
if (!stix_putatsysdic(stix, sym, (stix_oop_t)stix->scheduler)) return -1;
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include "stix-prv.h"
|
#include "stix-prv.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
stix_oop_process_t stix_addnewproc (stix_t* stix)
|
stix_oop_process_t stix_addnewproc (stix_t* stix)
|
||||||
{
|
{
|
||||||
stix_oop_process_t proc;
|
stix_oop_process_t proc;
|
||||||
|
@ -456,7 +456,7 @@ struct stix_context_t
|
|||||||
* moment the block context was created. */
|
* moment the block context was created. */
|
||||||
stix_oop_t home;
|
stix_oop_t home;
|
||||||
|
|
||||||
/* when a method context is craeted, it is set to itself.
|
/* when a method context is created, it is set to itself.
|
||||||
* no change is made when the method context is activated.
|
* no change is made when the method context is activated.
|
||||||
* when a block context is created, it is set to nil.
|
* when a block context is created, it is set to nil.
|
||||||
* when the block context is shallow-copied for activation,
|
* when the block context is shallow-copied for activation,
|
||||||
@ -467,17 +467,6 @@ struct stix_context_t
|
|||||||
stix_oop_t slot[1]; /* stack */
|
stix_oop_t slot[1]; /* stack */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define STIX_PROCESS_SCHEDULER_NAMED_INSTVARS 4
|
|
||||||
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_t head;
|
|
||||||
stix_oop_t tail;
|
|
||||||
stix_oop_t active;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define STIX_PROCESS_NAMED_INSTVARS 4
|
#define STIX_PROCESS_NAMED_INSTVARS 4
|
||||||
typedef struct stix_process_t stix_process_t;
|
typedef struct stix_process_t stix_process_t;
|
||||||
@ -485,15 +474,27 @@ typedef struct stix_process_t* stix_oop_process_t;
|
|||||||
struct stix_process_t
|
struct stix_process_t
|
||||||
{
|
{
|
||||||
STIX_OBJ_HEADER;
|
STIX_OBJ_HEADER;
|
||||||
stix_oop_t sp;
|
stix_oop_context_t context;
|
||||||
stix_oop_t state;
|
stix_oop_t state;
|
||||||
stix_oop_t prev;
|
stix_oop_process_t prev;
|
||||||
stix_oop_t next;
|
stix_oop_process_t next;
|
||||||
|
|
||||||
/* == variable indexed part == */
|
/* == variable indexed part == */
|
||||||
stix_oop_t slot[1]; /* process stack */
|
stix_oop_t slot[1]; /* process stack */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define STIX_PROCESS_SCHEDULER_NAMED_INSTVARS 4
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
Loading…
Reference in New Issue
Block a user