Skip site navigation (1)Skip section navigation (2)
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>