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>
