Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 May 2003 13:27:17 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 31865 for review
Message-ID:  <200305252027.h4PKRH6E007869@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=31865

Change 31865 by marcel@marcel_nfs on 2003/05/25 13:27:16

	IFC @31863

Affected files ...

.. //depot/projects/ia64/lib/libthr/arch/ia64/ia64/_curthread.c#4 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_cancel.c#4 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_create.c#6 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_exit.c#4 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_find_thread.c#2 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_gc.c#4 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_info.c#2 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_init.c#4 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_join.c#3 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_kern.c#6 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_private.h#4 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_spinlock.c#3 integrate
.. //depot/projects/ia64/lib/libthr/thread/thr_stack.c#2 integrate
.. //depot/projects/ia64/release/Makefile.inc.docports#10 integrate
.. //depot/projects/ia64/sys/dev/fxp/if_fxp.c#32 integrate
.. //depot/projects/ia64/sys/geom/geom_disk.c#34 integrate
.. //depot/projects/ia64/sys/ia64/ia64/trap.c#52 integrate
.. //depot/projects/ia64/sys/kern/kern_alq.c#5 integrate
.. //depot/projects/ia64/sys/kern/kern_umtx.c#2 integrate
.. //depot/projects/ia64/sys/kern/subr_sbuf.c#10 integrate
.. //depot/projects/ia64/sys/nfsserver/nfs.h#6 integrate
.. //depot/projects/ia64/sys/nfsserver/nfs_serv.c#21 integrate
.. //depot/projects/ia64/sys/nfsserver/nfs_srvsubs.c#10 integrate
.. //depot/projects/ia64/usr.sbin/Makefile#39 integrate
.. //depot/projects/ia64/usr.sbin/ppp/ncpaddr.c#8 integrate

Differences ...

==== //depot/projects/ia64/lib/libthr/arch/ia64/ia64/_curthread.c#4 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libthr/arch/ia64/ia64/_curthread.c,v 1.1 2003/04/20 03:06:42 marcel Exp $");
+__FBSDID("$FreeBSD: src/lib/libthr/arch/ia64/ia64/_curthread.c,v 1.2 2003/05/25 06:49:19 marcel Exp $");
 
 #include <sys/types.h>
 #include <sys/ucontext.h>
@@ -52,7 +52,7 @@
 {
 
 	if (uc != NULL)
-		uc->uc_mcontext.mc_gr[13] = (uint64_t)thread;
+		uc->uc_mcontext.mc_special.tp = (uint64_t)thread;
 	else
 		_tp = thread;
 	return (NULL);

==== //depot/projects/ia64/lib/libthr/thread/thr_cancel.c#4 (text+ko) ====

@@ -1,6 +1,6 @@
 /*
  * David Leonard <d@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/ia64/lib/libthr/thread/thr_create.c#6 (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.7 2003/05/25 08:35:37 mtm Exp $
  */
 #include <errno.h>
 #include <stdlib.h>
@@ -155,16 +155,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 +172,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 +190,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/ia64/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/ia64/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/ia64/lib/libthr/thread/thr_gc.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_gc.c,v 1.3 2003/04/20 02:56:12 marcel Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_gc.c,v 1.4 2003/05/25 08:31:33 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,43 @@
 			/* 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);
+			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;
+			}
 
-				/*
-				 * 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 +162,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/ia64/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/ia64/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.6 2003/05/25 08:31:33 mtm Exp $
  */
 
 /* Allocate space for global thread variables here: */
@@ -326,7 +326,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/ia64/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.5 2003/05/25 08:31:33 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;
+			}
+	THREAD_LIST_UNLOCK;
 
-
 	/* 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);
+		DEAD_LIST_UNLOCK;
 		ret = ESRCH;
 		goto out;
 
@@ -99,33 +97,32 @@
 	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);
+		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;
 
 		/* Keep track of which thread we're joining to: */
 		curthread->join_status.thread = pthread;
+		_SPINUNLOCK(&pthread->lock);
 
 		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);
+			DEAD_LIST_UNLOCK;
 			_thread_suspend(curthread, NULL);
