On Thu, Aug 02, 2001 at 12:09:05PM -0400, Victor J. Orlikowski wrote:
> Aaron Bannert writes:
> > On Tue, Jul 31, 2001 at 06:31:23PM -0400, Victor J. Orlikowski wrote:
> > > Rather, let's be more clear.
> > >
> <snip>
> >
> My fault. That code is more than slightly wrong, now that I look
> at it better. Let's examine the following pseudocode, which closely
> follows some of my undergraduate OS work at the university.
> I will not be doing any checking for null values, etc.
>
> struct Condition {
> mutex *lock; /* mutex associated with condition */
> int thread_id; /* Current holder of the lock */
> mutex condlock;
> };
>
> void Wait(struct Condition *c) {
> acquire(c->condlock);
> if (c->thread_id != thread_id_of(current_thread)) {
> release(c->condlock);
> exit(-1); /* Only the holder of the lock may call wait */
> }
> l->thread_id = -1; /* or whatever invalid thread value */
> release(c->condlock);
> release(*(c->lock));
> wait_on_signal_or_broadcast(); /* hint, use a semaphore */
> acquire(*(c->lock));
> acquire(c->condlock);
> c->thread_id = thread_id_of(current_thread);
> release(c->condlock);
> }
>
> void Signal(struct Condition *c) {
> if (c->thread_id != thread_id_of(current_thread))
> exit(-1); /* Only the holder of the lock may call signal */
> wake_one_sleeper();
> }
>
> void Broadcast(struct Condition *c) {
> if (c->thread_id != thread_id_of(current_thread))
> exit(-1); /* Only the holder of the lock may call broadcast */
> wake_all_sleepers();
> }
>
> > Not really, but maybe I'm just being dense. Assuming "mutex1" is the
> > mutex associated with the condition (and therefore has the same scope),
> > what is the scope of "mutex2" and "held"?
> >
> The scope of mutex2 is not associated with the condition; it is
> intended to provided the needed mutual exclusion for mutex1 and the
> state variable held. However, you can ignore this, since that code was
> slightly wrong.
>
> > And more importantly, if you're using sleep(), then aren't you just doing
> > a primitive poll/wait loop, and therefore defeating the whole purpose
> > of event-based scheduling using CVs?
> Sleep() was not intended to be sleep; I was writing pseudocode.
> Sleep() was a place holder for whatever function you are calling
> that is used to block the current thread until is is awakened via a
> signal() or broadcast() operation. Hopefully I'm more clear in the
> above example.
Fair enough. The above is much more clear, but there is now another
problem...
>
> Does the new code fit better with what you expect?
In your above example, how can more than one thread be wait()ing on
a condition, if only the thread that has the "c->lock" may call
wait()?
Also, Signal() and Broadcast() may not be MT-safe, as they perform
operations on c->thread_id that are non-exclusive and may be non-atomic
on some platforms.
-aaron