changed the process list of a semaphore to a doubly linked list

This commit is contained in:
hyunghwan.chung 2016-02-29 17:26:40 +00:00
parent 55a43371d5
commit b3b9af86fd
5 changed files with 96 additions and 69 deletions

View File

@ -28,7 +28,7 @@
#class(#pointer) Process(Object)
{
#dcl initial_context current_context state prev next sp sem_next.
#dcl initial_context current_context state sp prev next sem.
#method new
{
@ -106,7 +106,7 @@
#class ProcessScheduler(Object)
{
#dcl tally active runnable.
#dcl tally active runnable_head runnable_tail.
#method new
{

View File

@ -210,8 +210,8 @@ static STIX_INLINE stix_oop_process_t find_next_runnable_process (stix_t* stix)
{
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);
npr = stix->processor->active->p_next;
if ((stix_oop_t)npr == stix->_nil) npr = stix->processor->runnable_head;
return npr;
}
@ -247,7 +247,16 @@ printf ("TOO MANY PROCESS\n");
}
/* append to the runnable list */
LIST_CHAIN (p_, LIST_TAIL(p_, stix->processor->runnable), proc, stix->processor->runnable);
if (tally > 0)
{
proc->p_prev = stix->processor->runnable_tail;
stix->processor->runnable_tail->p_next = proc;
}
else
{
stix->processor->runnable_head = proc;
}
stix->processor->runnable_tail = proc;
tally++;
stix->processor->tally = STIX_SMOOI_TO_OOP(tally);
@ -268,15 +277,58 @@ static STIX_INLINE void unchain_from_processor (stix_t* stix, stix_oop_process_t
tally = STIX_OOP_TO_SMOOI(stix->processor->tally);
STIX_ASSERT (tally > 0);
LIST_UNCHAIN (p_, proc);
if ((stix_oop_t)proc->p_prev != stix->_nil) proc->p_prev->p_next = proc->p_next;
else stix->processor->runnable_head = proc->p_next;
if ((stix_oop_t)proc->p_next != stix->_nil) proc->p_next->p_prev = proc->p_prev;
else stix->processor->runnable_tail = proc->p_prev;
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;
if (tally == 0) stix->processor->active = stix->nil_process;
stix->processor->tally = STIX_SMOOI_TO_OOP(tally);
}
static STIX_INLINE void chain_into_semaphore (stix_t* stix, stix_oop_process_t proc, stix_oop_semaphore_t sem)
{
/* append a process to the process list of a semaphore*/
STIX_ASSERT ((stix_oop_t)proc->sem == stix->_nil);
STIX_ASSERT ((stix_oop_t)proc->p_prev == stix->_nil);
STIX_ASSERT ((stix_oop_t)proc->p_next == stix->_nil);
if ((stix_oop_t)sem->waiting_head == stix->_nil)
{
STIX_ASSERT ((stix_oop_t)sem->waiting_tail == stix->_nil);
sem->waiting_head = proc;
}
else
{
proc->p_prev = sem->waiting_tail;
sem->waiting_tail->p_next = proc;
}
sem->waiting_tail = proc;
proc->sem = sem;
}
static STIX_INLINE void unchain_from_semaphore (stix_t* stix, stix_oop_process_t proc)
{
stix_oop_semaphore_t sem;
STIX_ASSERT ((stix_oop_t)proc->sem != stix->_nil);
sem = proc->sem;
if ((stix_oop_t)proc->p_prev != stix->_nil) proc->p_prev->p_next = proc->p_next;
else sem->waiting_head = proc->p_next;
if ((stix_oop_t)proc->p_next != stix->_nil) proc->p_next->p_prev = proc->p_prev;
else sem->waiting_tail = proc->p_prev;
proc->p_prev = (stix_oop_process_t)stix->_nil;
proc->p_next = (stix_oop_process_t)stix->_nil;
}
static void terminate_process (stix_t* stix, stix_oop_process_t proc)
{
if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_RUNNING) ||
@ -294,11 +346,9 @@ static void terminate_process (stix_t* stix, stix_oop_process_t proc)
proc->sp = STIX_SMOOI_TO_OOP(-1); /* invalidate the process stack */
proc->current_context = proc->initial_context; /* not needed but just in case */
if (proc->sem_next)
{
/* it's in the semaphore */
/* TODO: remove it from the waiting list */
}
/* a runnable or running process must not be chanined to the
* process list of a semaphore */
STIX_ASSERT ((stix_oop_t)proc->sem == stix->_nil);
if (nrp == proc)
{
@ -321,7 +371,12 @@ static void terminate_process (stix_t* stix, stix_oop_process_t proc)
{
/* SUSPENDED ---> TERMINATED */
proc->state = STIX_SMOOI_TO_OOP(PROCESS_STATE_TERMINATED);
proc->sp = STIX_SMOOI_TO_OOP(-1); /* invalid the proce stack */
proc->sp = STIX_SMOOI_TO_OOP(-1); /* invalidate the proce stack */
if ((stix_oop_t)proc->sem != stix->_nil)
{
unchain_from_semaphore (stix, proc);
}
}
else if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_WAITING))
{
@ -332,7 +387,7 @@ static void terminate_process (stix_t* stix, stix_oop_process_t proc)
static void resume_process (stix_t* stix, stix_oop_process_t proc)
{
printf ("TO RESUME PROCESS = %p %d\n", proc, STIX_OOP_TO_SMOOI(proc->state));
printf ("TO RESUME PROCESS = %p %d\n", proc, (int)STIX_OOP_TO_SMOOI(proc->state));
if (proc->state == STIX_SMOOI_TO_OOP(PROCESS_STATE_SUSPENDED))
{
/* SUSPENED ---> RUNNING */
@ -447,11 +502,14 @@ printf ("signal semaphore...1111\n");
{
printf ("signal semaphore...2222\n");
proc = sem->waiting_head;
sem->waiting_head = proc->sem_next;
/*
sem->waiting_head = proc->semp_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;
proc->semp_next = (stix_oop_process_t)stix->_nil;
*/
unchain_from_semaphore (stix, proc);
resume_process (stix, proc); /* TODO: error check */
}
}
@ -473,23 +531,14 @@ printf (">>>>>>>>>>>>>> AWAIT SEMAPHORE - NO SUSPENDING ...................\n");
{
/* not signaled. need to wait */
proc = stix->processor->active;
STIX_ASSERT ((stix_oop_t)proc->sem_next == stix->_nil);
/* add the active process to the semaphore's waiting list */
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;
printf (">>>>>>>>>>>>>> AWAIT SEMAPHORE - SUEPENDING ACTIVE PROCESS...............\n");
/* suspend the active process */
suspend_process (stix, proc);
/* link the suspened process to the semaphore's process list */
chain_into_semaphore (stix, proc, sem);
printf (">>>>>>>>>>>>>> AWAIT SEMAPHORE - SUEPENDING PROCESS...............\n");
suspend_process (stix, proc); /* suspend the active process */
STIX_ASSERT (stix->processor->active != proc);
}
}

View File

@ -212,13 +212,6 @@ static int ignite_2 (stix_t* stix)
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;

View File

@ -54,7 +54,7 @@
/* this is for gc debugging */
/*#define STIX_DEBUG_PROCESSOR*/
/*#define STIX_DEBUG_GC_001*/
#define STIX_DEBUG_GC_001
/*#define STIX_DEBUG_GC_002*/
#define STIX_DEBUG_COMP_001
/*#define STIX_DEBUG_COMP_002*/
@ -237,27 +237,6 @@
#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)
/* ========================================================================= */

View File

@ -543,33 +543,38 @@ struct stix_context_t
#define STIX_PROCESS_NAMED_INSTVARS 7
typedef struct stix_process_t stix_process_t;
typedef struct stix_process_t* stix_oop_process_t;
#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_process_t
{
STIX_OBJ_HEADER;
stix_oop_context_t initial_context;
stix_oop_context_t current_context;
stix_oop_t state; /* SmallInteger */
stix_oop_t sp; /* stack pointer. SmallInteger */
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;
stix_oop_semaphore_t sem;
/* == variable indexed part == */
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 */
stix_oop_process_t waiting_head;
stix_oop_process_t waiting_tail;
};
#define STIX_PROCESS_SCHEDULER_NAMED_INSTVARS 3
#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
@ -577,7 +582,8 @@ struct stix_process_scheduler_t
STIX_OBJ_HEADER;
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 */
stix_oop_process_t runnable_head; /* runnable process list */
stix_oop_process_t runnable_tail; /* runnable process list */
};
/**