added some code to implement semaphores
This commit is contained in:
parent
fc7a44ba7d
commit
734082db91
@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
#class Delay(Object)
|
#class Delay(Object)
|
||||||
{
|
{
|
||||||
## TODO: support milliseconds or nanoseconds
|
## TODO: support milliseconds or nanoseconds
|
||||||
@ -26,7 +28,7 @@
|
|||||||
|
|
||||||
#class(#pointer) Process(Object)
|
#class(#pointer) Process(Object)
|
||||||
{
|
{
|
||||||
#dcl initial active state prev next sp.
|
#dcl initial_context runnable_context state prev next sp sem_next.
|
||||||
|
|
||||||
#method new
|
#method new
|
||||||
{
|
{
|
||||||
@ -71,6 +73,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#class Semaphore(Object)
|
||||||
|
{
|
||||||
|
#dcl count waiting_head waiting_tail.
|
||||||
|
|
||||||
|
#method initialize
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#method signal
|
||||||
|
{
|
||||||
|
<primitive: #_semaphore_signal>
|
||||||
|
self primitiveFailed.
|
||||||
|
}
|
||||||
|
|
||||||
|
#method wait
|
||||||
|
{
|
||||||
|
<primitive: #_semaphore_wait>
|
||||||
|
self primitiveFailed.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#class ProcessScheduler(Object)
|
#class ProcessScheduler(Object)
|
||||||
{
|
{
|
||||||
#dcl tally head tail active.
|
#dcl tally head tail active.
|
||||||
|
228
stix/lib/exec.c
228
stix/lib/exec.c
@ -26,10 +26,11 @@
|
|||||||
|
|
||||||
#include "stix-prv.h"
|
#include "stix-prv.h"
|
||||||
|
|
||||||
|
|
||||||
#define PROCESS_STATE_RUNNING 3
|
#define PROCESS_STATE_RUNNING 3
|
||||||
#define PROCESS_STATE_BLOCKED 2
|
#define PROCESS_STATE_WAITING 2
|
||||||
#define PROCESS_STATE_SUSPENDED 1
|
#define PROCESS_STATE_RUNNABLE 1
|
||||||
#define PROCESS_STATE_CREATED 0
|
#define PROCESS_STATE_SUSPENDED 0
|
||||||
#define PROCESS_STATE_TERMINATED -1
|
#define PROCESS_STATE_TERMINATED -1
|
||||||
|
|
||||||
#if defined(USE_DYNCALL)
|
#if defined(USE_DYNCALL)
|
||||||
@ -138,6 +139,8 @@
|
|||||||
# 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)
|
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;
|
||||||
@ -147,7 +150,7 @@ static stix_oop_process_t make_process (stix_t* stix, stix_oop_context_t c)
|
|||||||
stix_poptmp (stix);
|
stix_poptmp (stix);
|
||||||
if (!proc) return STIX_NULL;
|
if (!proc) return STIX_NULL;
|
||||||
|
|
||||||
proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_CREATED);
|
proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED);
|
||||||
proc->initial_context = c;
|
proc->initial_context = c;
|
||||||
proc->sp = STIX_SMOOI_TO_OOP(-1);
|
proc->sp = STIX_SMOOI_TO_OOP(-1);
|
||||||
|
|
||||||
@ -161,8 +164,8 @@ static void switch_process (stix_t* stix, stix_oop_process_t proc)
|
|||||||
{
|
{
|
||||||
if (stix->processor->active != proc)
|
if (stix->processor->active != proc)
|
||||||
{
|
{
|
||||||
STIX_ASSERT (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED) ||
|
STIX_ASSERT (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE) ||
|
||||||
proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_BLOCKED));
|
proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_WAITING));
|
||||||
|
|
||||||
#if defined(STIX_DEBUG_PROCESSOR)
|
#if defined(STIX_DEBUG_PROCESSOR)
|
||||||
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);
|
||||||
@ -177,8 +180,8 @@ printf ("ACTUAL PROCESS SWITCHING BF...%d %p\n", (int)stix->ip, stix->active_con
|
|||||||
/* 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->suspended_context = stix->active_context;
|
stix->processor->active->runnable_context = stix->active_context;
|
||||||
stix->processor->active->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED);
|
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);
|
||||||
@ -191,7 +194,7 @@ printf ("ACTUAL PROCESS SWITCHING BF...%d %p\n", (int)stix->ip, stix->active_con
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* activate the suspended context of the new process */
|
/* activate the suspended context of the new process */
|
||||||
SWITCH_ACTIVE_CONTEXT (stix, proc->suspended_context);
|
SWITCH_ACTIVE_CONTEXT (stix, proc->runnable_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);
|
||||||
@ -218,7 +221,7 @@ printf ("SWITCHING TO THE NEXT PROCESS\n");
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static STIX_INLINE int register_new_process (stix_t* stix, stix_oop_process_t proc)
|
static STIX_INLINE int insert_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. */
|
||||||
@ -227,11 +230,11 @@ static STIX_INLINE int register_new_process (stix_t* stix, stix_oop_process_t pr
|
|||||||
STIX_ASSERT ((stix_oop_t)proc->prev == stix->_nil);
|
STIX_ASSERT ((stix_oop_t)proc->prev == stix->_nil);
|
||||||
STIX_ASSERT ((stix_oop_t)proc->next == stix->_nil);
|
STIX_ASSERT ((stix_oop_t)proc->next == stix->_nil);
|
||||||
|
|
||||||
STIX_ASSERT (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_CREATED));
|
STIX_ASSERT (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED));
|
||||||
STIX_ASSERT ((stix_oop_t)proc->suspended_context == stix->_nil);
|
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)
|
if (tally == 0)
|
||||||
{
|
{
|
||||||
/* the process schedule has no process.
|
/* the process schedule has no process.
|
||||||
* it is the first process */
|
* it is the first process */
|
||||||
@ -239,36 +242,59 @@ static STIX_INLINE int register_new_process (stix_t* stix, stix_oop_process_t pr
|
|||||||
|
|
||||||
stix->processor->head = proc;
|
stix->processor->head = proc;
|
||||||
stix->processor->tail = proc;
|
stix->processor->tail = proc;
|
||||||
stix->processor->tally = STIX_SMOOI_TO_OOP(1);
|
|
||||||
#if defined(STIX_DEBUG_PROCESSOR)
|
|
||||||
printf ("ADDED FIRST NEW PROCESS - %d\n", (int)1);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (tally >= STIX_SMOOI_MAX)
|
else if (tally < STIX_SMOOI_MAX)
|
||||||
{
|
|
||||||
#if defined(STIX_DEBUG_PROCESSOR)
|
|
||||||
printf ("TOO MANY PROCESS\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
stix->errnum = STIX_EPFULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
proc->next = stix->processor->head;
|
proc->next = stix->processor->head;
|
||||||
stix->processor->head->prev = proc;
|
stix->processor->head->prev = proc;
|
||||||
stix->processor->head = proc;
|
stix->processor->head = proc;
|
||||||
stix->processor->tally = STIX_SMOOI_TO_OOP(tally + 1);
|
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 ("ADDED NEW PROCESS - %d\n", (int)tally + 1);
|
printf ("TOO MANY PROCESS\n");
|
||||||
#endif
|
#endif
|
||||||
|
stix->errnum = STIX_EPFULL;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED);
|
tally++;
|
||||||
proc->suspended_context = proc->initial_context;
|
stix->processor->tally = STIX_SMOOI_TO_OOP(tally);
|
||||||
|
#if defined(STIX_DEBUG_PROCESSOR)
|
||||||
|
printf ("INSERTED PROCESS %d TO PROCESSOR\n", (int)tally);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static STIX_INLINE void delete_from_processor (stix_t* stix, stix_oop_process_t proc)
|
||||||
|
{
|
||||||
|
stix_ooi_t tally;
|
||||||
|
|
||||||
|
STIX_ASSERT (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING) ||
|
||||||
|
proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE));
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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:
|
/* TODO:
|
||||||
@ -276,21 +302,20 @@ static void terminate_process (stix_t* stix, stix_oop_process_t proc)
|
|||||||
* can the only process be killed? if so, terminate VM??? */
|
* 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_SUSPENDED) ||
|
proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNABLE) ||
|
||||||
proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_BLOCKED))
|
proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_WAITING)) /* TODO: is it safe to terminate a waiting process? */
|
||||||
{
|
{
|
||||||
stix_ooi_t tally;
|
stix_ooi_t tally;
|
||||||
|
|
||||||
tally = STIX_OOP_TO_SMOOI(stix->processor->tally);
|
tally = STIX_OOP_TO_SMOOI(stix->processor->tally);
|
||||||
|
|
||||||
/* the state must be alive */
|
|
||||||
if ((stix_oop_t)proc->prev != stix->_nil) proc->prev->next = proc->next;
|
if ((stix_oop_t)proc->prev != stix->_nil) proc->prev->next = proc->next;
|
||||||
else stix->processor->head = proc->next;
|
else stix->processor->head = proc->next;
|
||||||
if ((stix_oop_t)proc->next != stix->_nil) proc->next->prev = proc->prev;
|
if ((stix_oop_t)proc->next != stix->_nil) proc->next->prev = proc->prev;
|
||||||
else stix->processor->tail = proc->prev;
|
else stix->processor->tail = proc->prev;
|
||||||
|
|
||||||
proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED);
|
proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED);
|
||||||
if (proc == stix->processor->active) proc->suspended_context = stix->active_context; /* not needed but just in case */
|
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 */
|
||||||
|
|
||||||
tally--;
|
tally--;
|
||||||
@ -316,7 +341,7 @@ static void terminate_process (stix_t* stix, stix_oop_process_t proc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int schedule_process (stix_t* stix, stix_oop_process_t proc)
|
static int resume_process (stix_t* stix, stix_oop_process_t proc)
|
||||||
{
|
{
|
||||||
if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED))
|
if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED))
|
||||||
{
|
{
|
||||||
@ -324,11 +349,15 @@ static int schedule_process (stix_t* stix, stix_oop_process_t proc)
|
|||||||
stix->errnum = STIX_EINVAL; /* TODO: more specialized error code? */
|
stix->errnum = STIX_EINVAL; /* TODO: more specialized error code? */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_CREATED))
|
else if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED))
|
||||||
{
|
{
|
||||||
/* the process is not scheduled at all. it must not exist in the
|
/* the process is not scheduled at all. it must not exist in the
|
||||||
* process list of the process scheduler. */
|
* process list of the process scheduler. */
|
||||||
if (register_new_process (stix, proc) <= -1) return -1;
|
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);
|
switch_process (stix, proc);
|
||||||
}
|
}
|
||||||
else if (stix->processor->active != proc)
|
else if (stix->processor->active != proc)
|
||||||
@ -339,6 +368,85 @@ static int schedule_process (stix_t* stix, stix_oop_process_t proc)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
/* RUNNABLE -> RUNNING */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void signal_semaphore (stix_t* stix, stix_oop_semaphore_t sem)
|
||||||
|
{
|
||||||
|
stix_oop_process_t proc;
|
||||||
|
stix_ooi_t count;
|
||||||
|
|
||||||
|
if ((stix_oop_t)sem->waiting_head == stix->_nil)
|
||||||
|
{
|
||||||
|
count = STIX_OOP_TO_SMOOI(sem->count);
|
||||||
|
count++;
|
||||||
|
sem->count = STIX_SMOOI_TO_OOP(count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proc = sem->waiting_head;
|
||||||
|
sem->waiting_head = proc->sem_next;
|
||||||
|
if ((stix_oop_t)sem->waiting_head == stix->_nil)
|
||||||
|
sem->waiting_tail = (stix_oop_process_t)stix->_nil;
|
||||||
|
|
||||||
|
proc->sem_next = (stix_oop_process_t)stix->_nil;
|
||||||
|
resume_process (stix, proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void await_semaphore (stix_t* stix, stix_oop_semaphore_t sem)
|
||||||
|
{
|
||||||
|
stix_oop_process_t proc;
|
||||||
|
stix_ooi_t count;
|
||||||
|
|
||||||
|
count = STIX_OOP_TO_SMOOI(sem->count);
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
count--;
|
||||||
|
sem->count = STIX_SMOOI_TO_OOP(count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proc = stix->processor->active;
|
||||||
|
STIX_ASSERT ((stix_oop_t)proc->sem_next == stix->_nil);
|
||||||
|
|
||||||
|
if ((stix_oop_t)sem->waiting_tail == stix->_nil)
|
||||||
|
{
|
||||||
|
STIX_ASSERT ((stix_oop_t)sem->waiting_head == stix->_nil);
|
||||||
|
sem->waiting_head = proc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
STIX_ASSERT ((stix_oop_t)sem->waiting_head != stix->_nil);
|
||||||
|
sem->waiting_tail->sem_next = proc;
|
||||||
|
}
|
||||||
|
sem->waiting_tail = proc;
|
||||||
|
|
||||||
|
suspend_process (stix, proc);
|
||||||
|
STIX_ASSERT (stix->processor->active != proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static stix_oop_process_t start_initial_process (stix_t* stix, stix_oop_context_t c)
|
static stix_oop_process_t start_initial_process (stix_t* stix, stix_oop_context_t c)
|
||||||
{
|
{
|
||||||
stix_oop_process_t proc;
|
stix_oop_process_t proc;
|
||||||
@ -350,14 +458,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 (register_new_process (stix, proc) <= -1) return STIX_NULL;
|
if (insert_into_processor (stix, proc) <= -1) return STIX_NULL;
|
||||||
|
proc->runnable_context = proc->initial_context;
|
||||||
/*TODO: set the state 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 schedule_process() would do with less overhead */
|
/* do somthing that resume_process() would do with less overhead */
|
||||||
STIX_ASSERT ((stix_oop_t)proc->suspended_context != stix->_nil);
|
STIX_ASSERT ((stix_oop_t)proc->runnable_context != stix->_nil);
|
||||||
STIX_ASSERT (proc->suspended_context == proc->initial_context);
|
STIX_ASSERT (proc->runnable_context == proc->initial_context);
|
||||||
SWITCH_ACTIVE_CONTEXT (stix, proc->initial_context);
|
SWITCH_ACTIVE_CONTEXT (stix, proc->initial_context);
|
||||||
|
|
||||||
return proc;
|
return proc;
|
||||||
@ -642,7 +750,7 @@ 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->suspended_context == ctx);
|
STIX_ASSERT (stix->processor->active->runnable_context == ctx);
|
||||||
STIX_ASSERT (stix->active_context == ctx);
|
STIX_ASSERT (stix->active_context == ctx);
|
||||||
|
|
||||||
/* emulate the message sending */
|
/* emulate the message sending */
|
||||||
@ -1196,6 +1304,34 @@ static int prim_process_terminate (stix_t* stix, stix_ooi_t nargs)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int prim_semaphore_signal (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->_semaphore) return 0;
|
||||||
|
|
||||||
|
signal_semaphore (stix, (stix_oop_semaphore_t)rcv);
|
||||||
|
|
||||||
|
/* keep the receiver in the stack top */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int prim_semaphore_wait (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->_semaphore) return 0;
|
||||||
|
|
||||||
|
await_semaphore (stix, (stix_oop_semaphore_t)rcv);
|
||||||
|
|
||||||
|
/* keep the receiver in the stack top */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int prim_processor_schedule (stix_t* stix, stix_ooi_t nargs)
|
static int prim_processor_schedule (stix_t* stix, stix_ooi_t nargs)
|
||||||
{
|
{
|
||||||
stix_oop_t rcv, arg;
|
stix_oop_t rcv, arg;
|
||||||
@ -1210,7 +1346,7 @@ static int prim_processor_schedule (stix_t* stix, stix_ooi_t nargs)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schedule_process (stix, (stix_oop_process_t)arg) <= -1)
|
if (resume_process (stix, (stix_oop_process_t)arg) <= -1)
|
||||||
{
|
{
|
||||||
printf ("PROCESS SCHEDULE FAILURE...\n");
|
printf ("PROCESS SCHEDULE FAILURE...\n");
|
||||||
/* TODO: Can this be a soft failure? */
|
/* TODO: Can this be a soft failure? */
|
||||||
@ -1909,6 +2045,8 @@ static prim_t primitives[] =
|
|||||||
{ -1, prim_block_new_process, "_block_new_process" },
|
{ -1, prim_block_new_process, "_block_new_process" },
|
||||||
|
|
||||||
{ 0, prim_process_terminate, "_process_terminate" },
|
{ 0, prim_process_terminate, "_process_terminate" },
|
||||||
|
{ 0, prim_semaphore_signal, "_semaphore_signal" },
|
||||||
|
{ 0, prim_semaphore_wait, "_semaphore_wait" },
|
||||||
|
|
||||||
{ 1, prim_processor_schedule, "_processor_schedule" },
|
{ 1, prim_processor_schedule, "_processor_schedule" },
|
||||||
{ 1, prim_processor_remove, "_processor_remove" },
|
{ 1, prim_processor_remove, "_processor_remove" },
|
||||||
|
@ -324,6 +324,7 @@ printf ("STARTING GC curheap base %p ptr %p newheap base %p ptr %p\n",
|
|||||||
stix->_association = stix_moveoop (stix, stix->_association);
|
stix->_association = stix_moveoop (stix, stix->_association);
|
||||||
stix->_method_context = stix_moveoop (stix, stix->_method_context);
|
stix->_method_context = stix_moveoop (stix, stix->_method_context);
|
||||||
stix->_block_context = stix_moveoop (stix, stix->_block_context);
|
stix->_block_context = stix_moveoop (stix, stix->_block_context);
|
||||||
|
stix->_semaphore = stix_moveoop (stix, stix->_semaphore);
|
||||||
stix->_process = stix_moveoop (stix, stix->_process);
|
stix->_process = stix_moveoop (stix, stix->_process);
|
||||||
stix->_process_scheduler = stix_moveoop (stix, stix->_process_scheduler);
|
stix->_process_scheduler = stix_moveoop (stix, stix->_process_scheduler);
|
||||||
stix->_true_class = stix_moveoop (stix, stix->_true_class);
|
stix->_true_class = stix_moveoop (stix, stix->_true_class);
|
||||||
|
@ -137,6 +137,7 @@ static int ignite_1 (stix_t* stix)
|
|||||||
stix->_method_context = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_CONTEXT_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
|
stix->_method_context = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_CONTEXT_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
|
||||||
stix->_block_context = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_CONTEXT_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
|
stix->_block_context = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_CONTEXT_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
|
||||||
stix->_process = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_PROCESS_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
|
stix->_process = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_PROCESS_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
|
||||||
|
stix->_semaphore = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_SEMAPHORE_NAMED_INSTVARS, 0, STIX_OBJ_TYPE_OOP));
|
||||||
stix->_process_scheduler = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_PROCESS_SCHEDULER_NAMED_INSTVARS, 0, STIX_OBJ_TYPE_OOP));
|
stix->_process_scheduler = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_PROCESS_SCHEDULER_NAMED_INSTVARS, 0, STIX_OBJ_TYPE_OOP));
|
||||||
stix->_true_class = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP));
|
stix->_true_class = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP));
|
||||||
stix->_false_class = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP));
|
stix->_false_class = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP));
|
||||||
@ -158,7 +159,7 @@ static int ignite_1 (stix_t* stix)
|
|||||||
!stix->_method_dictionary || !stix->_method || !stix->_association ||
|
!stix->_method_dictionary || !stix->_method || !stix->_association ||
|
||||||
|
|
||||||
!stix->_method_context || !stix->_block_context ||
|
!stix->_method_context || !stix->_block_context ||
|
||||||
!stix->_process || !stix->_process_scheduler ||
|
!stix->_process || !stix->_semaphore || !stix->_process_scheduler ||
|
||||||
|
|
||||||
!stix->_true_class || !stix->_false_class ||
|
!stix->_true_class || !stix->_false_class ||
|
||||||
!stix->_character || !stix->_small_integer ||
|
!stix->_character || !stix->_small_integer ||
|
||||||
@ -249,6 +250,7 @@ static int ignite_3 (stix_t* stix)
|
|||||||
{ 13, { 'M','e','t','h','o','d','C','o','n','t','e','x','t' } },
|
{ 13, { 'M','e','t','h','o','d','C','o','n','t','e','x','t' } },
|
||||||
{ 12, { 'B','l','o','c','k','C','o','n','t','e','x','t' } },
|
{ 12, { 'B','l','o','c','k','C','o','n','t','e','x','t' } },
|
||||||
{ 7, { 'P','r','o','c','e','s','s' } },
|
{ 7, { 'P','r','o','c','e','s','s' } },
|
||||||
|
{ 9, { 'S','e','m','a','p','h','o','r','e' } },
|
||||||
{ 16, { 'P','r','o','c','e','s','s','S','c','h','e','d','u','l','e','r' } },
|
{ 16, { 'P','r','o','c','e','s','s','S','c','h','e','d','u','l','e','r' } },
|
||||||
{ 4, { 'T','r','u','e' } },
|
{ 4, { 'T','r','u','e' } },
|
||||||
{ 5, { 'F','a','l','s','e' } },
|
{ 5, { 'F','a','l','s','e' } },
|
||||||
|
@ -586,6 +586,9 @@ printf ("%p\n", a);
|
|||||||
printf ("ERROR: cannot compile code - %d\n", stix_geterrnum(stix));
|
printf ("ERROR: cannot compile code - %d\n", stix_geterrnum(stix));
|
||||||
}
|
}
|
||||||
stix_close (stix);
|
stix_close (stix);
|
||||||
|
#if defined(USE_LTDL)
|
||||||
|
lt_dlexit ();
|
||||||
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -539,23 +539,36 @@ struct stix_context_t
|
|||||||
stix_oop_t slot[1]; /* stack */
|
stix_oop_t slot[1]; /* stack */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define STIX_PROCESS_NAMED_INSTVARS 6
|
|
||||||
|
#define STIX_PROCESS_NAMED_INSTVARS 7
|
||||||
typedef struct stix_process_t stix_process_t;
|
typedef struct stix_process_t stix_process_t;
|
||||||
typedef struct stix_process_t* stix_oop_process_t;
|
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_context_t initial_context;
|
stix_oop_context_t initial_context;
|
||||||
stix_oop_context_t suspended_context;
|
stix_oop_context_t runnable_context;
|
||||||
stix_oop_t state; /* SmallInteger */
|
stix_oop_t state; /* SmallInteger */
|
||||||
stix_oop_process_t prev;
|
stix_oop_process_t prev;
|
||||||
stix_oop_process_t next;
|
stix_oop_process_t next;
|
||||||
stix_oop_t sp; /* stack pointer. SmallInteger */
|
stix_oop_t sp; /* stack pointer. SmallInteger */
|
||||||
|
stix_oop_process_t sem_next;
|
||||||
|
|
||||||
/* == variable indexed part == */
|
/* == variable indexed part == */
|
||||||
stix_oop_t slot[1]; /* process stack */
|
stix_oop_t slot[1]; /* process stack */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define STIX_SEMAPHORE_NAMED_INSTVARS 3
|
||||||
|
typedef struct stix_semaphore_t stix_semaphore_t;
|
||||||
|
typedef struct stix_semaphore_t* stix_oop_semaphore_t;
|
||||||
|
struct stix_semaphore_t
|
||||||
|
{
|
||||||
|
STIX_OBJ_HEADER;
|
||||||
|
stix_oop_t count; /* SmallInteger */
|
||||||
|
stix_oop_process_t waiting_head; /* 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 4
|
||||||
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;
|
||||||
@ -739,6 +752,7 @@ struct stix_t
|
|||||||
stix_oop_t _method_context; /* MethodContext */
|
stix_oop_t _method_context; /* MethodContext */
|
||||||
stix_oop_t _block_context; /* BlockContext */
|
stix_oop_t _block_context; /* BlockContext */
|
||||||
stix_oop_t _process; /* Process */
|
stix_oop_t _process; /* Process */
|
||||||
|
stix_oop_t _semaphore; /* Semaphore */
|
||||||
stix_oop_t _process_scheduler; /* ProcessScheduler */
|
stix_oop_t _process_scheduler; /* ProcessScheduler */
|
||||||
stix_oop_t _true_class; /* True */
|
stix_oop_t _true_class; /* True */
|
||||||
stix_oop_t _false_class; /* False */
|
stix_oop_t _false_class; /* False */
|
||||||
@ -785,8 +799,8 @@ extern "C" {
|
|||||||
|
|
||||||
STIX_EXPORT stix_t* stix_open (
|
STIX_EXPORT stix_t* stix_open (
|
||||||
stix_mmgr_t* mmgr,
|
stix_mmgr_t* mmgr,
|
||||||
stix_oow_t xtnsize,
|
stix_oow_t xtnsize,
|
||||||
stix_oow_t heapsize,
|
stix_oow_t heapsize,
|
||||||
const stix_vmprim_t* vmprim,
|
const stix_vmprim_t* vmprim,
|
||||||
stix_errnum_t* errnum
|
stix_errnum_t* errnum
|
||||||
);
|
);
|
||||||
@ -798,7 +812,7 @@ STIX_EXPORT void stix_close (
|
|||||||
STIX_EXPORT int stix_init (
|
STIX_EXPORT int stix_init (
|
||||||
stix_t* vm,
|
stix_t* vm,
|
||||||
stix_mmgr_t* mmgr,
|
stix_mmgr_t* mmgr,
|
||||||
stix_oow_t heapsize,
|
stix_oow_t heapsize,
|
||||||
const stix_vmprim_t* vmprim
|
const stix_vmprim_t* vmprim
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user