4

now writing complicated class and felt that I use to much CRITICAL_SECTION.

As far as I know there are atomic operations for some types, that are always executed without any hardware or software interrupt.

I want to check if I understand everything correctly.

  • To set or get atomic value we don't need CRITICAL_SECTION because doing that there won't be interrupts.
  • bool is atomic.

So there are my statements, want to ask, if they are correct, also if they are correct, what types variables may be also set or get without CRITICAL_SECTION?

P. S. I'm talking about getting or setting one single value per method, not two, not five, but one.

ST3
  • 8,826
  • 3
  • 68
  • 92
  • 2
    Whether a type can be read/written/manipulated atomically is very much implementation (and there maybe even compiler option) defined. You should mostly rely on `std::atomic` and friends. – PlasmaHH Aug 19 '13 at 13:49
  • 1
    The only functions I would do this with are the Interlocked functions - e.g. `InterlockedIncrement` etc. [See here for details](http://msdn.microsoft.com/en-us/library/ms684122(v=vs.85).aspx). – Roger Rowland Aug 19 '13 at 13:54
  • You are going to get yourself into a *lot* of trouble with this. Slamming a critical section around a bool doesn't accomplish anything. And std::atomic<> does *not* magically make a big chunk of code thread-safe. Thread-safety needs to be built-in from the start, you cannot add it later. – Hans Passant Aug 19 '13 at 14:10

4 Answers4

5
  1. You don't need locks round atomic data, but internally they might lock. Note for example, C++11's std::atomic has a is_lock_free function.
  2. bool may not be atomic. See here and here
Community
  • 1
  • 1
doctorlove
  • 18,872
  • 2
  • 46
  • 62
4

Note: This answer applies to Windows and says nothing of other platforms.

There are no InterlockedRead or InterlockedWrite functions; simple reads and writes with the correct integer size (and alignment) are atomic on Windows ("Simple reads and writes to properly-aligned 32-bit variables are atomic operations.").

(and there are no cache problems since a properly-aligned variable is always on a single cache line).

However, reading and modifying such variables (or any other variable) are not atomic:

  • Read a bool? Fine. Test-And-Set a bool? Better use InterlockedCompareExchange.
  • Overwrite an integer? great! Add to it? Critical section.
Medinoc
  • 6,577
  • 20
  • 42
  • 1
    In Windows you can use `InterlockedXxx` easily to both set (`InterlockedExchange`) and add (`InterlockedExchangeAdd`). – Roman R. Aug 19 '13 at 19:12
  • You should say what architecture this applies to, I don't think its true on ARM – paulm Dec 08 '15 at 15:17
2

Here this can be found:

Simple reads and writes to properly aligned 64-bit variables are atomic on 64-bit Windows. Reads and writes to 64-bit values are not guaranteed to be atomic on 32-bit Windows. Reads and writes to variables of other sizes are not guaranteed to be atomic on any platform.

Result should be correct but in programming it is better not to trust should. There still remains small possibility of failure because of CPU cache.

ST3
  • 8,826
  • 3
  • 68
  • 92
  • You forgot the passage about 32-bit variables (previous paragraph). – Medinoc Aug 19 '13 at 15:34
  • @Medinoc First sentence is important too, however the quoted-one is more important, don't think that it is useful to make wide answers, because there are more info that may (or not may) be useful. – ST3 Aug 19 '13 at 18:42
1

You cannot guarantee for all implementations/platforms/compilers that bool, or any other type, or most operations, are atomic. So, no, I don't believe your statements are correct. You can retool your logic or use other means of establishing atomicity, but you probably can't get away with just removing CRITICAL_SECTION usage if you rely on it.

pattivacek
  • 5,617
  • 5
  • 48
  • 62