-			GIANT_LOCK(curthread);
+			/* XXX - For correctness reasons. */
+			DEAD_LIST_LOCK;
+			_thread_critical_enter(curthread);
 		}
 
 		/*
@@ -135,6 +132,15 @@
 		ret = curthread->join_status.error;
 		if ((ret == 0) && (thread_return != NULL))
 			*thread_return = curthread->join_status.ret;
+		_thread_critical_exit(curthread);
+		/*
+		 * XXX - Must unlock here, instead of doing it earlier,
+		 *	 because it could lead to a deadlock. If the thread
+		 *	 we are joining is waiting on this lock we would
+		 *	 deadlock if we released this lock before unlocking the
+		 *	 joined thread.
+		 */
+		DEAD_LIST_UNLOCK;
 	} else {
 		/*
 		 * The thread exited (is dead) without being detached, and no
@@ -149,12 +155,13 @@
 
 		/* 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");
+		DEAD_LIST_UNLOCK;
 	}
 
 out:
-	GIANT_UNLOCK(curthread);
-
 	_thread_leave_cancellation_point();
 
 	/* Return the completion status: */

==== //depot/projects/ia64/lib/libthr/thread/thr_kern.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/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/ia64/lib/libthr/thread/thr_private.h#4 (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.12 2003/05/25 08:48:11 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.
@@ -593,6 +594,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 +672,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
@@ -713,6 +737,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/ia64/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/ia64/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.2 2003/05/25 08:31:33 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");
+		DEAD_LIST_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");
+		DEAD_LIST_UNLOCK;
 	}
 	/*
 	 * The user specified a non-default stack and/or guard size, so try to
@@ -167,8 +165,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");
+		DEAD_LIST_LOCK;
 
 		LIST_FOREACH(spare_stack, &_mstackq, qe) {
 			if (spare_stack->stacksize == stack_size &&
@@ -180,8 +177,7 @@
 		}
 
 		/* Unlock the garbage collector mutex. */
-		if (pthread_mutex_unlock(&_gc_mutex) != 0)
-			PANIC("Cannot unlock gc mutex");
+		DEAD_LIST_UNLOCK;
 	}
 
 	/* Check if a stack was not allocated from a stack cache: */
@@ -212,7 +208,7 @@
 	return (stack);
 }
 
