From 27c2c5b404e63e8fdb268aa9cbff312fa43f5106 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Fri, 3 Nov 2017 16:26:55 +0000 Subject: [PATCH] disallowed semaphore removal from a group when a process is waiting for the semaphore to be signaled --- moo/kernel/Process.moo | 6 +++--- moo/kernel/test-004.moo | 1 + moo/lib/exec.c | 31 ++++++++++++++++++++++++++----- moo/lib/gc.c | 7 +++---- 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index ed3b05c..bb10ae2 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -218,7 +218,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit { | x | x := self _addSemaphore: sem. - if (x isError) { thisProcess primError dump. Exception signal: ('Cannot add a semaphore - ' & thisProcess primError) }. + if (x isError) { Exception signal: ('Cannot add a semaphore - ' & x asString) }. ^x } @@ -226,7 +226,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit { | x | x := self _removeSemaphore: sem. - if (x isError) { thisProcess primError dump. Exception signal: ('Cannot remove a semaphore - ' & thisProcess primError) }. + if (x isError) { Exception signal: ('Cannot remove a semaphore - ' & x asString) }. ^x } @@ -234,7 +234,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit { | x | x := self _wait. - if (x isError) { thisProcess primError dump. Exception signal: ('Cannot wait on a semaphore - ' & thisProcess primError) }. + if (x isError) { Exception signal: ('Cannot wait on a semaphore - ' & x asString) }. if (x signalAction notNil) { x signalAction value: x }. ^x } diff --git a/moo/kernel/test-004.moo b/moo/kernel/test-004.moo index 2b76f2b..18eb526 100644 --- a/moo/kernel/test-004.moo +++ b/moo/kernel/test-004.moo @@ -33,6 +33,7 @@ class MyObject(Object) s3 := Semaphore new. sg := SemaphoreGroup new. + sg addSemaphore: s1. sg addSemaphore: s2. sg addSemaphore: s3. diff --git a/moo/lib/exec.c b/moo/lib/exec.c index a8e3dd3..ac8b6e8 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -816,7 +816,7 @@ static MOO_INLINE void await_semaphore (moo_t* moo, moo_oop_semaphore_t sem) count = MOO_OOP_TO_SMOOI(sem->count); if (count > 0) { - /* it's already signalled */ + /* it's already signaled */ count--; sem->count = MOO_SMOOI_TO_OOP(count); @@ -881,7 +881,7 @@ static MOO_INLINE moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore } /* no semaphores have been signaled. suspend the current process - * until the at least one of them is signaled */ + * until at least one of them is signaled */ proc = moo->processor->active; /* suspend the active process */ @@ -2622,6 +2622,25 @@ static moo_pfrc_t pf_semaphore_group_remove_semaphore (moo_t* moo, moo_ooi_t nar if (sem->group == rcv) { int sems_idx; + + if ((moo_oop_t)rcv->waiting.first != moo->_nil) + { + /* there is a process waiting on this semaphore group. + * i don't allow a semaphore to be removed from the group. + * i want to dodge potential problems arising when removal is allowed. + * + * for instance, consider this psuedo code. + * sg addSemaphore: s + * [ sg wait ] fork. + * [ sg wait ] fork. + * [ sg wait ] fork. + * sg removeSemaphore: s. + * + */ + MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EPERM); + goto done; + } + sems_idx = MOO_OOP_TO_SMOOI(sem->count) > 0? MOO_SEMAPHORE_GROUP_SEMS_SIG: MOO_SEMAPHORE_GROUP_SEMS_UNSIG; MOO_DELETE_FROM_OOP_LIST (moo, &rcv->sems[sems_idx], sem, grm); sem->grm.prev = (moo_oop_semaphore_t)moo->_nil; @@ -2632,6 +2651,7 @@ static moo_pfrc_t pf_semaphore_group_remove_semaphore (moo_t* moo, moo_ooi_t nar { moo_ooi_t count; count = MOO_OOP_TO_SMOOI(rcv->sem_io_count); + MOO_ASSERT (moo, count > 0); count--; rcv->sem_io_count = MOO_SMOOI_TO_OOP(count); } @@ -2644,6 +2664,7 @@ static moo_pfrc_t pf_semaphore_group_remove_semaphore (moo_t* moo, moo_ooi_t nar MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EPERM); } +done: return MOO_PF_SUCCESS; } @@ -2666,7 +2687,7 @@ static moo_pfrc_t pf_semaphore_group_wait (moo_t* moo, moo_ooi_t nargs) sem = await_semaphore_group (moo, (moo_oop_semaphore_group_t)rcv); if (sem != moo->_nil) { - /* there was a singaled semaphore. the active process won't get + /* there was a signaled semaphore. the active process won't get * suspended. change the return value of the current process * forcibly to the signaled semaphore */ MOO_STACK_SETTOP (moo, sem); @@ -4957,7 +4978,7 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo) if (moo->sem_gcfin_sigreq) { signal_sem_gcfin: - MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Signalled GCFIN semaphore\n"); + MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Signaled GCFIN semaphore\n"); proc = signal_semaphore (moo, moo->sem_gcfin); if (moo->processor->active == moo->nil_process && (moo_oop_t)proc != moo->_nil) @@ -4998,7 +5019,7 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo) */ MOO_LOG3 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, - "Signalled GCFIN semaphore without gcfin signal request - total - %zd runnable/running - %zd suspended - %zd\n", + "Signaled GCFIN semaphore without gcfin signal request - total - %zd runnable/running - %zd suspended - %zd\n", MOO_OOP_TO_SMOOI(moo->processor->total_count), MOO_OOP_TO_SMOOI(moo->processor->runnable.count), MOO_OOP_TO_SMOOI(moo->processor->suspended.count)); proc = signal_semaphore (moo, moo->sem_gcfin); if ((moo_oop_t)proc != moo->_nil) diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 9d04b91..2db98a1 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -28,7 +28,7 @@ /* - * Stix ..................... + * Apex...................... * ^ ^ ^ : ....... * | | | v v : * | | +------------------- Class ..... @@ -41,7 +41,7 @@ * * The class hierarchy is roughly as follows: * - * Stix + * Apex * Class * NilObject * Object @@ -66,8 +66,7 @@ * LargePositiveInteger * LargeNegativeInteger * - * Stix has no instance variables. - * Stix has 1 class variable: Sysdic + * Apex has no instance variables. * */