views:

176

answers:

3

Does anyone know of a Windows user-mode thread synchronization library for C++ (utilizing spin locks / atomic operations)? I only need mutexes (~critical sections), but condition variables would be a plus.

+2  A: 

You have the win 32 one: http://msdn.microsoft.com/en-us/library/ms682530%28VS.85%29.aspx. You have a complete explanation of synchronization using this library here.

Patrice Bernassola
Win32 critical sections are not user-mode constructs, are they?
CyberShadow
They are user-mode only for uncontested locks. When you get highly-contested locks, you'll get switching to kernel-mode.
Eclipse
+1  A: 

As Patrice stated, you can use the win32 library for user mode (critical section contains a spincount which will spin).

Visual Studio 2010 Beta2 / Win7 x64 contain the Concurrency Runtime (ConcRT) which is built on User Mode Scheduled threads, which allow ConcRT to detect kernel blocking and switch to another task in user mode (lower overhead than a typical context swap). So for example if you use boost::thread and their condition variables and mutexes on a task in ConcRT these will be handled in user mode.

You can also use Intel's Threading Building Blocks which contains some user mode spin locks. No condition variable.

Anthony Williams has an implementation of std::thread for sale on his website that includes the atomics library from C++0x if you really want to build your own spinlocks.

In general unless you are doing very fine grained synchronization where you guarantee there isn't going to be lots of contention, I'd encourage you to be judicious with your usage of spinlocks, they tend to 'spin' and as such consume system cpu resources...

-Rick

Rick
A: 

Thank you for the answers. Turns out that basing my expectations about the size of a threading library on boost was a bad idea, and writing your own synchronization code based on InterlockedExchange is dead-simple. My spinlock code achieves a performance of about 20% better than Win32 critical sections (and I mean real application performance, not a synthetic test) :)

CyberShadow
I'm not sure I would call any non trivial synchronization code 'dead simple' - synchronization tends to be very difficult.
Stephen Nutt
That statement is a bit out of context, isn't it? Locking a mutex is as simple as `while (InterlockedExchange(`, and unlocking is `x=0;`.
CyberShadow
In the general case locking a mutex is not that simple, but I agree it can be. This simple approach can cause starvation and priority inversion - however if all your threads run at the same priority and contention for the mutex is low then these issues may not be of concern.
Stephen Nutt
It's true, that's my situation. Since such mutexes are very cheap in terms of resources, I partition my shared resources as much as possible and lock each partition individually - that way, these is practically no contention.
CyberShadow
Note to whoever might be reading this: even almost-never-contested locks are very expensive. It might be much faster to perform completely parallel processing, and then merge the results (e.g. using delayed duplicate detection).
CyberShadow