Subject: Re: CVS commit: src
To: Jason Thorpe <thorpej@wasabisystems.com>
From: Juergen Hannken-Illjes <hannken@netbsd.org>
List: tech-kern
Date: 06/22/2004 12:21:38
On Mon, Jun 21, 2004 at 04:12:24PM -0700, Jason Thorpe wrote:
>
> On Jun 21, 2004, at 12:36 PM, Bill Studenmund wrote:
>
> >I'm not fully sure why, but I'm more comfortable with this complexity
> >in
> >the lock manager.
>
> I'm not. The more overhead the locking primitives we have are (and
> lockmgr is pretty heavy-weight), we can pretty much never hope to have
> a scalable MP implementation.
>
> Put complexity in the things that require it, don't add complexity to
> places where it is seldom needed.
Is this one possible? Should add no overhead to the lock manager.
--
Jürgen Hannken-Illjes - hannken@netbsd.org
void
transfer_sleepers(const void *from_ident, const void *to_ident)
{
struct slpque *qp_from, *qp_to;
struct lwp *l, **q;
int s;
SCHED_ASSERT_UNLOCKED();
SCHED_LOCK(s);
qp_from = SLPQUE(from_ident);
for (q = &qp_from->sq_head; (l = *q) != NULL; ) {
if (l->l_wchan == from_ident) {
/* dequeue from old queue */
*q = l->l_forw;
if (qp_from->sq_tailp == &l->l_forw)
qp_from->sq_tailp = q;
/* change wchan and enqueue */
l->l_wchan = to_ident;
qp_to = SLPQUE(to_ident);
if (qp_to->sq_head == 0)
qp_to->sq_head = l;
else
*qp_to->sq_tailp = l;
*(qp_to->sq_tailp = &l->l_forw) = 0;
} else
q = &l->l_forw;
}
SCHED_UNLOCK(s);
}
Then transferlockers() could be as simple as
void
transferlockers(struct lock *from, struct lock *to)
{
if (from->lk_waitcount == 0)
return;
if (from->lk_flags & LK_WAITDRAIN)
transfer_sleepers((void *)&from->lk_flags,
(void *)&to->lk_flags);
else
transfer_sleepers((void *)from, (void *)to);
}