Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Jun 1999 13:44:36 -0400
From:      Richard Cownie <tich@ma.ikos.com>
To:        Kevin Van maren <vanmaren@cs.utah.edu>, freebsd-smp@FreeBSD.ORG
Subject:   Re: high-efficiency SMP locks - submission for review
Message-ID:  <99062914233100.20670@par28.ma.ikos.com>
References:  <199906291705.LAA20627@zane.cs.utah.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 29 Jun 1999, Kevin Van maren wrote:
> On the x86, you do need to lock the bus to guarantee operations
> are atomic, with the exception of xchg (but not the variants),
> which is guaranteed to be atomic.  They also must be naturally-aligned.

No, you can have a non-aligned locked access - there's a bunch of
complex and ugly stuff ("split locks", the SPLCK# bus signal) in
the P6 bus protocol to support this. But don't do it if you can
possibly avoid it - it's inefficient, and since it exercises arcane
features of the hardware, it could be buggy.  

It's also a little inaccurate to talk of "locking the bus" for these
instructions.  If the memory region is cacheable, the atomic access
is implemented by locking the line in the cache until the read-modify-write
is completed - this doesn't require any locked transactions on the P6 bus.
So in general it doesn't have much/any performance penalty (try timing
it if you doubt this).

In general, the hardware implementation is now so complex that you shouldn't
think about it too much; the instructions with a LOCK prefix (or the
XCHG instruction) will give you an atomic read-modify-write, other
instructions won't necessarily be atomic.  Note in particular that
CMPXCHG is not atomic, you need LOCK CMPXCHG - I wasted a couple of weeks
with that bug in my own code.  A non-atomic CMPXCHG seems like a particularly
useless instruction ...  LOCK CMPXCHG is great though, you can use it to
synthesize an arbitrarily complex atomic update like this:

retry:
  oldval = *lockp; // normal read of lock variable
  newval = SomeFunc(oldval);  // arbitrarily complex function
  LOCK CMPXCHG     // if (*lockp == oldval) *lockp = newval; else goto retry;
 
Also the claim that x86 takes interrupts only at instruction boundaries is
only half-true - I believe you can take an interrupt in the middle of a 
string instruction, it will leave the registers in a suitable state so that
restarting the string instruction will resume where it left off.  
For the OS, the big question is whether you have to look at any special
state or do any special fixup to get back to the correct state when resuming
after an interrupt, and for the x86 the answer is no.  I've never used the
68000, but I believe it's screwed up in this respect, hence early 68000
workstations had 2 cpu's, one to run programs and the other just to handle
the page faults, because you couldn't safely resume after the fault ...

Richard Cownie (tich@ma.ikos.com)


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-smp" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?99062914233100.20670>