From a5328db569dab61c6dbc9d2e5d0f7d11f935ee6e Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Sun, 15 Apr 2018 16:24:31 +0000 Subject: [PATCH] aded a field to hodl the total number of semaphores in SemaphoreGroup changed await_semaphore_group() to return failure if no member semaphore exists --- moo/kernel/Process.moo | 5 ++-- moo/kernel/Socket.moo | 11 +++++-- moo/lib/exec.c | 67 ++++++++++++++++++++++++++---------------- moo/lib/moo.h | 7 +++-- 4 files changed, 57 insertions(+), 33 deletions(-) diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 9291265..c0dd080 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -52,7 +52,7 @@ class Semaphore(Object) { var waiting_head := nil, waiting_tail := nil, - count := 0. + count := 0. ## semaphore signal count var(#get,#set) heapIndex := -1. @@ -139,7 +139,8 @@ class SemaphoreGroup(Object) last_sem := nil, first_sigsem := nil, last_sigsem := nil, - sem_io_count := 0. + sem_io_count := 0, + sem_count := 0. (* TODO: good idea to a shortcut way to prohibit a certain method in the heirarchy chain? method(#class,#prohibited) new. diff --git a/moo/kernel/Socket.moo b/moo/kernel/Socket.moo index ee64ffc..68c9c68 100644 --- a/moo/kernel/Socket.moo +++ b/moo/kernel/Socket.moo @@ -612,7 +612,7 @@ error -> exception ]. [ - | s s2 st sg | + | s s2 st sg ss | [ s := Socket domain: Socket.Domain.INET type: Socket.Type.STREAM. ##s connect: (SocketAddress fromString: '127.0.0.1:9999') do: conact. @@ -624,6 +624,7 @@ error -> exception ## ###s2 listen: 10; watchInput. ## s2 listen: 10 do: accact. +(* st := Semaphore new. System addAsyncSemaphore: st. System signal: st afterSecs: 5. @@ -632,16 +633,20 @@ sg := SemaphoreGroup new. 'JJJJJJJJJJJ' dump. sg wait. 'YYYYYYYYYYYYYYY' dump. +*) ###[ while (1) { '1111' dump. System sleepForSecs: 1 } ] fork. +(* st := Semaphore new. System addAsyncSemaphore: st. System signal: st afterSecs: 20. - +*) while (true) { - if (System handleAsyncEvent isError) { break }. + ss := System handleAsyncEvent. + if (ss isError) { break }. + ###if (ss == st) { System removeAsyncSemaphore: st }. }. ] ensure: diff --git a/moo/lib/exec.c b/moo/lib/exec.c index cb32588..46a959b 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -919,6 +919,15 @@ static MOO_INLINE moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore MOO_ASSERT (moo, moo_iskindof(moo, (moo_oop_t)semgrp, moo->_semaphore_group)); + if (MOO_OOP_TO_SMOOI(semgrp->sem_count) <= 0) + { + /* cannot wait on a semaphore group that has no member semaphores. + * return failure if waiting on such a semapohre group is attempted */ + MOO_ASSERT (moo, (moo_oop_t)semgrp->sems[MOO_SEMAPHORE_GROUP_SEMS_SIG].first == moo->_nil); + MOO_ASSERT (moo, (moo_oop_t)semgrp->sems[MOO_SEMAPHORE_GROUP_SEMS_SIG].last == moo->_nil); + return MOO_ERROR_TO_OOP(MOO_EINVAL); /* TODO: better error code? */ + } + sem = semgrp->sems[MOO_SEMAPHORE_GROUP_SEMS_SIG].first; if ((moo_oop_t)sem != moo->_nil) { @@ -937,12 +946,6 @@ static MOO_INLINE moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore return (moo_oop_t)sem; } -MOO_DEBUG1 (moo, "QQQQQQQQQQQQQQQQQQQQQQQ %d\n", semgrp->sem_io_count); -if (MOO_OOP_TO_SMOOI(semgrp->sem_io_count) <= 0) -{ - //return MOO_ERROR_TO_OOP(MOO_EIOERR); -} - /* no semaphores have been signaled. suspend the current process * until at least one of them is signaled */ proc = moo->processor->active; @@ -2341,25 +2344,30 @@ static moo_pfrc_t pf_semaphore_group_add_semaphore (moo_t* moo, moo_ooi_t nargs) sg = (moo_oop_semaphore_group_t)MOO_STACK_GETRCV(moo, nargs); MOO_PF_CHECK_RCV (moo, moo_iskindof(moo, (moo_oop_t)sg, moo->_semaphore_group)); - sem = (moo_oop_semaphore_t)MOO_STACK_GETARG (moo, nargs, 0); + sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0); MOO_PF_CHECK_ARGS (moo, nargs, moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore)); if ((moo_oop_t)sem->group == moo->_nil) { /* the semaphore doesn't belong to a group */ - + moo_ooi_t count; int sems_idx; sems_idx = MOO_OOP_TO_SMOOI(sem->count) > 0? MOO_SEMAPHORE_GROUP_SEMS_SIG: MOO_SEMAPHORE_GROUP_SEMS_UNSIG; MOO_APPEND_TO_OOP_LIST (moo, &sg->sems[sems_idx], moo_oop_semaphore_t, sem, grm); sem->group = sg; + count = MOO_OOP_TO_SMOOI(sg->sem_count); + MOO_ASSERT (moo, count >= 0); + count++; + sg->sem_count = MOO_SMOOI_TO_OOP(count); + if ((moo_oop_t)sem->io_index != moo->_nil) { - /* this semaphore is associated with I/O operation */ - moo_ooi_t count; - - MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_index) && MOO_OOP_TO_SMOOI(sem->io_index) >= 0 && MOO_OOP_TO_SMOOI(sem->io_index) < moo->sem_io_tuple_count); + /* the semaphore being added is associated with I/O operation. */ + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_index) && + MOO_OOP_TO_SMOOI(sem->io_index) >= 0 && + MOO_OOP_TO_SMOOI(sem->io_index) < moo->sem_io_tuple_count); count = MOO_OOP_TO_SMOOI(sg->sem_io_count); MOO_ASSERT (moo, count >= 0); @@ -2369,7 +2377,15 @@ static moo_pfrc_t pf_semaphore_group_add_semaphore (moo_t* moo, moo_ooi_t nargs) if (count == 1) { /* the first IO semaphore is being added to the semaphore group. - * but there are processes waiting on the semaphore group */ + * but there are already processes waiting on the semaphore group. + * + * for instance, + * [Process 1] + * sg := SemaphoreGroup new. + * sg wait. + * [Process 2] + * sg addSemaphore: (Semaphore new). + */ moo_oop_process_t wp; /* TODO: add sem_wait_count to process. no traversal... */ @@ -2402,6 +2418,7 @@ static moo_pfrc_t pf_semaphore_group_remove_semaphore (moo_t* moo, moo_ooi_t nar { moo_oop_semaphore_group_t rcv; moo_oop_semaphore_t sem; + moo_ooi_t count; rcv = (moo_oop_semaphore_group_t)MOO_STACK_GETRCV(moo, nargs); MOO_PF_CHECK_RCV (moo, moo_iskindof(moo, (moo_oop_t)rcv, moo->_semaphore_group)); @@ -2438,11 +2455,14 @@ static moo_pfrc_t pf_semaphore_group_remove_semaphore (moo_t* moo, moo_ooi_t nar sem->grm.prev = (moo_oop_semaphore_t)moo->_nil; sem->grm.next = (moo_oop_semaphore_t)moo->_nil; sem->group = (moo_oop_semaphore_group_t)moo->_nil; + + count = MOO_OOP_TO_SMOOI(rcv->sem_count); + MOO_ASSERT (moo, count > 0); + count--; + rcv->sem_count = MOO_SMOOI_TO_OOP(count); if ((moo_oop_t)sem->io_index != moo->_nil) { - moo_ooi_t count; - MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_index) && MOO_OOP_TO_SMOOI(sem->io_index) >= 0 && MOO_OOP_TO_SMOOI(sem->io_index) < moo->sem_io_tuple_count); count = MOO_OOP_TO_SMOOI(rcv->sem_io_count); @@ -2793,7 +2813,7 @@ static moo_pfrc_t pf_integer_div (moo_t* moo, moo_ooi_t nargs) rcv = MOO_STACK_GETRCV(moo, nargs); arg = MOO_STACK_GETARG(moo, nargs, 0); - quo = moo_divints (moo, rcv, arg, 0, MOO_NULL); + quo = moo_divints(moo, rcv, arg, 0, MOO_NULL); if (!quo) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); /* TODO: MOO_EDIVBY0 soft or hard failure? */ @@ -2810,9 +2830,8 @@ static moo_pfrc_t pf_integer_rem (moo_t* moo, moo_ooi_t nargs) rcv = MOO_STACK_GETRCV(moo, nargs); arg = MOO_STACK_GETARG(moo, nargs, 0); - quo = moo_divints (moo, rcv, arg, 0, &rem); - if (!quo) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); -/* TODO: MOO_EDIVBY0 soft or hard failure? */ + quo = moo_divints(moo, rcv, arg, 0, &rem); + if (!quo) return (moo->errnum == MOO_EINVAL || moo->errnum == MOO_EDIVBY0? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); MOO_STACK_SETRET (moo, nargs, rem); return MOO_PF_SUCCESS; @@ -2827,9 +2846,8 @@ static moo_pfrc_t pf_integer_mdiv (moo_t* moo, moo_ooi_t nargs) rcv = MOO_STACK_GETRCV(moo, nargs); arg = MOO_STACK_GETARG(moo, nargs, 0); - quo = moo_divints (moo, rcv, arg, 1, MOO_NULL); - if (!quo) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); -/* TODO: MOO_EDIVBY0 soft or hard failure? */ + quo = moo_divints(moo, rcv, arg, 1, MOO_NULL); + if (!quo) return (moo->errnum == MOO_EINVAL || moo->errnum == MOO_EDIVBY0? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); MOO_STACK_SETRET (moo, nargs, quo); return MOO_PF_SUCCESS; @@ -2844,9 +2862,8 @@ static moo_pfrc_t pf_integer_mod (moo_t* moo, moo_ooi_t nargs) rcv = MOO_STACK_GETRCV(moo, nargs); arg = MOO_STACK_GETARG(moo, nargs, 0); - quo = moo_divints (moo, rcv, arg, 1, &rem); - if (!quo) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); -/* TODO: MOO_EDIVBY0 soft or hard failure? */ + quo = moo_divints(moo, rcv, arg, 1, &rem); + if (!quo) return (moo->errnum == MOO_EINVAL || moo->errnum == MOO_EDIVBY0? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); MOO_STACK_SETRET (moo, nargs, rem); return MOO_PF_SUCCESS; diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 3fb6d6f..e46702a 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -757,7 +757,7 @@ typedef struct moo_process_t* moo_oop_process_t; typedef struct moo_semaphore_t moo_semaphore_t; typedef struct moo_semaphore_t* moo_oop_semaphore_t; -#define MOO_SEMAPHORE_GROUP_NAMED_INSTVARS 7 +#define MOO_SEMAPHORE_GROUP_NAMED_INSTVARS 8 typedef struct moo_semaphore_group_t moo_semaphore_group_t; typedef struct moo_semaphore_group_t* moo_oop_semaphore_group_t; @@ -852,8 +852,8 @@ struct moo_semaphore_group_t struct { moo_oop_process_t first; - moo_oop_process_t last; /* list of processes waiting on this semaphore group */ - } waiting; + moo_oop_process_t last; + } waiting; /* list of processes waiting on this semaphore group */ /* [END IMPORTANT] */ struct @@ -863,6 +863,7 @@ struct moo_semaphore_group_t } sems[2]; /* sems[0] - unsignaled semaphores, sems[1] - signaled semaphores */ moo_oop_t sem_io_count; /* the number of io semaphores in the group */ + moo_oop_t sem_count; /* the total number of semaphores in the group */ }; #define MOO_PROCESS_SCHEDULER_NAMED_INSTVARS 9