Date: Wed, 28 Jun 2006 04:45:43 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 100185 for review Message-ID: <200606280445.k5S4jhjT042729@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100185 Change 100185 by kmacy@kmacy_storage:sun4v_work_sleepq on 2006/06/28 04:44:46 add support for LK_DRAIN semantics Affected files ... .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_sxu.c#4 edit .. //depot/projects/kmacy_sun4v/src/sys/sys/sxu.h#3 edit Differences ... ==== //depot/projects/kmacy_sun4v/src/sys/kern/kern_sxu.c#4 (text+ko) ==== @@ -110,6 +110,30 @@ lock_destroy(&sx->sxu_object); } + +void +_sxu_drain(struct sxu *sx, struct cv *cv_drain, const char *file, int line) +{ + mtx_lock(sx->sxu_lock); + KASSERT(sx->sxu_drain_cvp == NULL, ("sxu lock already being drained")); + KASSERT(sx->sx->sxu_xholder != curthread ("sxu draining against myself")); + WITNESS_CHECKORDER(&sx->sxu_object, LOP_NEWORDER, file, line); + + sx->sxu_drain_cvp = cv_drain; + cv_wait(cv_drain, sx->sxu_lock); + + + /* Acquire an exclusive lock. */ + sx->sxu_cnt--; + sx->sxu_xholder = curthread; + sx->sxu_drain_cvp = NULL; + + LOCK_LOG_LOCK("SLOCK", &sx->sxu_object, 0, 0, file, line); + WITNESS_LOCK(&sx->sxu_object, 0, file, line); + mtx_unlock(sx->sxu_lock); +} + + int _sxu_slock(struct sxu *sx, int timo, const char *file, int line) { @@ -132,8 +156,8 @@ if (sx->sxu_cnt < 0) lock_profile_waitstart(&waittime); while (sx->sxu_cnt < 0) { + lock_profile_obtain_lock_failed(&sx->sxu_object, &contested); sx->sxu_shrd_wcnt++; - lock_profile_obtain_lock_failed(&sx->sxu_object, &contested); if (timo) error = cv_timedwait(&sx->sxu_shrd_cv, sx->sxu_lock, timo); else @@ -273,11 +297,13 @@ if (sx->sxu_cnt == 0) lock_profile_release_lock(&sx->sxu_object); - if (sx->sxu_excl_wcnt > 0) { - if (sx->sxu_cnt == 0) - cv_signal(&sx->sxu_excl_cv); - } else if (sx->sxu_shrd_wcnt > 0) /* XXX why would shrd_wcnt be > 0 if the holder is shared? */ + + if (sx->sxu_excl_wcnt > 0 && sx->sxu_cnt == 0) + cv_signal(&sx->sxu_excl_cv); + else if (sx->sxu_shrd_wcnt > 0) /* XXX why would shrd_wcnt be > 0 if the holder is shared? */ cv_broadcast(&sx->sxu_shrd_cv); + else if (sx->sxu_drain_cvp && (sx->sx_cnt == 0)) + cv_signal(sx->sxu_drain_cvp); LOCK_LOG_LOCK("SUNLOCK", &sx->sxu_object, 0, 0, file, line); @@ -306,9 +332,10 @@ cv_broadcast(&sx->sxu_shrd_cv); else if (sx->sxu_excl_wcnt > 0) cv_signal(&sx->sxu_excl_cv); + else if (sx->sxu_drain_cvp) + cv_signal(sx->sxu_drain_cvp); LOCK_LOG_LOCK("XUNLOCK", &sx->sxu_object, 0, 0, file, line); - mtx_unlock(sx->sxu_lock); } ==== //depot/projects/kmacy_sun4v/src/sys/sys/sxu.h#3 (text+ko) ==== @@ -43,7 +43,7 @@ struct cv sxu_excl_cv; /* xlock waiters. */ int sxu_excl_wcnt; /* Number of xlock waiters. */ struct thread *sxu_xholder; /* Thread presently holding xlock. */ - struct cv sxu_drain_cv; /* drain waiter. */ + struct cv *sxu_drain_cvp; /* pointer to drain waiter (if any). */ }; #ifdef _KERNEL @@ -58,6 +58,8 @@ void _sxu_xunlock(struct sxu *sx, const char *file, int line); int _sxu_try_upgrade(struct sxu *sx, const char *file, int line); void _sxu_downgrade(struct sxu *sx, const char *file, int line); +void _sxu_drain(struct sxu *sx, struct cv *cv_drain, const char *file, int line); + #ifdef INVARIANT_SUPPORT void _sxu_assert(struct sxu *sxu, int what, const char *file, int line); #endif @@ -87,6 +89,8 @@ #define sxu_xunlock(sx) _sxu_xunlock((sx), LOCK_FILE, LOCK_LINE) #define sxu_try_upgrade(sx) _sxu_try_upgrade((sx), LOCK_FILE, LOCK_LINE) #define sxu_downgrade(sx) _sxu_downgrade((sx), LOCK_FILE, LOCK_LINE) +#define sxu_drain(sx, cv) _sxu_drain((sx), (cv), LOCK_FILE, LOCK_LINE) + #define sxu_unlock(sx) do { \ if ((sx)->sx_cnt < 0) \ sxu_xunlock(sx); \
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606280445.k5S4jhjT042729>