Date: Thu, 1 Oct 1998 09:21:01 -0500 From: Alex Nash <nash@mcs.net> To: John Birrell <jb@cimlogic.com.au> Cc: cvs-committers@FreeBSD.ORG, cvs-all@FreeBSD.ORG Subject: Re: cvs commit: src/lib/libc_r/uthread uthread_gc.c Makefile.inc uthread_init.c uthread_find_thread.c uthread_kern.c uthread_cre Message-ID: <19981001092101.B7057@mcs.net> In-Reply-To: <199810010202.MAA07069@cimlogic.com.au>; from John Birrell on Thu, Oct 01, 1998 at 12:02:33PM %2B1000 References: <19980930192221.S9697@pr.mcs.net> <199810010202.MAA07069@cimlogic.com.au>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Oct 01, 1998 at 12:02:33PM +1000, John Birrell wrote:
> > What are the semantics that allow these functions to obtain the spinlock
> > and not release it before returning?
>
> If that were to happen, it would show up a bug in either the malloc/realloc/
> free code or a function called from within that code. The check that phk has
> in his code simply allows him to find when his code is broken by other
> people's changes. If you ever see the recursion warning, someone has
> broken the code. So going to great pains to get the locking semantics
> right for broken code is a waste of time.
The only reason the lock & return without unlocking code is correct in the
recursive case is that a single unlock releases all previous locks. This
is dependent on the spinlock implementation (something malloc() shouldn't
need to know).
> > > The malloc/free/
> > > realloc functions check for recursion within the malloc code itself. In
> > > a thread-safe library, the single spinlock ensures that no two threads
> > > go inside the protected code at the same time.
> >
> > It doesn't prevent the *same* thread from being inside the protected
> > code more than once (e.g. due to a signal).
>
> The *same* thread will lock against itself. A deadlock. That's a bug.
I wish this predictable behavior were true. The spinlock code allows
recursive locking by the same thread (libc_r/uthread/uthread_spinlock.c):
while(_atomic_lock(&lck->access_lock)) {
/* Give up the time slice: */
sched_yield();
/* Check if already locked by the running thread: */
if (lck->lock_owner == (long) _thread_run)
return;
}
> The behaviour of malloc/realloc/free is the same whether threaded or not.
> The thread implementation has to behave in such a way that it doesn't
> allow the same thread to go back into the malloc/realloc/free code if it
> has already taken the lock. The only time this would occur is if the
> thread kernel was trying to go in there. I've moved that code so that it
> doesn't need to do that anymore.
There still appears to be a problem, regardless of the thread kernel. I
think we first need to agree/disagree on whether or not a single thread
can _SPINLOCK multiple times.
> > Because our spinlock allows a single thread to recursively obtain the
> > lock without counting, it's conceivable that the following scenario
> > might occur:
>
> It doesn't. A thread can't tell from the spinlock value if _it_ locked the
> lock or another thread did.
I don't follow. In the threaded library, _SPINLOCK calls _spinlock
which does check the lock owner and acts differently depending on which
thread (if any) currently owns the lock.
Alex
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19981001092101.B7057>
