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>