From owner-svn-src-user@FreeBSD.ORG Fri Nov 5 06:35:11 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5080E1065670; Fri, 5 Nov 2010 06:35:11 +0000 (UTC) (envelope-from davidxu@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3275B8FC14; Fri, 5 Nov 2010 06:35:11 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oA56ZBJp087044; Fri, 5 Nov 2010 06:35:11 GMT (envelope-from davidxu@svn.freebsd.org) Received: (from davidxu@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oA56ZBKW087041; Fri, 5 Nov 2010 06:35:11 GMT (envelope-from davidxu@svn.freebsd.org) Message-Id: <201011050635.oA56ZBKW087041@svn.freebsd.org> From: David Xu Date: Fri, 5 Nov 2010 06:35:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r214823 - in user/davidxu/libthr/sys: kern sys X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Nov 2010 06:35:11 -0000 Author: davidxu Date: Fri Nov 5 06:35:10 2010 New Revision: 214823 URL: http://svn.freebsd.org/changeset/base/214823 Log: Introduce a bit flag UMUTEX_SIMPLE for umutex, so that it does not use thread id to lock and unlock. this is necessary, because a link entry can not be embedded into mutex which will be shared between processes, because if other process do incorrect think, it corrupt your link list. But to let unlocking after fork() to work, we either should link it into list to remember it or use a id which can be atomatically duplicated. We use pthread pointer, the bit UMUTEX_SIMPLE_OWNER indicates if the mutex is locked or unlocked. Modified: user/davidxu/libthr/sys/kern/kern_umtx.c user/davidxu/libthr/sys/sys/umtx.h Modified: user/davidxu/libthr/sys/kern/kern_umtx.c ============================================================================== --- user/davidxu/libthr/sys/kern/kern_umtx.c Fri Nov 5 05:11:54 2010 (r214822) +++ user/davidxu/libthr/sys/kern/kern_umtx.c Fri Nov 5 06:35:10 2010 (r214823) @@ -228,17 +228,26 @@ static uma_zone_t umtx_pi_zone; static struct umtxq_chain umtxq_chains[2][UMTX_CHAINS]; static MALLOC_DEFINE(M_UMTX, "umtx", "UMTX queue memory"); static int umtx_pi_allocated; +#ifdef SMP +static int umtx_cvsig_migrate = 0; +#else +static int umtx_cvsig_migrate = 1; +#endif SYSCTL_NODE(_debug, OID_AUTO, umtx, CTLFLAG_RW, 0, "umtx debug"); SYSCTL_INT(_debug_umtx, OID_AUTO, umtx_pi_allocated, CTLFLAG_RD, &umtx_pi_allocated, 0, "Allocated umtx_pi"); +SYSCTL_INT(_debug_umtx, OID_AUTO, umtx_cvsig_migrate, CTLFLAG_RW, + &umtx_cvsig_migrate, 0, "cvsig migrate"); + #define UMTX_STATE #ifdef UMTX_STATE static int umtx_cv_broadcast_migrate; static int umtx_cv_signal_migrate; static int umtx_cv_insert_failure; static int umtx_cv_unlock_failure; +static int umtx_timedlock_count; SYSCTL_INT(_debug_umtx, OID_AUTO, umtx_cv_broadcast_migrate, CTLFLAG_RD, &umtx_cv_broadcast_migrate, 0, "cv_broadcast thread migrated"); SYSCTL_INT(_debug_umtx, OID_AUTO, umtx_cv_signal_migrate, CTLFLAG_RD, @@ -247,6 +256,8 @@ SYSCTL_INT(_debug_umtx, OID_AUTO, umtx_c &umtx_cv_insert_failure, 0, "cv_wait failure"); SYSCTL_INT(_debug_umtx, OID_AUTO, umtx_cv_unlock_failure, CTLFLAG_RD, &umtx_cv_unlock_failure, 0, "cv_wait unlock mutex failure"); +SYSCTL_INT(_debug_umtx, OID_AUTO, umtx_timedlock_count, CTLFLAG_RD, + &umtx_timedlock_count, 0, "umutex timedlock count"); #define UMTX_STATE_INC(var) umtx_##var++ #define UMTX_STATE_ADD(var, val) (umtx_##var += (val)) #else @@ -1202,7 +1213,10 @@ _do_lock_normal(struct thread *td, struc uint32_t owner, old, id; int error = 0; - id = td->td_tid; + if (flags & UMUTEX_SIMPLE) + id = UMUTEX_SIMPLE_OWNER; + else + id = td->td_tid; uq = td->td_umtxq; /* @@ -1321,7 +1335,10 @@ do_unlock_normal(struct thread *td, stru int error; int count; - id = td->td_tid; + if (flags & UMUTEX_SIMPLE) + id = UMUTEX_SIMPLE_OWNER; + else + id = td->td_tid; /* * Make sure we own this mtx. */ @@ -2066,7 +2083,10 @@ _do_lock_pp(struct thread *td, struct um uint32_t owner, id; int error, pri, old_inherited_pri, su; - id = td->td_tid; + if (flags & UMUTEX_SIMPLE) + id = UMUTEX_SIMPLE_OWNER; + else + id = td->td_tid; uq = td->td_umtxq; if ((error = umtx_key_get(m, TYPE_PP_UMUTEX, GET_SHARE(flags), &uq->uq_key)) != 0) @@ -2196,7 +2216,10 @@ do_unlock_pp(struct thread *td, struct u uint32_t rceiling; int error, pri, new_inherited_pri, su; - id = td->td_tid; + if (flags & UMUTEX_SIMPLE) + id = UMUTEX_SIMPLE_OWNER; + else + id = td->td_tid; uq = td->td_umtxq; su = (priv_check(td, PRIV_SCHED_RTPRIO) == 0); @@ -2284,7 +2307,10 @@ do_set_ceiling(struct thread *td, struct return (EINVAL); if (ceiling > RTP_PRIO_MAX) return (EINVAL); - id = td->td_tid; + if (flags & UMUTEX_SIMPLE) + id = UMUTEX_SIMPLE_OWNER; + else + id = td->td_tid; uq = td->td_umtxq; if ((error = umtx_key_get(m, TYPE_PP_UMUTEX, GET_SHARE(flags), &uq->uq_key)) != 0) @@ -2387,6 +2413,9 @@ do_lock_umutex(struct thread *td, struct error = ERESTART; } else { const clockid_t clockid = CLOCK_REALTIME; + + UMTX_STATE_INC(timedlock_count); + if ((wflags & UMUTEX_ABSTIME) == 0) { kern_clock_gettime(td, clockid, &ets); timespecadd(&ets, timeout); @@ -2720,7 +2749,7 @@ do_cv_signal(struct thread *td, struct u struct umtxq_chain *uc, *ucm; struct umtx_q *uq; struct umtx_key key; - int error, len; + int error, len, migrate; uint32_t flags, owner; flags = fuword32(&cv->c_flags); @@ -2744,8 +2773,17 @@ do_cv_signal(struct thread *td, struct u } len = uh->length; - - if (uh->binding) { + switch(umtx_cvsig_migrate) { + case 1: /* auto */ + migrate = (mp_ncpus == 1); + break; + case 0: /* disable */ + migrate = 0; + break; + default: /* always */ + migrate = 1; + } + if (migrate && uh->binding) { struct umutex *bind_mutex = uh->bind_mutex; struct umtx_key mkey; int oldlen; Modified: user/davidxu/libthr/sys/sys/umtx.h ============================================================================== --- user/davidxu/libthr/sys/sys/umtx.h Fri Nov 5 05:11:54 2010 (r214822) +++ user/davidxu/libthr/sys/sys/umtx.h Fri Nov 5 06:35:10 2010 (r214823) @@ -40,10 +40,14 @@ #define UMUTEX_UNOWNED 0x0 #define UMUTEX_CONTESTED 0x80000000U +#define UMUTEX_OWNER_MASK 0x7FFFFFFFU #define UMUTEX_ERROR_CHECK 0x0002 /* Error-checking mutex */ #define UMUTEX_PRIO_INHERIT 0x0004 /* Priority inherited mutex */ #define UMUTEX_PRIO_PROTECT 0x0008 /* Priority protect mutex */ +#define UMUTEX_SIMPLE 0x0010 /* Use simple lock id. */ + +#define UMUTEX_SIMPLE_OWNER 1 /* The simple mutex's lock bit. */ /* urwlock flags */ #define URWLOCK_PREFER_READER 0x0002