Re: Disabling interrupts to protect data



David Brown wrote:
Stefan Reuther wrote:
All this is totally simple when you can use CLI/STI:
void atomic_swap(node** a, node** b, node* c) {
cli(); *a = *b; *b = c; sti();
}

// prepend new node to a list (easier than appending...)
node* list;
node* newNode;
atomic_swap(&newNode->next, &list, newNode);
(some strategically-placed 'volatile' can be appropriate.)

Here you have missed one important point that many people fail to
understand about interrupt disabling (and the related topic of volatile
accesses) - memory barriers. Unless your cli() and sti() macros /
assembly functions specifically include memory barriers, then your
atomic_swap function is not safe.

Yep. The declaration should've been
void atomic_swap(node*volatile* a, node*volatile* b, node* c);
I was just too lazy to figure out where to place the 'volatile's :-)
That, together with cli/sti macros acting as memory barriers (honestly,
cli/sti which are not such barriers are useless) fixes the routine for a
single processor system. Multiprocessor is a little harder.

In the atomic_swap function above, for example, the compiler will
probably see the cli() and sti() as volatile accesses (depending on the
compiler and the definition of these macros). But the code in the
middle does not use volatile accesses - the compiler can therefore
freely move these operations before or after the cli() and sti()
operations.

Actually, our compiler moved the accesses even though I used 'volatile'.
Fortunately the vendor fixed it quickly, but in the meantime I've made
an asm version to fix it forever.


Stefan

.



Relevant Pages

  • Re: MSDN volatile sample
    ... must be specified to get the memory barriers. ... Telling us we have to put volatile keyword to thread sharing data ... Now I strongly suspect whether compiler will generate any wrong code -- ... It seems that volatile will make wrong optimization to prevent thread1 ...
    (microsoft.public.vc.language)
  • Re: Efficient way to synchronize bool variables
    ...  volatile, even with memory barriers, does NOT create ... thread-safe modifications, and will not work. ... Couple that with volatile ... THe compiler is horribly conservative ...
    (microsoft.public.vc.mfc)
  • Re: Share .cpp and .h along projects
    ... larger object can be controlled in a threadsafe manner using a volatile ... pointer and memory barriers. ... The compiler DOES apply those optimizations. ...
    (microsoft.public.vc.language)
  • Re: mutex question
    ... This is not a compiler bug -- this is a code bug. ... use 'volatile' on variables shared between threads. ... Memory barriers, not volatile, are the correct mechanism to force updating of variables between threads. ...
    (microsoft.public.win32.programmer.kernel)
  • Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
    ... re-ordering, the question then becomes one of "with regard to *what* does ... sequence point in between them is pretty clearly a buggy compiler. ... "Volatile accesses" are a side effect, ...
    (Linux-Kernel)