implemented wait on a semaphore group and related semaphore handling
This commit is contained in:
parent
6711bc01fa
commit
ce72ffa193
@ -55,8 +55,9 @@ class Semaphore(Object)
|
|||||||
fireTimeNsec := 0,
|
fireTimeNsec := 0,
|
||||||
ioIndex := -1,
|
ioIndex := -1,
|
||||||
ioHandle := nil,
|
ioHandle := nil,
|
||||||
ioMask := 0,
|
ioMask := 0.
|
||||||
group := nil.
|
|
||||||
|
var(#get,#set) _group := nil.
|
||||||
|
|
||||||
method(#class) forMutualExclusion
|
method(#class) forMutualExclusion
|
||||||
{
|
{
|
||||||
@ -148,7 +149,7 @@ TODO: timed wait...
|
|||||||
}
|
}
|
||||||
elsif (sem == zzz)
|
elsif (sem == zzz)
|
||||||
{
|
{
|
||||||
}
|
}.
|
||||||
}
|
}
|
||||||
|
|
||||||
============ CASE 2====================
|
============ CASE 2====================
|
||||||
@ -225,8 +226,17 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
|||||||
|
|
||||||
method initialize: arr
|
method initialize: arr
|
||||||
{
|
{
|
||||||
|
| i sem |
|
||||||
self.size := arr size.
|
self.size := arr size.
|
||||||
self.semarr := arr.
|
self.semarr := arr.
|
||||||
|
|
||||||
|
i := 0.
|
||||||
|
while (i < self.size)
|
||||||
|
{
|
||||||
|
sem := self.semarr at: i.
|
||||||
|
sem _group: self.
|
||||||
|
i := i + 1.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
method(#primitive) wait.
|
method(#primitive) wait.
|
||||||
|
@ -473,6 +473,7 @@ static MOO_INLINE void chain_into_semaphore (moo_t* moo, moo_oop_process_t proc,
|
|||||||
MOO_ASSERT (moo, (moo_oop_t)proc->sem_wait.prev == moo->_nil);
|
MOO_ASSERT (moo, (moo_oop_t)proc->sem_wait.prev == moo->_nil);
|
||||||
MOO_ASSERT (moo, (moo_oop_t)proc->sem_wait.next == moo->_nil);
|
MOO_ASSERT (moo, (moo_oop_t)proc->sem_wait.next == moo->_nil);
|
||||||
|
|
||||||
|
/* a semaphore or a semaphore group must be given for process chaining */
|
||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,sem) == moo->_semaphore ||
|
MOO_ASSERT (moo, MOO_CLASSOF(moo,sem) == moo->_semaphore ||
|
||||||
MOO_CLASSOF(moo,sem) == moo->_semaphore_group);
|
MOO_CLASSOF(moo,sem) == moo->_semaphore_group);
|
||||||
|
|
||||||
@ -684,6 +685,7 @@ static void yield_process (moo_t* moo, moo_oop_process_t proc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static int async_signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
static int async_signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
||||||
{
|
{
|
||||||
if (moo->sem_list_count >= SEM_LIST_MAX)
|
if (moo->sem_list_count >= SEM_LIST_MAX)
|
||||||
@ -709,6 +711,7 @@ static int async_signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
|||||||
moo->sem_list_count++;
|
moo->sem_list_count++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static moo_oop_process_t signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
static moo_oop_process_t signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
||||||
{
|
{
|
||||||
@ -717,7 +720,7 @@ static moo_oop_process_t signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
|||||||
|
|
||||||
if ((moo_oop_t)sem->group != moo->_nil)
|
if ((moo_oop_t)sem->group != moo->_nil)
|
||||||
{
|
{
|
||||||
/* the semaphore belongs to a group */
|
/* the semaphore belongs to a semaphore group */
|
||||||
moo_oop_semaphore_group_t semgrp;
|
moo_oop_semaphore_group_t semgrp;
|
||||||
|
|
||||||
semgrp = sem->group;
|
semgrp = sem->group;
|
||||||
@ -733,6 +736,17 @@ static moo_oop_process_t signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if the semaphore belongs to a semaphore group, no process is waiting
|
||||||
|
* on the semaphore group. however, a process may still be waiting on
|
||||||
|
* the semaphore. If a process waits on a semaphore group and another
|
||||||
|
* process wait on a semaphor that belongs to the semaphore group, the
|
||||||
|
* process waiting on the group always wins.
|
||||||
|
*
|
||||||
|
* TODO: implement a fair scheduling policy. or do i simply have to disallow individual wait on a semaphore belonging to a group?
|
||||||
|
*
|
||||||
|
* if it doesn't belong to a sempahore group, i'm free from the ambiguity
|
||||||
|
* issue.
|
||||||
|
*/
|
||||||
if ((moo_oop_t)sem->waiting.first == moo->_nil)
|
if ((moo_oop_t)sem->waiting.first == moo->_nil)
|
||||||
{
|
{
|
||||||
/* no process is waiting on this semaphore */
|
/* no process is waiting on this semaphore */
|
||||||
@ -761,12 +775,22 @@ static moo_oop_process_t signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void await_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
static int await_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
||||||
{
|
{
|
||||||
/* TODO: support timeout */
|
/* TODO: support timeout */
|
||||||
moo_oop_process_t proc;
|
moo_oop_process_t proc;
|
||||||
moo_ooi_t count;
|
moo_ooi_t count;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* TODO: do i have to disallow?? */
|
||||||
|
if ((moo_oop_t)sem->group != moo->_nil)
|
||||||
|
{
|
||||||
|
/* disallow a semaphore in a semaphore group to be waited on */
|
||||||
|
moo_seterrnum (moo, MOO_EPERM);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
count = MOO_OOP_TO_SMOOI(sem->count);
|
count = MOO_OOP_TO_SMOOI(sem->count);
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
@ -791,6 +815,8 @@ static void await_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
|||||||
|
|
||||||
MOO_ASSERT (moo, moo->processor->active != proc);
|
MOO_ASSERT (moo, moo->processor->active != proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore_group_t semgrp)
|
static moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore_group_t semgrp)
|
||||||
@ -840,7 +866,7 @@ static moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore_group_t se
|
|||||||
if (MOO_OOP_TO_SMOOI(sem->io_index) >= 0) moo->sem_io_wait_count++;
|
if (MOO_OOP_TO_SMOOI(sem->io_index) >= 0) moo->sem_io_wait_count++;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* link the suspended process to the semaphore's process list */
|
/* link the suspended process to the semaphore group's process list */
|
||||||
chain_into_semaphore (moo, proc, (moo_oop_semaphore_t)semgrp);
|
chain_into_semaphore (moo, proc, (moo_oop_semaphore_t)semgrp);
|
||||||
MOO_ASSERT (moo, semgrp->waiting.last == proc);
|
MOO_ASSERT (moo, semgrp->waiting.last == proc);
|
||||||
/*if (MOO_OOP_TO_SMOOI(sem->io_index) >= 0) moo->sem_io_wait_count++;*/
|
/*if (MOO_OOP_TO_SMOOI(sem->io_index) >= 0) moo->sem_io_wait_count++;*/
|
||||||
@ -2468,7 +2494,11 @@ static moo_pfrc_t pf_semaphore_wait (moo_t* moo, moo_ooi_t nargs)
|
|||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
await_semaphore (moo, (moo_oop_semaphore_t)rcv);
|
if (await_semaphore (moo, (moo_oop_semaphore_t)rcv) <= -1)
|
||||||
|
{
|
||||||
|
MOO_STACK_SETRETTOERRNUM (moo, nargs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
|
Loading…
Reference in New Issue
Block a user