Date: Wed, 30 Sep 1998 19:22:21 -0500 From: Alex Nash <nash@mcs.net> To: John Birrell <jb@FreeBSD.ORG> 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_create.c uthread_exit.c Message-ID: <19980930192221.S9697@pr.mcs.net> In-Reply-To: <199809300636.XAA11479@freefall.freebsd.org>; from John Birrell on Tue, Sep 29, 1998 at 11:36:56PM -0700 References: <199809300636.XAA11479@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Sep 29, 1998 at 11:14:00PM -0700, John Birrell wrote:
> jb 1998/09/29 23:13:59 PDT
>
> Modified files:
> lib/libc/stdlib malloc.c
> Log:
> Delete the XXX comments that refer to spinlock recursion.
What are the semantics that allow these functions to obtain the spinlock
and not release it before returning?
> 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 thread implementation
> is responsible for ensuring that the spinlock does in fact protect malloc.
> There was a window of opportunity in which this was not the case. I'll fix
> that with a commit RSN.
Because our spinlock allows a single thread to recursively obtain the
lock without counting, it's conceivable that the following scenario
might occur:
Thread A Thread B
-------- --------
malloc()
THREAD_LOCK is obtained
malloc_active is loaded
into a register (this is
theoretical, malloc_active++
isn't guaranteed to be
atomic)
a signal is posted
--BEGIN SIGNAL--
malloc()
THREAD_LOCK is obtained
malloc_active is still
zero so we proceed
...
THREAD_UNLOCK completely
releases the lock
--END SIGNAL--
malloc()
THREAD_LOCK is obtained
(the signal handler unlocked
it for us)
malloc_active is loaded
into a register
malloc_active is
incremented
[start allocation stuff]
malloc_active is incremented
(actually set to 1)
[allocation stuff which may
conflict with thread A]
decrement malloc_active
(now at 0)
THREAD_UNLOCK
decrement malloc_active
(now at -1)
THREAD_UNLOCK
(it was already unlocked)
malloc()/free()/realloc()
malloc_active is found to
contain -1: function fails
claiming recursive entry
Alex
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19980930192221.S9697>