-/* This function must be called with _gc_mutex held. */
+/* This function must be called with the 'dead thread list' lock held. */
 void
 _thread_stack_free(void *stack, size_t stacksize, size_t guardsize)
 {

==== //depot/projects/ia64/release/Makefile.inc.docports#10 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/release/Makefile.inc.docports,v 1.17 2003/04/26 07:31:43 murray Exp $
+# $FreeBSD: src/release/Makefile.inc.docports,v 1.18 2003/05/25 03:41:41 kuriyama Exp $
 #
 # List of (dependent) ports that are minimally required to be
 # checked out from CVS in order to get ${DOCPORTS} built and
@@ -66,7 +66,8 @@
 MINIMALDOCPORTS+=	ports/textproc/sed_inplace
 .endif
 .if ${MACHINE_ARCH} != "i386"
-MINIMALDOCPORTS+=	ports/textproc/openjade
+MINIMALDOCPORTS+=	ports/textproc/openjade \
+			ports/textproc/opensp
 .else
 MINIMALDOCPORTS+=	ports/textproc/jade
 .endif

==== //depot/projects/ia64/sys/dev/fxp/if_fxp.c#32 (text+ko) ====

@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/fxp/if_fxp.c,v 1.179 2003/05/16 01:13:16 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/fxp/if_fxp.c,v 1.180 2003/05/25 05:04:26 truckman Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -383,7 +383,7 @@
 	u_int32_t val;
 	u_int16_t data, myea[ETHER_ADDR_LEN / 2];
 	int i, rid, m1, m2, prefer_iomap, maxtxseg;
-	int s;
+	int s, ipcbxmit_disable;
 
 	sc->dev = dev;
 	callout_handle_init(&sc->stat_ch);
@@ -582,9 +582,31 @@
 	 * and later chips. Note: we need extended TXCB support
 	 * too, but that's already enabled by the code above.
 	 * Be careful to do this only on the right devices.
+	 *
+	 * At least some 82550 cards probed as "chip=0x12298086 rev=0x0d"
+	 * truncate packets that end with an mbuf containing 1 to 3 bytes
+	 * when used with this feature enabled in the previous version of the
+	 * driver.  This problem appears to be fixed now that the driver
+	 * always sets the hardware parse bit in the IPCB structure, which
+	 * the "Intel 8255x 10/100 Mbps Ethernet Controller Family Open
+	 * Source Software Developer Manual" says is necessary in the
+	 * cases where packet truncation was observed.
+	 *
+	 * The device hint "hint.fxp.UNIT_NUMBER.ipcbxmit_disable"
+	 * allows this feature to be disabled at boot time.
+	 *
+	 * If fxp is not compiled into the kernel, this feature may also
+	 * be disabled at run time:
+	 *    # kldunload fxp
+	 *    # kenv hint.fxp.0.ipcbxmit_disable=1
+	 *    # kldload fxp
 	 */
 
-	if (sc->revision == FXP_REV_82550 || sc->revision == FXP_REV_82550_C) {
+	if (resource_int_value("fxp", device_get_unit(dev), "ipcbxmit_disable",
+	    &ipcbxmit_disable) != 0)
+		ipcbxmit_disable = 0;
+	if (ipcbxmit_disable == 0 && (sc->revision == FXP_REV_82550 ||
+	    sc->revision == FXP_REV_82550_C)) {
 		sc->rfa_size = sizeof (struct fxp_rfa);
 		sc->tx_cmd = FXP_CB_COMMAND_IPCBXMIT;
 		sc->flags |= FXP_FLAG_EXT_RFA;
@@ -1277,6 +1299,23 @@
 		txp = sc->fxp_desc.tx_last->tx_next;
 
 		/*
+		 * A note in Appendix B of the Intel 8255x 10/100 Mbps
+		 * Ethernet Controller Family Open Source Software
+		 * Developer Manual says:
+		 *   Using software parsing is only allowed with legal
+		 *   TCP/IP or UDP/IP packets.
+		 *   ...
+		 *   For all other datagrams, hardware parsing must
+		 *   be used.
+		 * Software parsing appears to truncate ICMP and
+		 * fragmented UDP packets that contain one to three
+		 * bytes in the second (and final) mbuf of the packet.
+		 */
+		if (sc->flags & FXP_FLAG_EXT_RFA)
+			txp->tx_cb->ipcb_ip_activation_high =
+			    FXP_IPCB_HARDWAREPARSING_ENABLE;
+
+		/*
 		 * Deal with TCP/IP checksum offload. Note that
 		 * in order for TCP checksum offload to work,
 		 * the pseudo header checksum must have already
@@ -1287,8 +1326,6 @@
 
 		if (mb_head->m_pkthdr.csum_flags) {
 			if (mb_head->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
-				txp->tx_cb->ipcb_ip_activation_high =
-				    FXP_IPCB_HARDWAREPARSING_ENABLE;
 				txp->tx_cb->ipcb_ip_schedule =
 				    FXP_IPCB_TCPUDP_CHECKSUM_ENABLE;
 				if (mb_head->m_pkthdr.csum_flags & CSUM_TCP)

==== //depot/projects/ia64/sys/geom/geom_disk.c#34 (text+ko) ====

@@ -32,7 +32,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/geom/geom_disk.c,v 1.71 2003/05/21 18:52:29 phk Exp $
+ * $FreeBSD: src/sys/geom/geom_disk.c,v 1.72 2003/05/25 16:57:10 phk Exp $
  */
 
 #include "opt_geom.h"
@@ -295,12 +295,14 @@
 }
 
 static void
-g_disk_create(void *arg, int flag __unused)
+g_disk_create(void *arg, int flag)
 {
 	struct g_geom *gp;
 	struct g_provider *pp;
 	struct disk *dp;
 
+	if (flag == EV_CANCEL)
+		return;
 	g_topology_assert();
 	dp = arg;
 	gp = g_new_geomf(&g_disk_class, "%s%d", dp->d_name, dp->d_unit);

==== //depot/projects/ia64/sys/ia64/ia64/trap.c#52 (text+ko) ====

@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/ia64/ia64/trap.c,v 1.77 2003/05/24 21:16:19 marcel Exp $ */
+/* $FreeBSD: src/sys/ia64/ia64/trap.c,v 1.78 2003/05/25 01:01:28 marcel Exp $ */
 /* From: src/sys/alpha/alpha/trap.c,v 1.33 */
 /* $NetBSD: trap.c,v 1.31 1998/03/26 02:21:46 thorpej Exp $ */
 
@@ -346,8 +346,7 @@
 	user = ((framep->tf_special.iip >> 61) < 5) ? 1 : 0;
 
 	/* Short-circuit break instruction based system calls. */
-	if (vector == IA64_VEC_BREAK && user &&
-	    framep->tf_special.ifa == 0x100000) {
+	if (vector == IA64_VEC_BREAK && framep->tf_special.ifa == 0x100000) {
 		break_syscall(framep);
 		return;
 	}

==== //depot/projects/ia64/sys/kern/kern_alq.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/sys/kern/kern_alq.c,v 1.5 2003/02/19 05:47:25 imp Exp $
+ * $FreeBSD: src/sys/kern/kern_alq.c,v 1.6 2003/05/25 08:48:42 jeff Exp $
  *
  */
 
@@ -428,6 +428,8 @@
 		aln = ale->ae_next;

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200305252027.h4PKRH6E007869>