PERFORCE change 31939 for review
Peter Wemm
peter at FreeBSD.org
Tue May 27 14:21:21 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=31939
Change 31939 by peter at peter_daintree on 2003/05/27 14:20:15
IFC @31936
Affected files ...
.. //depot/projects/hammer/lib/libthr/arch/i386/i386/_setcurthread.c#6 integrate
.. //depot/projects/hammer/lib/libthr/arch/ia64/ia64/_curthread.c#3 integrate
.. //depot/projects/hammer/lib/libthr/arch/sparc64/sparc64/_setcurthread.c#2 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_cancel.c#4 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_create.c#5 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_exit.c#4 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_find_thread.c#2 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_gc.c#3 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_info.c#2 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_init.c#4 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_join.c#3 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_kern.c#5 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_private.h#5 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_spinlock.c#3 integrate
.. //depot/projects/hammer/lib/libthr/thread/thr_stack.c#2 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/early-adopter/article.sgml#4 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/errata/article.sgml#4 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/hardware/alpha/proc-alpha.sgml#5 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/hardware/common/dev.sgml#7 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/hardware/common/intro.sgml#3 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/hardware/i386/proc-i386.sgml#4 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/hardware/ia64/article.sgml#4 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/hardware/ia64/proc-ia64.sgml#3 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/hardware/sparc64/proc-sparc64.sgml#4 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/installation/common/install.sgml#6 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/installation/common/trouble.sgml#5 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/installation/common/upgrade.sgml#4 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/readme/article.sgml#5 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/relnotes/common/new.sgml#8 integrate
.. //depot/projects/hammer/release/doc/de_DE.ISO8859-1/share/sgml/release.dsl#5 integrate
.. //depot/projects/hammer/release/doc/en_US.ISO8859-1/relnotes/common/new.sgml#28 integrate
.. //depot/projects/hammer/release/doc/ja_JP.eucJP/early-adopter/article.sgml#3 integrate
.. //depot/projects/hammer/release/doc/ja_JP.eucJP/hardware/common/dev.sgml#5 integrate
.. //depot/projects/hammer/release/doc/ja_JP.eucJP/hardware/common/intro.sgml#3 integrate
.. //depot/projects/hammer/release/doc/ja_JP.eucJP/hardware/i386/proc-i386.sgml#4 integrate
.. //depot/projects/hammer/release/doc/ja_JP.eucJP/hardware/ia64/article.sgml#3 integrate
.. //depot/projects/hammer/release/doc/ja_JP.eucJP/hardware/ia64/proc-ia64.sgml#3 integrate
.. //depot/projects/hammer/release/doc/ja_JP.eucJP/share/sgml/release.dsl#5 integrate
.. //depot/projects/hammer/sys/alpha/alpha/busdma_machdep.c#7 integrate
.. //depot/projects/hammer/sys/alpha/include/bus.h#7 integrate
.. //depot/projects/hammer/sys/amd64/amd64/busdma_machdep.c#5 integrate
.. //depot/projects/hammer/sys/amd64/include/bus_dma.h#6 integrate
.. //depot/projects/hammer/sys/contrib/dev/acpica/dsmethod.c#5 integrate
.. //depot/projects/hammer/sys/contrib/dev/acpica/nsalloc.c#4 integrate
.. //depot/projects/hammer/sys/dev/advansys/advansys.c#5 integrate
.. //depot/projects/hammer/sys/dev/advansys/adwcam.c#5 integrate
.. //depot/projects/hammer/sys/dev/aha/aha.c#6 integrate
.. //depot/projects/hammer/sys/dev/ahb/ahb.c#5 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic79xx.c#7 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic79xx.h#6 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic79xx.reg#7 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic79xx.seq#6 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic79xx_inline.h#6 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic79xx_osm.c#6 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic79xx_osm.h#4 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic79xx_pci.c#6 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic7xxx.c#7 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic7xxx.h#5 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic7xxx.reg#5 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic7xxx.seq#4 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic7xxx_inline.h#5 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic7xxx_osm.c#9 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic7xxx_osm.h#6 integrate
.. //depot/projects/hammer/sys/dev/aic7xxx/aic7xxx_pci.c#5 integrate
.. //depot/projects/hammer/sys/dev/amd/amd.c#3 integrate
.. //depot/projects/hammer/sys/dev/buslogic/bt.c#6 integrate
.. //depot/projects/hammer/sys/dev/dpt/dpt_scsi.c#6 integrate
.. //depot/projects/hammer/sys/dev/firewire/fwdma.h#2 integrate
.. //depot/projects/hammer/sys/dev/ida/ida.c#6 integrate
.. //depot/projects/hammer/sys/dev/mpt/mpt_freebsd.c#6 integrate
.. //depot/projects/hammer/sys/dev/trm/trm.c#5 integrate
.. //depot/projects/hammer/sys/geom/geom_disk.c#13 integrate
.. //depot/projects/hammer/sys/i386/i386/busdma_machdep.c#8 integrate
.. //depot/projects/hammer/sys/i386/include/bus_dma.h#5 integrate
.. //depot/projects/hammer/sys/ia64/ia64/busdma_machdep.c#7 integrate
.. //depot/projects/hammer/sys/ia64/ia64/exception.s#12 integrate
.. //depot/projects/hammer/sys/ia64/ia64/machdep.c#15 integrate
.. //depot/projects/hammer/sys/ia64/ia64/pmap.c#13 integrate
.. //depot/projects/hammer/sys/ia64/ia64/support.s#4 integrate
.. //depot/projects/hammer/sys/ia64/ia64/unwind.c#4 integrate
.. //depot/projects/hammer/sys/ia64/include/bus.h#6 integrate
.. //depot/projects/hammer/sys/kern/kern_alq.c#5 integrate
.. //depot/projects/hammer/sys/kern/kern_umtx.c#2 integrate
.. //depot/projects/hammer/sys/kern/subr_sbuf.c#6 integrate
.. //depot/projects/hammer/sys/pci/agp_intel.c#6 integrate
.. //depot/projects/hammer/sys/pci/agpreg.h#4 integrate
.. //depot/projects/hammer/sys/powerpc/include/bus.h#5 integrate
.. //depot/projects/hammer/sys/powerpc/powerpc/busdma_machdep.c#6 integrate
.. //depot/projects/hammer/sys/sparc64/include/bus.h#8 integrate
.. //depot/projects/hammer/sys/sparc64/include/iommuvar.h#5 integrate
.. //depot/projects/hammer/sys/sparc64/pci/psycho.c#10 integrate
.. //depot/projects/hammer/sys/sparc64/sbus/sbus.c#5 integrate
.. //depot/projects/hammer/sys/sparc64/sparc64/bus_machdep.c#8 integrate
.. //depot/projects/hammer/sys/sparc64/sparc64/iommu.c#7 integrate
.. //depot/projects/hammer/tools/tools/tinderbox/tbmaster.pl#8 integrate
.. //depot/projects/hammer/usr.bin/usbhidctl/usbhid.c#3 integrate
.. //depot/projects/hammer/usr.sbin/pkg_install/info/show.c#6 integrate
.. //depot/projects/hammer/usr.sbin/pkg_install/lib/lib.h#5 integrate
.. //depot/projects/hammer/usr.sbin/pkg_install/lib/str.c#2 integrate
Differences ...
==== //depot/projects/hammer/lib/libthr/arch/i386/i386/_setcurthread.c#6 (text+ko) ====
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/arch/i386/i386/_setcurthread.c,v 1.7 2003/05/23 23:39:31 mtm Exp $
+ * $FreeBSD: src/lib/libthr/arch/i386/i386/_setcurthread.c,v 1.8 2003/05/25 22:40:57 mtm Exp $
*/
#include <sys/types.h>
@@ -87,13 +87,15 @@
}
void *
-_set_curthread(ucontext_t *uc, struct pthread *thr)
+_set_curthread(ucontext_t *uc, struct pthread *thr, int *err)
{
union descriptor desc;
void **ldt_entry;
int ldt_index;
int error;
+ *err = 0;
+
/*
* If we are setting up the initial thread, the gs register
* won't be setup for the current thread. In any case, we
@@ -106,8 +108,11 @@
if (ldt_inited == NULL)
ldt_init();
- if (ldt_free == NULL)
- abort();
+ if (ldt_free == NULL) {
+ /* Concurrent thread limit reached */
+ *err = curthread->error = EAGAIN;
+ return (NULL);
+ }
/*
* Pull one off of the free list and update the free list pointer.
==== //depot/projects/hammer/lib/libthr/arch/ia64/ia64/_curthread.c#3 (text+ko) ====
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libthr/arch/ia64/ia64/_curthread.c,v 1.2 2003/05/25 06:49:19 marcel Exp $");
+__FBSDID("$FreeBSD: src/lib/libthr/arch/ia64/ia64/_curthread.c,v 1.3 2003/05/25 22:40:57 mtm Exp $");
#include <sys/types.h>
#include <sys/ucontext.h>
@@ -48,9 +48,9 @@
}
void *
-_set_curthread(ucontext_t *uc, struct pthread *thread)
+_set_curthread(ucontext_t *uc, struct pthread *thread, int *err)
{
-
+ *err = 0;
if (uc != NULL)
uc->uc_mcontext.mc_special.tp = (uint64_t)thread;
else
==== //depot/projects/hammer/lib/libthr/arch/sparc64/sparc64/_setcurthread.c#2 (text+ko) ====
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libthr/arch/sparc64/sparc64/_setcurthread.c,v 1.2 2003/04/03 03:34:50 jake Exp $");
+__FBSDID("$FreeBSD: src/lib/libthr/arch/sparc64/sparc64/_setcurthread.c,v 1.3 2003/05/25 22:40:57 mtm Exp $");
#include <sys/types.h>
#include <sys/ucontext.h>
@@ -48,9 +48,9 @@
}
void *
-_set_curthread(ucontext_t *uc, struct pthread *thread)
+_set_curthread(ucontext_t *uc, struct pthread *thread, int *err)
{
-
+ *err = 0;
if (uc != NULL)
uc->uc_mcontext.mc_global[6] = (uint64_t)thread;
else
==== //depot/projects/hammer/lib/libthr/thread/thr_cancel.c#4 (text+ko) ====
@@ -1,6 +1,6 @@
/*
* David Leonard <d at openbsd.org>, 1999. Public domain.
- * $FreeBSD: src/lib/libthr/thread/thr_cancel.c,v 1.4 2003/05/23 09:48:20 mtm Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_cancel.c,v 1.5 2003/05/25 08:48:11 mtm Exp $
*/
#include <sys/errno.h>
#include <pthread.h>
@@ -21,7 +21,16 @@
_pthread_cancel(pthread_t pthread)
{
int ret;
+ pthread_t joined;
+ /*
+ * When canceling a thread that has joined another thread, this
+ * routine breaks the normal lock order of locking first the
+ * joined and then the joiner. Therefore, it is necessary that
+ * if it can't obtain the second lock, that it release the first
+ * one and restart from the top.
+ */
+retry:
if ((ret = _find_thread(pthread)) != 0)
/* The thread is not on the list of active threads */
goto out;
@@ -70,10 +79,14 @@
/*
* Disconnect the thread from the joinee:
*/
- if (pthread->join_status.thread != NULL) {
- pthread->join_status.thread->joiner
- = NULL;
- pthread->join_status.thread = NULL;
+ if ((joined = pthread->join_status.thread) != NULL) {
+ if (_spintrylock(&joined->lock) == EBUSY) {
+ _thread_critical_exit(pthread);
+ goto retry;
+ }
+ pthread->join_status.thread->joiner = NULL;
+ _spinunlock(&joined->lock);
+ joined = pthread->join_status.thread = NULL;
}
pthread->cancelflags |= PTHREAD_CANCELLING;
PTHREAD_NEW_STATE(pthread, PS_RUNNING);
==== //depot/projects/hammer/lib/libthr/thread/thr_create.c#5 (text+ko) ====
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/thread/thr_create.c,v 1.6 2003/05/23 09:48:20 mtm Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_create.c,v 1.9 2003/05/26 00:37:07 mtm Exp $
*/
#include <errno.h>
#include <stdlib.h>
@@ -116,7 +116,17 @@
new_thread->ctx.uc_stack.ss_sp = new_thread->stack;
new_thread->ctx.uc_stack.ss_size = pattr->stacksize_attr;
makecontext(&new_thread->ctx, _thread_start, 0);
- new_thread->arch_id = _set_curthread(&new_thread->ctx, new_thread);
+ new_thread->arch_id = _set_curthread(&new_thread->ctx, new_thread, &ret);
+ if (ret != 0) {
+ if (pattr->stackaddr_attr == NULL) {
+ STACK_LOCK;
+ _thread_stack_free(new_thread->stack,
+ pattr->stacksize_attr, pattr->guardsize_attr);
+ STACK_UNLOCK;
+ }
+ free(new_thread);
+ return (ret);
+ }
/* Copy the thread attributes: */
memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));
@@ -155,16 +165,14 @@
new_thread->flags = 0;
/*
- * Protect the scheduling queues.
- */
- GIANT_LOCK(curthread);
-
- /*
* Initialise the unique id which GDB uses to
* track threads.
*/
new_thread->uniqueid = next_uniqueid++;
+ THREAD_LIST_LOCK;
+ _thread_critical_enter(new_thread);
+
/*
* Check if the garbage collector thread
* needs to be started.
@@ -174,6 +182,8 @@
/* Add the thread to the linked list of all threads: */
TAILQ_INSERT_HEAD(&_thread_list, new_thread, tle);
+ THREAD_LIST_UNLOCK;
+
/*
* Create the thread.
*
@@ -190,11 +200,11 @@
PANIC("thr_create");
}
- GIANT_UNLOCK(curthread);
-
/* Return a pointer to the thread structure: */
(*thread) = new_thread;
+ _thread_critical_exit(new_thread);
+
/*
* Start a garbage collector thread
* if necessary.
==== //depot/projects/hammer/lib/libthr/thread/thr_exit.c#4 (text+ko) ====
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/thread/thr_exit.c,v 1.5 2003/05/23 09:48:20 mtm Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_exit.c,v 1.6 2003/05/25 08:31:33 mtm Exp $
*/
#include <errno.h>
#include <unistd.h>
@@ -95,6 +95,7 @@
_pthread_exit(void *status)
{
pthread_t pthread;
+ int exitNow = 0;
/* Check if this thread is already in the process of exiting: */
if ((curthread->flags & PTHREAD_EXITING) != 0) {
@@ -121,37 +122,14 @@
_thread_cleanupspecific();
}
- /*
- * Lock the garbage collector mutex to ensure that the garbage
- * collector is not using the dead thread list.
- */
- if (pthread_mutex_lock(&_gc_mutex) != 0)
- PANIC("Cannot lock gc mutex");
-
- /* Add this thread to the list of dead threads. */
- TAILQ_INSERT_HEAD(&_dead_list, curthread, dle);
-
- /*
- * Signal the garbage collector thread that there is something
- * to clean up.
- */
- if (pthread_cond_signal(&_gc_cond) != 0)
- PANIC("Cannot signal gc cond");
-
- /*
- * Avoid a race condition where a scheduling signal can occur
- * causing the garbage collector thread to run. If this happens,
- * the current thread can be cleaned out from under us.
- */
- GIANT_LOCK(curthread);
+ /* Lock the dead list first to maintain correct lock order */
+ DEAD_LIST_LOCK;
+ _thread_critical_enter(curthread);
- /* Unlock the garbage collector mutex. */
- if (pthread_mutex_unlock(&_gc_mutex) != 0)
- PANIC("Cannot unlock gc mutex");
-
/* Check if there is a thread joining this one: */
if (curthread->joiner != NULL) {
pthread = curthread->joiner;
+ _SPINLOCK(&pthread->lock);
curthread->joiner = NULL;
/* Make the joining thread runnable: */
@@ -161,6 +139,7 @@
pthread->join_status.ret = curthread->ret;
pthread->join_status.error = 0;
pthread->join_status.thread = NULL;
+ _SPINUNLOCK(&pthread->lock);
/* Make this thread collectable by the garbage collector. */
PTHREAD_ASSERT(((curthread->attr.flags & PTHREAD_DETACHED) ==
@@ -168,14 +147,31 @@
curthread->attr.flags |= PTHREAD_DETACHED;
}
- /* Remove this thread from the thread list: */
+ /*
+ * Add this thread to the list of dead threads, and
+ * also remove it from the active threads list.
+ */
+ THREAD_LIST_LOCK;
+ TAILQ_INSERT_HEAD(&_dead_list, curthread, dle);
TAILQ_REMOVE(&_thread_list, curthread, tle);
-
PTHREAD_SET_STATE(curthread, PS_DEAD);
- GIANT_UNLOCK(curthread);
+ _thread_critical_exit(curthread);
+
+ /*
+ * Signal the garbage collector thread that there is something
+ * to clean up.
+ */
+ if (pthread_cond_signal(&_gc_cond) != 0)
+ PANIC("Cannot signal gc cond");
/* If we're the last thread, call it quits */
if (TAILQ_EMPTY(&_thread_list))
+ exitNow = 1;
+
+ THREAD_LIST_UNLOCK;
+ DEAD_LIST_UNLOCK;
+
+ if (exitNow)
exit(0);
/*
==== //depot/projects/hammer/lib/libthr/thread/thr_find_thread.c#2 (text+ko) ====
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/thread/thr_find_thread.c,v 1.2 2003/04/02 03:05:39 jeff Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_find_thread.c,v 1.3 2003/05/25 08:35:37 mtm Exp $
*/
#include <errno.h>
#include <pthread.h>
@@ -44,7 +44,7 @@
if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
return(EINVAL);
- GIANT_LOCK(curthread);
+ THREAD_LIST_LOCK;
/* Search for the specified thread: */
TAILQ_FOREACH(pthread1, &_thread_list, tle) {
@@ -52,7 +52,7 @@
break;
}
- GIANT_UNLOCK(curthread);
+ THREAD_LIST_UNLOCK;
/* Return zero if the thread exists: */
return ((pthread1 != NULL) ? 0:ESRCH);
==== //depot/projects/hammer/lib/libthr/thread/thr_gc.c#3 (text+ko) ====
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/thread/thr_gc.c,v 1.3 2003/04/20 02:56:12 marcel Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_gc.c,v 1.5 2003/05/26 00:37:07 mtm Exp $
*
* Garbage collector thread. Frees memory allocated for dead threads.
*
@@ -75,19 +75,17 @@
_thread_dump_info();
/*
- * Lock the garbage collector mutex which ensures that
+ * Lock the list of dead threads which ensures that
* this thread sees another thread exit:
*/
- if (pthread_mutex_lock(&_gc_mutex) != 0)
- PANIC("Cannot lock gc mutex");
+ DEAD_LIST_LOCK;
/* No stack or thread structure to free yet. */
p_stack = NULL;
pthread_cln = NULL;
- GIANT_LOCK(curthread);
-
/* Check if this is the last running thread. */
+ THREAD_LIST_LOCK;
if (TAILQ_FIRST(&_thread_list) == curthread &&
TAILQ_NEXT(curthread, tle) == NULL)
/*
@@ -95,6 +93,7 @@
* now.
*/
f_done = 1;
+ THREAD_LIST_UNLOCK;
/*
* Enter a loop to search for the first dead thread that
@@ -106,57 +105,45 @@
/* Don't destroy the initial thread. */
if (pthread == _thread_initial)
continue;
+
+ _SPINLOCK(&pthread->lock);
+
/*
- * Check if this thread has detached:
+ * Check if the stack was not specified by
+ * the caller to pthread_create() and has not
+ * been destroyed yet:
*/
- if ((pthread->attr.flags &
- PTHREAD_DETACHED) != 0) {
- /* Remove this thread from the dead list: */
- TAILQ_REMOVE(&_dead_list, pthread, dle);
+ STACK_LOCK;
+ if (pthread->attr.stackaddr_attr == NULL &&
+ pthread->stack != NULL) {
+ _thread_stack_free(pthread->stack,
+ pthread->attr.stacksize_attr,
+ pthread->attr.guardsize_attr);
+ pthread->stack = NULL;
+ }
+ STACK_UNLOCK;
- /*
- * Check if the stack was not specified by
- * the caller to pthread_create() and has not
- * been destroyed yet:
- */
- if (pthread->attr.stackaddr_attr == NULL &&
- pthread->stack != NULL) {
- _thread_stack_free(pthread->stack,
- pthread->attr.stacksize_attr,
- pthread->attr.guardsize_attr);
- }
+ /*
+ * If the thread has not been detached, leave
+ * it on the dead thread list.
+ */
+ if ((pthread->attr.flags & PTHREAD_DETACHED) == 0) {
+ _SPINUNLOCK(&pthread->lock);
+ continue;
+ }
- /*
- * Point to the thread structure that must
- * be freed outside the locks:
- */
- pthread_cln = pthread;
+ /* Remove this thread from the dead list: */
+ TAILQ_REMOVE(&_dead_list, pthread, dle);
- } else {
- /*
- * This thread has not detached, so do
- * not destroy it.
- *
- * Check if the stack was not specified by
- * the caller to pthread_create() and has not
- * been destroyed yet:
- */
- if (pthread->attr.stackaddr_attr == NULL &&
- pthread->stack != NULL) {
- _thread_stack_free(pthread->stack,
- pthread->attr.stacksize_attr,
- pthread->attr.guardsize_attr);
+ /*
+ * Point to the thread structure that must
+ * be freed outside the locks:
+ */
+ pthread_cln = pthread;
- /*
- * NULL the stack pointer now that the
- * memory has been freed:
- */
- pthread->stack = NULL;
- }
- }
+ _SPINUNLOCK(&pthread->lock);
}
- GIANT_UNLOCK(curthread);
/*
* Check if this is not the last thread and there is no
* memory to free this time around.
@@ -177,15 +164,14 @@
* timeout (for a backup poll).
*/
if ((ret = pthread_cond_timedwait(&_gc_cond,
- &_gc_mutex, &abstime)) != 0 && ret != ETIMEDOUT) {
+ &dead_list_lock, &abstime)) != 0 && ret != ETIMEDOUT) {
_thread_printf(STDERR_FILENO, "ret = %d", ret);
PANIC("gc cannot wait for a signal");
}
}
/* Unlock the garbage collector mutex: */
- if (pthread_mutex_unlock(&_gc_mutex) != 0)
- PANIC("Cannot unlock gc mutex");
+ DEAD_LIST_UNLOCK;
/*
* If there is memory to free, do it now. The call to
==== //depot/projects/hammer/lib/libthr/thread/thr_info.c#2 (text+ko) ====
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/thread/thr_info.c,v 1.2 2003/04/02 03:05:39 jeff Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_info.c,v 1.3 2003/05/25 08:31:33 mtm Exp $
*/
#include <stdio.h>
#include <stdlib.h>
@@ -109,6 +109,7 @@
}
/* Check if there are no dead threads: */
+ DEAD_LIST_LOCK;
if (TAILQ_FIRST(&_dead_list) == NULL) {
/* Output a record: */
strcpy(s, "\n\nTHERE ARE NO DEAD THREADS\n");
@@ -126,6 +127,7 @@
dump_thread(fd, pthread, /*long_version*/ 0);
}
}
+ DEAD_LIST_UNLOCK;
/* Close the dump file: */
__sys_close(fd);
==== //depot/projects/hammer/lib/libthr/thread/thr_init.c#4 (text+ko) ====
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/thread/thr_init.c,v 1.5 2003/05/23 09:48:20 mtm Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_init.c,v 1.7 2003/05/25 22:40:57 mtm Exp $
*/
/* Allocate space for global thread variables here: */
@@ -162,6 +162,7 @@
size_t len;
int mib[2];
sigset_t set;
+ int error;
struct clockinfo clockinfo;
struct sigaction act;
@@ -221,7 +222,7 @@
memset(pthread, 0, sizeof(struct pthread));
_thread_initial = pthread;
- pthread->arch_id = _set_curthread(NULL, pthread);
+ pthread->arch_id = _set_curthread(NULL, pthread, &error);
/* Get our thread id. */
thr_self(&pthread->thr_id);
@@ -326,7 +327,7 @@
clockinfo.tick : CLOCK_RES_USEC_MIN;
/* Initialise the garbage collector mutex and condition variable. */
- if (_pthread_mutex_init(&_gc_mutex,NULL) != 0 ||
+ if (_pthread_mutex_init(&dead_list_lock,NULL) != 0 ||
_pthread_cond_init(&_gc_cond,NULL) != 0)
PANIC("Failed to initialise garbage collector mutex or condvar");
}
==== //depot/projects/hammer/lib/libthr/thread/thr_join.c#3 (text+ko) ====
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/thread/thr_join.c,v 1.4 2003/05/20 18:48:41 mtm Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_join.c,v 1.6 2003/05/26 00:28:49 mtm Exp $
*/
#include <errno.h>
#include <pthread.h>
@@ -60,38 +60,36 @@
}
/*
- * Lock the garbage collector mutex to ensure that the garbage
- * collector is not using the dead thread list.
- */
- if (pthread_mutex_lock(&_gc_mutex) != 0)
- PANIC("Cannot lock gc mutex");
-
- GIANT_LOCK(curthread);
-
- /*
* Search for the specified thread in the list of active threads. This
* is done manually here rather than calling _find_thread() because
* the searches in _thread_list and _dead_list (as well as setting up
* join/detach state) have to be done atomically.
*/
+ DEAD_LIST_LOCK;
+ THREAD_LIST_LOCK;
TAILQ_FOREACH(thread, &_thread_list, tle)
- if (thread == pthread)
+ if (thread == pthread) {
+ _SPINLOCK(&pthread->lock);
break;
+ }
if (thread == NULL)
/*
* Search for the specified thread in the list of dead threads:
*/
TAILQ_FOREACH(thread, &_dead_list, dle)
- if (thread == pthread)
+ if (thread == pthread) {
+ _SPINLOCK(&pthread->lock);
break;
-
+ }
/* Check if the thread was not found or has been detached: */
if (thread == NULL ||
((pthread->attr.flags & PTHREAD_DETACHED) != 0)) {
- if (pthread_mutex_unlock(&_gc_mutex) != 0)
- PANIC("Cannot lock gc mutex");
+ if (thread != NULL)
+ _SPINUNLOCK(&pthread->lock);
+ THREAD_LIST_UNLOCK;
+ DEAD_LIST_UNLOCK;
ret = ESRCH;
goto out;
@@ -99,21 +97,17 @@
if (pthread->joiner != NULL) {
/* Multiple joiners are not supported. */
/* XXXTHR - support multiple joiners. */
- if (pthread_mutex_unlock(&_gc_mutex) != 0)
- PANIC("Cannot lock gc mutex");
+ _SPINUNLOCK(&pthread->lock);
+ THREAD_LIST_UNLOCK;
+ DEAD_LIST_UNLOCK;
ret = ENOTSUP;
goto out;
}
- /*
- * Unlock the garbage collector mutex, now that the garbage collector
- * can't be run:
- */
- if (pthread_mutex_unlock(&_gc_mutex) != 0)
- PANIC("Cannot lock gc mutex");
/* Check if the thread is not dead: */
if (pthread->state != PS_DEAD) {
+ _thread_critical_enter(curthread);
/* Set the running thread to be the joiner: */
pthread->joiner = curthread;
@@ -123,9 +117,13 @@
while (curthread->join_status.thread == pthread) {
PTHREAD_SET_STATE(curthread, PS_JOIN);
/* Wait for our signal to wake up. */
- GIANT_UNLOCK(curthread);
+ _thread_critical_exit(curthread);
+ _SPINUNLOCK(&pthread->lock);
+ THREAD_LIST_UNLOCK;
+ DEAD_LIST_UNLOCK;
_thread_suspend(curthread, NULL);
- GIANT_LOCK(curthread);
+
+ _thread_critical_enter(curthread);
}
/*
@@ -135,6 +133,7 @@
ret = curthread->join_status.error;
if ((ret == 0) && (thread_return != NULL))
*thread_return = curthread->join_status.ret;
+ _thread_critical_exit(curthread);
} else {
/*
* The thread exited (is dead) without being detached, and no
@@ -149,12 +148,14 @@
/* Make the thread collectable by the garbage collector. */
pthread->attr.flags |= PTHREAD_DETACHED;
-
+ _SPINUNLOCK(&pthread->lock);
+ if (pthread_cond_signal(&_gc_cond) != 0)
+ PANIC("Cannot signal gc cond");
+ THREAD_LIST_UNLOCK;
+ DEAD_LIST_UNLOCK;
}
out:
- GIANT_UNLOCK(curthread);
-
_thread_leave_cancellation_point();
/* Return the completion status: */
==== //depot/projects/hammer/lib/libthr/thread/thr_kern.c#5 (text+ko) ====
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/thread/thr_kern.c,v 1.7 2003/05/23 10:28:13 mtm Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_kern.c,v 1.8 2003/05/25 07:58:22 mtm Exp $
*/
#include <sys/cdefs.h>
@@ -68,6 +68,13 @@
* acquired the giant lock.
*/
_SPINLOCK(&pthread->lock);
+
+ /* If we are already in a critical section, just up the refcount */
+ if (++curthread->crit_ref > 1)
+ return;
+ PTHREAD_ASSERT(curthread->crit_ref == 1,
+ ("Critical section reference count must be 1!"));
+
if (__sys_sigprocmask(SIG_SETMASK, &set, &sav)) {
_thread_printf(STDERR_FILENO, "Critical Enter: sig err %d\n",
errno);
@@ -81,6 +88,12 @@
{
sigset_t set;
+ /* We might be in a nested critical section */
+ if (--curthread->crit_ref > 0)
+ return;
+ PTHREAD_ASSERT(curthread->crit_ref == 0,
+ ("Non-Zero critical section reference count."));
+
/*
* Restore signals.
*/
==== //depot/projects/hammer/lib/libthr/thread/thr_private.h#5 (text+ko) ====
@@ -31,7 +31,7 @@
*
* Private thread definitions for the uthread kernel.
*
- * $FreeBSD: src/lib/libthr/thread/thr_private.h,v 1.9 2003/05/23 23:39:31 mtm Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_private.h,v 1.14 2003/05/26 00:37:07 mtm Exp $
*/
#ifndef _THR_PRIVATE_H
@@ -426,6 +426,7 @@
u_int64_t uniqueid; /* for gdb */
thr_id_t thr_id;
sigset_t savedsig;
+ int crit_ref; /* crit. section netsting level */
/*
* Lock for accesses to this thread structure.
@@ -577,6 +578,14 @@
;
#endif
+SCLASS spinlock_t stack_lock
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= _SPINLOCK_INITIALIZER
+#endif
+;
+#define STACK_LOCK _SPINLOCK(&stack_lock);
+#define STACK_UNLOCK _SPINUNLOCK(&stack_lock);
+
/* List of all threads: */
SCLASS TAILQ_HEAD(, pthread) _thread_list
#ifdef GLOBAL_PTHREAD_PRIVATE
@@ -593,6 +602,34 @@
;
#endif
+/*
+ * These two locks protect the global active threads list and
+ * the global dead threads list, respectively. Combining these
+ * into one lock for both lists doesn't seem wise, since it
+ * would likely increase contention during busy thread creation
+ * and destruction for very little savings in space.
+ *
+ * The lock for the "dead threads list" must be a pthread mutex
+ * because it is used with condition variables to synchronize
+ * the gc thread with active threads in the process of exiting or
+ * dead threads who have just been joined.
+ */
+SCLASS spinlock_t thread_list_lock
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= _SPINLOCK_INITIALIZER
+#endif
+;
+SCLASS pthread_mutex_t dead_list_lock
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL
+#endif
+;
+
+#define THREAD_LIST_LOCK _SPINLOCK(&thread_list_lock)
+#define THREAD_LIST_UNLOCK _SPINUNLOCK(&thread_list_lock)
+#define DEAD_LIST_LOCK _pthread_mutex_lock(&dead_list_lock)
+#define DEAD_LIST_UNLOCK _pthread_mutex_unlock(&dead_list_lock)
+
/* Initial thread: */
SCLASS struct pthread *_thread_initial
#ifdef GLOBAL_PTHREAD_PRIVATE
@@ -643,12 +680,7 @@
SCLASS int _giant_count;
-/* Garbage collector mutex and condition variable. */
-SCLASS pthread_mutex_t _gc_mutex
-#ifdef GLOBAL_PTHREAD_PRIVATE
-= NULL
-#endif
-;
+/* Garbage collector condition variable. */
SCLASS pthread_cond_t _gc_cond
#ifdef GLOBAL_PTHREAD_PRIVATE
= NULL
@@ -687,7 +719,7 @@
void _cond_wait_backout(pthread_t);
int _find_thread(pthread_t);
pthread_t _get_curthread(void);
-void *_set_curthread(ucontext_t *, struct pthread *);
+void *_set_curthread(ucontext_t *, struct pthread *, int *);
void _retire_thread(void *arch_id);
void *_thread_stack_alloc(size_t, size_t);
void _thread_stack_free(void *, size_t, size_t);
@@ -713,6 +745,7 @@
int _pthread_once(pthread_once_t *, void (*) (void));
pthread_t _pthread_self(void);
int _pthread_setspecific(pthread_key_t, const void *);
+int _spintrylock(spinlock_t *);
inline void _spinlock_pthread(pthread_t, spinlock_t *);
inline void _spinunlock_pthread(pthread_t, spinlock_t *);
void _thread_exit(char *, int, char *);
==== //depot/projects/hammer/lib/libthr/thread/thr_spinlock.c#3 (text+ko) ====
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/thread/thr_spinlock.c,v 1.3 2003/05/23 23:39:31 mtm Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_spinlock.c,v 1.4 2003/05/25 08:48:11 mtm Exp $
*
*/
@@ -69,6 +69,16 @@
_spinlock_pthread(curthread, lck);
}
+int
+_spintrylock(spinlock_t *lck)
+{
+ int error;
+ error = umtx_trylock((struct umtx *)lck, curthread->thr_id);
+ if (error != 0 && error != EBUSY)
+ abort();
+ return (error);
+}
+
inline void
_spinlock_pthread(pthread_t pthread, spinlock_t *lck)
{
==== //depot/projects/hammer/lib/libthr/thread/thr_stack.c#2 (text+ko) ====
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/thread/thr_stack.c,v 1.1 2003/04/01 03:46:29 jeff Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_stack.c,v 1.3 2003/05/26 00:37:07 mtm Exp $
*/
#include <sys/types.h>
#include <sys/mman.h>
@@ -144,8 +144,7 @@
* Use the garbage collector mutex for synchronization of the
* spare stack list.
*/
- if (pthread_mutex_lock(&_gc_mutex) != 0)
- PANIC("Cannot lock gc mutex");
+ STACK_LOCK;
if ((spare_stack = LIST_FIRST(&_dstackq)) != NULL) {
/* Use the spare stack. */
@@ -154,8 +153,7 @@
}
/* Unlock the garbage collector mutex. */
- if (pthread_mutex_unlock(&_gc_mutex) != 0)
- PANIC("Cannot unlock gc mutex");
+ STACK_UNLOCK;
}
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list