From owner-freebsd-threads@FreeBSD.ORG Mon Jul 19 17:53:10 2004 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3C61516A4CE for ; Mon, 19 Jul 2004 17:53:10 +0000 (GMT) Received: from mail1.speakeasy.net (mail1.speakeasy.net [216.254.0.201]) by mx1.FreeBSD.org (Postfix) with ESMTP id B4E1D43D60 for ; Mon, 19 Jul 2004 17:53:07 +0000 (GMT) (envelope-from jhb@FreeBSD.org) Received: (qmail 16466 invoked from network); 19 Jul 2004 17:53:07 -0000 Received: from dsl027-160-063.atl1.dsl.speakeasy.net (HELO server.baldwin.cx) ([216.27.160.63]) (envelope-sender ) encrypted SMTP for ; 19 Jul 2004 17:53:06 -0000 Received: from 10.50.41.229 (gw1.twc.weather.com [216.133.140.1]) (authenticated bits=0) by server.baldwin.cx (8.12.11/8.12.11) with ESMTP id i6JHr0dI013757 for ; Mon, 19 Jul 2004 13:53:01 -0400 (EDT) (envelope-from jhb@FreeBSD.org) From: John Baldwin To: threads@FreeBSD.org Date: Mon, 19 Jul 2004 13:52:50 -0400 User-Agent: KMail/1.6 MIME-Version: 1.0 Content-Disposition: inline Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Message-Id: <200407191352.50465.jhb@FreeBSD.org> X-Spam-Checker-Version: SpamAssassin 2.63 (2004-01-11) on server.baldwin.cx Subject: Patch to fix cv_wait return values X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Jul 2004 17:53:10 -0000 I have a patch to try to sync up the semantics of the return values of the cv_wait() functions with msleep(). The patch is at http://people.FreeBSD.org/~jhb/patches/cv_retval.patch and is inline below. If people could test it ok and verify that the patch is correct I'd appreciate it. Thanks. --- //depot/projects/smpng/sys/kern/kern_condvar.c 2004/06/29 02:54:29 +++ //depot/user/jhb/lock/kern/kern_condvar.c 2004/07/09 18:16:47 @@ -170,12 +170,28 @@ * procs or panic below, in case this is the idle process and * already asleep. */ - return 0; + return (0); } sq = sleepq_lookup(cvp); - /* XXX: Missing the threading checks from msleep! */ + /* + * Don't bother sleeping if we are exiting and not the exiting + * thread or if our thread is marked as interrupted. + */ + mtx_lock_spin(&sched_lock); + if (p->p_flag & P_SA || p->p_numthreads > 1) { + if ((p->p_flag & P_WEXIT) && p->p_singlethread != td) + rval = EINTR; + else if (td->td_flags & TDF_INTERRUPT) + rval = td->td_intrval; + if (rval != 0) { + mtx_unlock_spin(&sched_lock); + sleepq_release(cvp); + return (rval); + } + } + mtx_unlock_spin(&sched_lock); cvp->cv_waiters++; DROP_GIANT(); @@ -183,20 +199,16 @@ sleepq_add(sq, cvp, mp, cvp->cv_description, SLEEPQ_CONDVAR); sig = sleepq_catch_signals(cvp); - /* - * XXX: Missing magic return value handling for no signal - * caught but thread woken up during check. - */ - rval = sleepq_wait_sig(cvp); + if (sig == 0 && !TD_ON_SLEEPQ(td)) { + mtx_lock_spin(&sched_lock); + td->td_flags &= ~TDF_SINTR; + mtx_unlock_spin(&sched_lock); + sleepq_wait(cvp); + } else + rval = sleepq_wait_sig(cvp); if (rval == 0) rval = sleepq_calc_signal_retval(sig); - /* XXX: Part of missing threading checks? */ - PROC_LOCK(p); - if (p->p_flag & P_WEXIT) - rval = EINTR; - PROC_UNLOCK(p); - #ifdef KTRACE if (KTRPOINT(td, KTR_CSW)) ktrcsw(0, 0); @@ -303,6 +315,24 @@ sq = sleepq_lookup(cvp); + /* + * Don't bother sleeping if we are exiting and not the exiting + * thread or if our thread is marked as interrupted. + */ + mtx_lock_spin(&sched_lock); + if (p->p_flag & P_SA || p->p_numthreads > 1) { + if ((p->p_flag & P_WEXIT) && p->p_singlethread != td) + rval = EINTR; + else if (td->td_flags & TDF_INTERRUPT) + rval = td->td_intrval; + if (rval != 0) { + mtx_unlock_spin(&sched_lock); + sleepq_release(cvp); + return (rval); + } + } + mtx_unlock_spin(&sched_lock); + cvp->cv_waiters++; DROP_GIANT(); mtx_unlock(mp); @@ -310,20 +340,16 @@ sleepq_add(sq, cvp, mp, cvp->cv_description, SLEEPQ_CONDVAR); sleepq_set_timeout(cvp, timo); sig = sleepq_catch_signals(cvp); - /* - * XXX: Missing magic return value handling for no signal - * caught but thread woken up during check. - */ - rval = sleepq_timedwait_sig(cvp, sig != 0); + if (sig == 0 && !TD_ON_SLEEPQ(td)) { + mtx_lock_spin(&sched_lock); + td->td_flags &= ~TDF_SINTR; + mtx_unlock_spin(&sched_lock); + rval = sleepq_timedwait(cvp); + } else + rval = sleepq_timedwait_sig(cvp, sig != 0); if (rval == 0) rval = sleepq_calc_signal_retval(sig); - /* XXX: Part of missing threading checks? */ - PROC_LOCK(p); - if (p->p_flag & P_WEXIT) - rval = EINTR; - PROC_UNLOCK(p); - #ifdef KTRACE if (KTRPOINT(td, KTR_CSW)) ktrcsw(0, 0); -- John Baldwin <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve" = http://www.FreeBSD.org