[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 1/2] Implement basic sleeping locks for gnumach.
From: |
Samuel Thibault |
Subject: |
Re: [PATCH 1/2] Implement basic sleeping locks for gnumach. |
Date: |
Sun, 29 Jan 2017 21:44:45 +0100 |
User-agent: |
Mutt/1.5.21+34 (58baf7c9f32f) (2010-12-30) |
Agustina Arzille, on Sun 29 Jan 2017 16:46:45 -0300, wrote:
> >T1 atomic_cas(), gets the mutex
> >T2 fails atomic_cas()
> >T2 simple_lock()
> >T1 atomic_cas() to release the mutex
> >T2 reads KMUTEX_AVAIL in locked_swap
> >T3 atomic_cas(), gets the mutex
> >T2 writes KMUTEX_CONTENDED, gets KMUTEX_AVAIL
> >
> >now T2 believes it has the mutex, while it was given to T3.
>
> Ahh, that's a good point. We can use atomic_swap in place of locked_swap.
> Do you think that will be enough?
Yes.
There is just one thing I'm a bit afraid of: the code is assuming that
the only reason why the locker thread is awakened is that it was given
the mutex control. Is that guaranteed?
> >Don't use thread_sleep() as a whole: after failing to acquire simply,
> >assert_wait() the event, then use atomic_cas to try to put
> >KMUTEX_CONTENDED, and on success thread_block().
>
> This I don't see. thread_sleep() calls assert_wait() before unlocking the
> interlock and blocking. I'm not sure how using assert_wait() would improve
> things.
It'd allow to avoid simple_lock() completely on that side. I've been
thinking about avoiding simple_lock() completely, but it's not easy
without modifying thread_block/thread_wakeup_one deeply. So for now
let's keep the simple_lock, and then yes thread_sleep is enough.
> >>+void kmutex_unlock (struct kmutex *mtxp)
> >>+{
> >>+ if (atomic_cas (&mtxp->state, KMUTEX_LOCKED, KMUTEX_AVAIL))
> >>+ /* No waiters - We're done. */
> >>+ return;
> >>+
> >>+ simple_lock (&mtxp->lock);
> >>+
> >>+ if (!thread_wakeup_one ((event_t)mtxp))
> >>+ /* The waiter was interrupted and left - Reset the mutex state. */
> >>+ mtxp->state = KMUTEX_AVAIL;
> >
> >And what about other threads which were waiting on the mutex? We need
> >to make sure that at least one wakes up to get the mutex, otherwise
> >they'll stay asleep indefinitely.
>
> I modified thread_wakeup_prim() so that it returns TRUE if it managed
> to wake up at least a thread. So, if it returns false, we can be assert
> that there were no waiters.
The comment above is misleading then: "The waiter was interrupted and
left". Does it mean that *at best* there were some waiters but they were
interrupted?
Samuel