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>