aded a field to hodl the total number of semaphores in SemaphoreGroup
changed await_semaphore_group() to return failure if no member semaphore exists
This commit is contained in:
parent
0d40016fa1
commit
a5328db569
@ -52,7 +52,7 @@ class Semaphore(Object)
|
|||||||
{
|
{
|
||||||
var waiting_head := nil,
|
var waiting_head := nil,
|
||||||
waiting_tail := nil,
|
waiting_tail := nil,
|
||||||
count := 0.
|
count := 0. ## semaphore signal count
|
||||||
|
|
||||||
var(#get,#set) heapIndex := -1.
|
var(#get,#set) heapIndex := -1.
|
||||||
|
|
||||||
@ -139,7 +139,8 @@ class SemaphoreGroup(Object)
|
|||||||
last_sem := nil,
|
last_sem := nil,
|
||||||
first_sigsem := nil,
|
first_sigsem := nil,
|
||||||
last_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?
|
(* TODO: good idea to a shortcut way to prohibit a certain method in the heirarchy chain?
|
||||||
method(#class,#prohibited) new.
|
method(#class,#prohibited) new.
|
||||||
|
@ -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 := Socket domain: Socket.Domain.INET type: Socket.Type.STREAM.
|
||||||
##s connect: (SocketAddress fromString: '127.0.0.1:9999') do: conact.
|
##s connect: (SocketAddress fromString: '127.0.0.1:9999') do: conact.
|
||||||
@ -624,6 +624,7 @@ error -> exception
|
|||||||
## ###s2 listen: 10; watchInput.
|
## ###s2 listen: 10; watchInput.
|
||||||
## s2 listen: 10 do: accact.
|
## s2 listen: 10 do: accact.
|
||||||
|
|
||||||
|
(*
|
||||||
st := Semaphore new.
|
st := Semaphore new.
|
||||||
System addAsyncSemaphore: st.
|
System addAsyncSemaphore: st.
|
||||||
System signal: st afterSecs: 5.
|
System signal: st afterSecs: 5.
|
||||||
@ -632,16 +633,20 @@ sg := SemaphoreGroup new.
|
|||||||
'JJJJJJJJJJJ' dump.
|
'JJJJJJJJJJJ' dump.
|
||||||
sg wait.
|
sg wait.
|
||||||
'YYYYYYYYYYYYYYY' dump.
|
'YYYYYYYYYYYYYYY' dump.
|
||||||
|
*)
|
||||||
|
|
||||||
###[ while (1) { '1111' dump. System sleepForSecs: 1 } ] fork.
|
###[ while (1) { '1111' dump. System sleepForSecs: 1 } ] fork.
|
||||||
|
|
||||||
|
(*
|
||||||
st := Semaphore new.
|
st := Semaphore new.
|
||||||
System addAsyncSemaphore: st.
|
System addAsyncSemaphore: st.
|
||||||
System signal: st afterSecs: 20.
|
System signal: st afterSecs: 20.
|
||||||
|
*)
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (System handleAsyncEvent isError) { break }.
|
ss := System handleAsyncEvent.
|
||||||
|
if (ss isError) { break }.
|
||||||
|
###if (ss == st) { System removeAsyncSemaphore: st }.
|
||||||
}.
|
}.
|
||||||
]
|
]
|
||||||
ensure:
|
ensure:
|
||||||
|
@ -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));
|
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;
|
sem = semgrp->sems[MOO_SEMAPHORE_GROUP_SEMS_SIG].first;
|
||||||
if ((moo_oop_t)sem != moo->_nil)
|
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;
|
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
|
/* no semaphores have been signaled. suspend the current process
|
||||||
* until at least one of them is signaled */
|
* until at least one of them is signaled */
|
||||||
proc = moo->processor->active;
|
proc = moo->processor->active;
|
||||||
@ -2347,19 +2350,24 @@ static moo_pfrc_t pf_semaphore_group_add_semaphore (moo_t* moo, moo_ooi_t nargs)
|
|||||||
if ((moo_oop_t)sem->group == moo->_nil)
|
if ((moo_oop_t)sem->group == moo->_nil)
|
||||||
{
|
{
|
||||||
/* the semaphore doesn't belong to a group */
|
/* the semaphore doesn't belong to a group */
|
||||||
|
moo_ooi_t count;
|
||||||
int sems_idx;
|
int sems_idx;
|
||||||
|
|
||||||
sems_idx = MOO_OOP_TO_SMOOI(sem->count) > 0? MOO_SEMAPHORE_GROUP_SEMS_SIG: MOO_SEMAPHORE_GROUP_SEMS_UNSIG;
|
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);
|
MOO_APPEND_TO_OOP_LIST (moo, &sg->sems[sems_idx], moo_oop_semaphore_t, sem, grm);
|
||||||
sem->group = sg;
|
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)
|
if ((moo_oop_t)sem->io_index != moo->_nil)
|
||||||
{
|
{
|
||||||
/* this semaphore is associated with I/O operation */
|
/* the semaphore being added 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_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);
|
MOO_OOP_TO_SMOOI(sem->io_index) < moo->sem_io_tuple_count);
|
||||||
|
|
||||||
count = MOO_OOP_TO_SMOOI(sg->sem_io_count);
|
count = MOO_OOP_TO_SMOOI(sg->sem_io_count);
|
||||||
MOO_ASSERT (moo, count >= 0);
|
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)
|
if (count == 1)
|
||||||
{
|
{
|
||||||
/* the first IO semaphore is being added to the semaphore group.
|
/* 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;
|
moo_oop_process_t wp;
|
||||||
/* TODO: add sem_wait_count to process. no traversal... */
|
/* 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_group_t rcv;
|
||||||
moo_oop_semaphore_t sem;
|
moo_oop_semaphore_t sem;
|
||||||
|
moo_ooi_t count;
|
||||||
|
|
||||||
rcv = (moo_oop_semaphore_group_t)MOO_STACK_GETRCV(moo, nargs);
|
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));
|
MOO_PF_CHECK_RCV (moo, moo_iskindof(moo, (moo_oop_t)rcv, moo->_semaphore_group));
|
||||||
@ -2439,10 +2456,13 @@ static moo_pfrc_t pf_semaphore_group_remove_semaphore (moo_t* moo, moo_ooi_t nar
|
|||||||
sem->grm.next = (moo_oop_semaphore_t)moo->_nil;
|
sem->grm.next = (moo_oop_semaphore_t)moo->_nil;
|
||||||
sem->group = (moo_oop_semaphore_group_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)
|
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);
|
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);
|
count = MOO_OOP_TO_SMOOI(rcv->sem_io_count);
|
||||||
@ -2811,8 +2831,7 @@ static moo_pfrc_t pf_integer_rem (moo_t* moo, moo_ooi_t nargs)
|
|||||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||||
|
|
||||||
quo = moo_divints(moo, rcv, arg, 0, &rem);
|
quo = moo_divints(moo, rcv, arg, 0, &rem);
|
||||||
if (!quo) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE);
|
if (!quo) return (moo->errnum == MOO_EINVAL || moo->errnum == MOO_EDIVBY0? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE);
|
||||||
/* TODO: MOO_EDIVBY0 soft or hard failure? */
|
|
||||||
|
|
||||||
MOO_STACK_SETRET (moo, nargs, rem);
|
MOO_STACK_SETRET (moo, nargs, rem);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
@ -2828,8 +2847,7 @@ static moo_pfrc_t pf_integer_mdiv (moo_t* moo, moo_ooi_t nargs)
|
|||||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||||
|
|
||||||
quo = moo_divints(moo, rcv, arg, 1, MOO_NULL);
|
quo = moo_divints(moo, rcv, arg, 1, MOO_NULL);
|
||||||
if (!quo) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE);
|
if (!quo) return (moo->errnum == MOO_EINVAL || moo->errnum == MOO_EDIVBY0? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE);
|
||||||
/* TODO: MOO_EDIVBY0 soft or hard failure? */
|
|
||||||
|
|
||||||
MOO_STACK_SETRET (moo, nargs, quo);
|
MOO_STACK_SETRET (moo, nargs, quo);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
@ -2845,8 +2863,7 @@ static moo_pfrc_t pf_integer_mod (moo_t* moo, moo_ooi_t nargs)
|
|||||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||||
|
|
||||||
quo = moo_divints(moo, rcv, arg, 1, &rem);
|
quo = moo_divints(moo, rcv, arg, 1, &rem);
|
||||||
if (!quo) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE);
|
if (!quo) return (moo->errnum == MOO_EINVAL || moo->errnum == MOO_EDIVBY0? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE);
|
||||||
/* TODO: MOO_EDIVBY0 soft or hard failure? */
|
|
||||||
|
|
||||||
MOO_STACK_SETRET (moo, nargs, rem);
|
MOO_STACK_SETRET (moo, nargs, rem);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
|
@ -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_semaphore_t;
|
||||||
typedef struct moo_semaphore_t* moo_oop_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_semaphore_group_t;
|
||||||
typedef struct moo_semaphore_group_t* moo_oop_semaphore_group_t;
|
typedef struct moo_semaphore_group_t* moo_oop_semaphore_group_t;
|
||||||
|
|
||||||
@ -852,8 +852,8 @@ struct moo_semaphore_group_t
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
moo_oop_process_t first;
|
moo_oop_process_t first;
|
||||||
moo_oop_process_t last; /* list of processes waiting on this semaphore group */
|
moo_oop_process_t last;
|
||||||
} waiting;
|
} waiting; /* list of processes waiting on this semaphore group */
|
||||||
/* [END IMPORTANT] */
|
/* [END IMPORTANT] */
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -863,6 +863,7 @@ struct moo_semaphore_group_t
|
|||||||
} sems[2]; /* sems[0] - unsignaled semaphores, sems[1] - signaled semaphores */
|
} 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_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
|
#define MOO_PROCESS_SCHEDULER_NAMED_INSTVARS 9
|
||||||
|
Loading…
Reference in New Issue
Block a user