DragonFly submit List (threaded) for 2008-02
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
Re: lockmgr_sleep() (was Re: ssleep() (was Re: mention msleep() in porting_drivers.txt))
On Saturday 26 January 2008, Aggelos Economopoulos wrote:
> On Wednesday 16 January 2008, Aggelos Economopoulos wrote:
> > On Wednesday 16 January 2008, Matthew Dillon wrote:
> > > lockmgr_sleep(ident, lock, slpflags, wmesg, timeo)
> > >
> > > lockmgr_sleep can also figure out what kind of lock is held internally
> > > and deal with it, or it can just assume an exclusive lock. Either way
> > > lkflags do not have to be passed to it.
> >
> > Assuming an exclusive lock is not intuitive IMO and differs from the FreeBSD
> > semantics (even though it matches our msleep()/spin_sleep()). What do you
> > think of the lockmgr change suggested in another mail in this thread?
> >
> > >
> > > :If we're going to rename msleep() to spin_sleep() anyway, I suggest changing
> > > :the prototype to
> > > :
> > > :spin_sleep(void *ident, int flags, const char *wmesg, int timo,
> > > : struct spinlock *spin)
> > >
> > > We want all the *sleep() procedures to use a similar prototype,
> > > and in this case being compatible with our own history as well
> > > as FreeBSD's will reduce confusion to a minimum. That means putting
> > > the lock as the second argument.
> > >
> > > spin_sleep(ident, spin, slpflags, wmesg, timeo)
> >
> > Nobody can disagree with the "compatible" part, but for a whatever_sleep()
> > that does a "drop, tsleep() and reacquire whatever lock" it seems more
> > natural to require the tsleep() args followed by the whatever args. It may
> > be unlikely, but imagine having to add another flag. Would you put it after
> > "spin" seperating the tsleep() args further?
> >
> > Also, I don't think FreeBSD compatibility is an issue, unless the two choices
> > are otherwise on par.
>
> So what's the verdict? Veto still on? Need to know in order to submit a patch :)
Ping. It would be nice if the msleep() deprecation made it in the release. Can
you take a five minute break to clarify? The patch in question follows.
Thanks,
Aggelos
Index: sys/kern/kern_lock.c
===================================================================
retrieving revision 1.27
diff -u -p -r1.27 kern_lock.c
--- sys/kern/kern_lock.c
+++ sys/kern/kern_lock.c
@@ -537,11 +537,11 @@ lockuninit(struct lock *l)
* Determine the status of a lock.
*/
int
-lockstatus(struct lock *lkp, struct thread *td)
+lockstatus_owned(struct lock *lkp, struct thread *td)
{
int lock_type = 0;
- spin_lock_wr(&lkp->lk_spinlock);
+ /* XXX: assert owned */
if (lkp->lk_exclusivecount != 0) {
if (td == NULL || lkp->lk_lockholder == td)
lock_type = LK_EXCLUSIVE;
@@ -550,10 +550,19 @@ lockstatus(struct lock *lkp, struct thre
} else if (lkp->lk_sharecount != 0) {
lock_type = LK_SHARED;
}
- spin_unlock_wr(&lkp->lk_spinlock);
return (lock_type);
}
+int lockstatus(struct lock *lkp, struct thread *td)
+{
+ int lock_type;
+
+ spin_lock_wr(&lkp->lk_spinlock);
+ lock_type = lockstatus_owned(lkp, td);
+ spin_unlock_wr(&lkp->lk_spinlock);
+ return lock_type;
+}
+
/*
* Determine the number of holders of a lock.
*
Index: sys/kern/kern_synch.c
===================================================================
retrieving revision 1.88
diff -u -p -r1.88 kern_synch.c
--- sys/kern/kern_synch.c
+++ sys/kern/kern_synch.c
@@ -587,6 +587,29 @@ tsleep_interlock(void *ident)
}
/*
+ * Atomically drop a lockmgr lock and go to sleep. The lock is reacquired
+ * before returning from this function. Passes on the value returned by
+ * tsleep().
+ */
+int
+lock_sleep(void *ident, int flags, const char *wmesg, int timo,
+ struct lock *lk)
+{
+ int err, mode;
+
+ mode = lockstatus_owned(lk, curthread);
+ KKASSERT((mode == LK_EXCLUSIVE) || (mode == LK_SHARED));
+
+ crit_enter();
+ tsleep_interlock(ident);
+ lockmgr(lk, LK_RELEASE);
+ err = tsleep(ident, flags, wmesg, timo);
+ crit_exit();
+ lockmgr(lk, mode);
+ return err;
+}
+
+/*
* Interlocked spinlock sleep. An exclusively held spinlock must
* be passed to msleep(). The function will atomically release the
* spinlock and tsleep on the ident, then reacquire the spinlock and
@@ -596,8 +619,8 @@ tsleep_interlock(void *ident)
* heavily.
*/
int
-msleep(void *ident, struct spinlock *spin, int flags,
- const char *wmesg, int timo)
+spin_sleep(void *ident, int flags, const char *wmesg, int timo,
+ struct spinlock *spin)
{
globaldata_t gd = mycpu;
int error;
Index: sys/sys/cdefs.h
===================================================================
retrieving revision 1.19
diff -u -p -r1.19 cdefs.h
--- sys/sys/cdefs.h
+++ sys/sys/cdefs.h
@@ -174,8 +174,10 @@
#if __GNUC_PREREQ__(3, 1)
#define __always_inline __attribute__((__always_inline__))
+#define __deprecated __attribute__((deprecated))
#else
#define __always_inline
+#define __deprecated
#endif
#if __GNUC_PREREQ__(3, 3)
Index: sys/sys/lock.h
===================================================================
retrieving revision 1.19
diff -u -p -r1.19 lock.h
--- sys/sys/lock.h
+++ sys/sys/lock.h
@@ -205,6 +205,7 @@ void lockmgr_setexclusive_interlocked(st
void lockmgr_clrexclusive_interlocked(struct lock *);
void lockmgr_kernproc (struct lock *);
void lockmgr_printinfo (struct lock *);
+int lockstatus_owned (struct lock *, struct thread *);
int lockstatus (struct lock *, struct thread *);
int lockcount (struct lock *);
int lockcountnb (struct lock *);
Index: sys/sys/systm.h
===================================================================
retrieving revision 1.77
diff -u -p -r1.77 systm.h
--- sys/sys/systm.h
+++ sys/sys/systm.h
@@ -324,7 +324,19 @@ extern watchdog_tickle_fn wdog_tickler;
* less often.
*/
int tsleep (void *, int, const char *, int);
-int msleep (void *, struct spinlock *, int, const char *, int);
+int spin_sleep(void *, int, const char *, int, struct spinlock *);
+int lock_sleep(void *, int, const char *, int, struct lock *);
+/*
+ * msleep() has been renamed to spin_sleep() and is scheduled for removal in
+ * the next (2.2) release. XXX remove msleep().
+ */
+static inline __deprecated int
+msleep(void *ident, struct spinlock *spin, int flags,
+ const char *wmesg, int timo)
+{
+ return spin_sleep(ident, flags, wmesg, timo, spin);
+}
+
void tsleep_interlock (void *chan);
int lwkt_sleep (const char *, int);
void tstop (void);
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]