Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 Nov 2010 06:35:11 +0000 (UTC)
From:      David Xu <davidxu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r214823 - in user/davidxu/libthr/sys: kern sys
Message-ID:  <201011050635.oA56ZBKW087041@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



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