From b3b9af86fd36a9c2c633e9032eb7e3212aede375 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Mon, 29 Feb 2016 17:26:40 +0000 Subject: [PATCH] changed the process list of a semaphore to a doubly linked list --- stix/kernel/Process.st | 4 +- stix/lib/exec.c | 107 ++++++++++++++++++++++++++++++----------- stix/lib/ignite.c | 7 --- stix/lib/stix-prv.h | 23 +-------- stix/lib/stix.h | 24 +++++---- 5 files changed, 96 insertions(+), 69 deletions(-) diff --git a/stix/kernel/Process.st b/stix/kernel/Process.st index a8a2c04..ca3859a 100644 --- a/stix/kernel/Process.st +++ b/stix/kernel/Process.st @@ -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 { diff --git a/stix/lib/exec.c b/stix/lib/exec.c index caf0199..bce0315 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -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); } } diff --git a/stix/lib/ignite.c b/stix/lib/ignite.c index 87707af..134f30a 100644 --- a/stix/lib/ignite.c +++ b/stix/lib/ignite.c @@ -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; diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index a0a8f1b..bf19870 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -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) /* ========================================================================= */ diff --git a/stix/lib/stix.h b/stix/lib/stix.h index d17f1b9..39709b9 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -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 */ }; /**