Date: 31 Oct 1997 00:01:07 +1100 From: Julian Assange <proff@iq.org> To: freebsd-hackers@freebsd.org Subject: Re: kernel spinlocks, splbio(), MUTEX etc Message-ID: <wxiuufe770.fsf@profane.iq.org> In-Reply-To: Mike Smith's message of Thu, 30 Oct 1997 22:11:24 %2B1030 References: <199710301141.WAA00594@word.smith.net.au>
index | next in thread | previous in thread | raw e-mail
Mike Smith <mike@smith.net.au> writes:
> >
> > I have a possible access contention between two peices of code,
> > one hanging off a timeout() interrupt and the other called via
> > the VFS sub-system. I don't want to lock the object they are
> > accessing by using splbio() as both bits of code use around
> > 32k instructions.
> >
> > ideas?
>
> Can you defer one or both of the fragments? The only real alternatives
> are to redesign your code to reduce the size of the critical region(s),
> and that's not always easy...
>
> mike
I ended up using a combination of splbio(), tsleep(), wakeup() and my
own locking system. maruXORkeys() is the cpu pig that we don't want to
block on. Below is the locking code. I'm a bit dubious of my usage of
volatile here (I want it to apply to what the pointer points to rather
than the pointer itself) I don't want references to maru->mkeyLock to
end up optimized into a register on the first reference, because by
the time we get to the second another thread may have hit the
original in-memory instance.
static void
maruLockKeys(volatile munit *maru)
{
int s;
re:
s = splbio();
if (maru->m_keyLock == kl_timer)
{
splx(s);
tsleep(maru, PRIBIO, "maru", 0);
goto re;
}
maru->m_keyLockCount++;
if (maru->m_keyLock != kl_strategy) /* maybe running concurrently */
{
maru->m_keyLock = kl_strategy;
splx(s);
if (maru->m_keyState == ks_cipher)
maruXORkeys(maru);
}
else
splx(s);
}
static void
maruUnlockKeys(volatile munit *maru)
{
int s;
s = splbio();
if (--maru->m_keyLockCount == 0)
maru->m_keyLock = kl_none;
splx(s);
}
static void
maruKeyTimer(void *m)
{
volatile munit *maru = m; /* right semantics for volatile ?*/
maruInstance *i;
int s;
IFOPT(MARU_FOLLOW)
printf ("maruXORkey(%p)\n", m);
if (!munits[maru->m_unit])
return;
i = maru->m_instance;
if (!i)
return;
s = splbio(); /* where is MUTEX() when you need it */
switch (maru->m_keyLock)
{
case kl_none:
break;
case kl_timer:
case kl_strategy:
splx(s);
goto end;
default:
panic("maruKeyTimer() default: wtf are we doing here?");
}
maru->m_keyLock = kl_timer;
maru->m_keyLockCount++;
splx(s);
maruXORkeys(maru);
s = splbio();
if (maru->m_keyLock == kl_strategy)
{
splx(s);
wakeup(maru);
}
else
splx(s);
end:
timeout(maruKeyTimer, maru, ((maru->m_xorfreq*hz/1000)>0)? (maru->m_xorfreq*hz)/1000: 1);
}
--
Prof. Julian Assange |"Don't worry about people stealing your ideas. If your
| Ideas are any good, you'll have to ram them down
proff@iq.org | people's throats."
proff@gnu.ai.mit.edu | -- Howard Aiken
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?wxiuufe770.fsf>
