Re: Shared memory not SMP safe to user-mode code.

Jamie Lokier (lkd@tantalophile.demon.co.uk)
Wed, 1 Dec 1999 00:29:52 +0100


Richard B. Johnson wrote a spinlock:
> pars->spin += key;
> if(pars->spin != key)
> {
> pars->spin -= key;

Wrong. This is not safe on UP /or/ SMP because "+=" and "-=" are not
atomic operations in C. `volatile' does not help either.

On all machines, this is possible and leaves the wrong result in pars->spin:

Process 0 Process 1
--------- ---------
reg = pars->spin
reg += key
<pre-emptive task switch>
reg = pars->spin to
reg += key
pars->spin = reg
<pre-emptive task switch>
pars->spin = reg

There are variations involving interrupts and so on.

Now, you can use assembly language to force use of an atomic operation.
In x86 world, "addl $key, ADDRESS" is adequate for UP simply because
interrupts cannot split these single instructions. (On some other
processors, parts of instructions /can/ be interrupted).

It protects against signals handlers, interrupts and other processes.
But on SMP, "addl" is not atomic. You have to use "lock; addl" on SMP.

So you are right that the difference between UP and SMP is visible to
user processes. But, on x86, it is not visible to ordinary C code. C
does not have any atomic operations.

x86 applications using shared memory that want atomic access should
always use "lock" in their asm macros, in case they are run on SMP
machines. The only time this is not necessary is if the only thing
accessing your shared memory is a signal handler in the same process
context, or if you /know/ you will only ever run on a UP box.

-- Jamie

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/