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>