1

According to the answers from this question last versions of boost::mutex uses atomic operations and a Win32 Event for blocking waits instead of critical sections. Why? What is the reason behind it?

Community
  • 1
  • 1
FrozenHeart
  • 19,844
  • 33
  • 126
  • 242
  • I guess in order to enhance portability? – David Haim Nov 03 '15 at 11:56
  • @David Haim Win32 Events is a less platform-specific thing than critical sections in your opinion? – FrozenHeart Nov 03 '15 at 11:59
  • I guess that they preferred platform events + independend atomic opertaion over completly platform implementation – David Haim Nov 03 '15 at 12:02
  • I doubt you will get an answer here better to ask the developers who did it on some boost-related resource where they hang. Still the question is interesting since it looks not quite reasonable to replace critical sessions to events unless boost is meant to be used in ring0 code. – ixSci Nov 03 '15 at 12:05
  • @DavidHaim, they use platform specific events mechanism for the synchronization it is not cross-platform. In that it doesn't differ from the critical sessions which are windows specific as well – ixSci Nov 03 '15 at 12:06
  • 1
    @FrozenHeart nobody said Event is less platform specific. David said "to enhance portability" (of the library). The library will want to guarantee similar _semantics_ on all OS-es. This could be a factor. Not I say "could be" because I don't know. So, "enhancing portability" is about the _behaviour_ of `boost::mutex`, **not** about whether the code can compile on a platform. – sehe Nov 03 '15 at 13:04

1 Answers1

3

I belive that this what you are looking for (from https://www.justsoftwaresolutions.co.uk/articles/implementing_mutexes.html):

The simplest way to implement a mutex would be to write a wrapper class for one of the native Windows synchronization objects; after all, that's what they're there for. Unfortunately, they all have their problems. The Mutex, Event and Semaphore are kernel objects, so every synchronization call requires a context switch to the kernel. This can be rather expensive, especially so when there is no contention.

Boost mutexes are only designed for use within a single process, so the CRITICAL_SECTION looks appealing. Unfortunately, there are problems with this, too. The first of these is that it requires explicit initialization, which means it cannot reliably be used as part of an object with static storage duration — the standard static-initialization-order problem is compounded by the potential of race conditions, especially if the mutex is used as a local static. On most compilers, dynamic initialization of objects with static storage duration is not thread-safe, so two threads may race to run the initialization, potentially leading to the initialization being run twice, or one thread proceding without waiting for the initialization being run by the other thread to complete. The second problem is that you can't do a timed wait on a CRITICAL_SECTION, which means we need another solution for a mutex that supports timed waits, anyway.

There is also another problem with using CRITICAL_SECTIONs as a high-performance mutex, which is that a thread unlocking the CRITICAL_SECTION will hand-off ownership to a waiting thread.

fghj
  • 8,898
  • 4
  • 28
  • 56