svn commit: r214823 - in user/davidxu/libthr/sys: kern sys
David Xu
davidxu at FreeBSD.org
Fri Nov 5 06:35:11 UTC 2010
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
More information about the svn-src-user
mailing list