[Mingw-w64-public] Thoughts on supporting the C++11 thread library on Windows

K. Frank kfrank29.c@gmail.com
Mon May 7 17:28:00 GMT 2012


Hello Gabriel (and Ruben)!

By the way, I'm the guy Ruben mentioned in his subsequent post.

On Sat, May 5, 2012 at 11:20 PM, Gabriel Dos Reis
<gdr@integrable-solutions.net> wrote:
> Including the mingw64 project about this.
>
> On Sat, May 5, 2012 at 5:59 PM, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>> For GCC 4.7 I enabled most of <thread> (without timed mutexes) on Mac
>> OS X by making the _GLIBCXX_HAS_GTHREADS macro more fine-grained.  I
>> think we could quite easily do the same again for the win32 thread
>> model (defined in gthr-win32.h) so that <thread> and <mutex> are
>> available (including timed mutexes), but without <condition_variable>
>> and <future>.

Just my opinion:  One could make the macro more fine-grained, but I
really wouldn't want to do this.  If I'm using <thread> I'm using c++11,
so I like to think I'm in the "modern world."  I think (in the modern world)
that condition variables are a core part of threading, so I'd find is a
significant limitation if my c++11 implementation didn't have them.

(Also, I think that once you have the threading primitives (<thread>,
<mutex>, and <condition_variable>), you get <future> "for free" in the
sense that it's written on top of the primitives, and you don't need any
further os-specific support.)

>> It's harder to support <condition_variable> because Windows didn't
>> provide condition variables until Vista, and even then they interact
>> with a CRITICAL_SECTION and gthr-win32.h defines mutexes in terms of a
>> semaphore not a critical section.

Even leaving condition variables aside, I really don't think you want to
implement mutexes in terms of windows semaphores (or windows mutexes)
(unless your primary goal is to support older (pre-xp?) versions of windows.)
I believe (speaking from memory) that I built a trial implementation of <thread>
using  windows mutexes and that it was much slower than using windows
critical sections.  I think both creation and locking were slower, but I don't
remember the details.  This is reasonable, because windows mutexes (and
semaphores) are heavier-weight objects -- they provide cross-process
synchronization, not just intra-process, cross-thread synchronization.

And, as you mentioned, if you want to support condition variables (in terms
of windows condition variables), you need to base your mutexes on windows
critical sections.

>> Douglas Schmidt describes an
>> implementation of condition variables at
>> http://www.cs.wustl.edu/~schmidt/win32-cv-1.html but that also
>> requires mutexes to be critical sections - maybe that could be adapted
>> to use the gthr-win32.h semaphore-based definition of
>> __gthread_mutex_t, I haven't looked into it in detail.   My suggestion
>> would be to support <thread> and <mutex> but not <condition_variable>
>> (or <future> because our implementation uses a
>> std::condition_variable.)

My personal feeling is that a version of <thread> that is complete
(i.e., supports condition variables and futures), but requires windows
vista or later is a fine way to go.

Certainly given an either-or choice of an incomplete <thread> that
works pre-vista, or a complete <thread> that requires vista or later,
I would certainly vote for the complete <thread> and forgo pre-vista
support.

>> I have some untested implementations of
>> __gthread_create, __gthread_join etc. if anyone wants to work on
>> implementing that suggestion.  I don't have a Windows machine or
>> enough free time to do that myself in the near future.
>>
>> As a second idea, supporting the full C++11 thread library could be
>> done by creating a new thread model to be used instead of win32, which
>> would only be supported on Vista or later and would use Windows
>> critical sections for std::mutex and Windows  condition variables for
>> std::condition_variable.

I've done this, and it seems to work fine.  I would recommend it.

(I'm not sure what you mean by "a new thread model to be used instead
of win32."  The way I look at it I used win32, i.e., I implemented <thread>
on top of the vista-and-later version of win32.)

>> Critical sections don't support a timed
>> wait, so that thread model would be similar to the Mac OS X support
>> and omit timed mutexes.

I had to write some extra code to get timed mutexes to work.  I used
windows critical sections (just as for untimed mutexes), but spawned
a helper thread that blocked on the critical section, and had the original
thread use a timed windows WaitForSingleObject to wait (with a
timeout) for the helper thread.

>> That could easily be solved by implementing
>> std::timed_mutex as a Windows mutex instead of a critical section,

Again, I wouldn't recommend using windows mutexes as you would
lose condition variables.  Also, as I mentioned above, they are much
more expensive than critical sections.

>> but
>> that would be difficult in the current Gthreads design because it
>> follows POSIX and assumes that a timed mutex is exactly the same type
>> as a non-timed mutex and you just use a different function to wait.
>> We should consider adding a __gthread_timed_mutex type which can be
>> different to __gthread_mutex_t, but would be the same type on POSIX
>> platforms that support the Timeouts option and define
>> pthread_mutex_timedlock.   Again, I have some sketches to make that
>> work but nothing concrete.
>>
>> If there are any Windows hackers out there who want to improve thread
>> support on their platform please get in touch, I'll be happy to help
>> and advise (although not for the next two weeks as I'm about to go on
>> holiday.)

I have a pretty complete mingw / mingw-w64 <thread> implementation
that uses win32 directly and doesn't rely on pthreads.  I'd certainly be
happy to make it available, if people would find it useful.  As noted, it
requires vista or later.  (I've only tested in on 64-bit windows 7.)

But I'm not sure that there is any problem that needs to be solved.

For my own <thread> programming, I have been using "The Mighty
Ruben's Wacky Build" (TM) of mingw-w64 gcc 4.7.0 that has <thread>
implemented on top of winpthreads.  It passes all of my (not particularly
complete) <thread> tests.  Presumably it works pre vista.

And although I don't care much about pthreads, as a practical matter
there is an awful lot of pthreads code out there so a mingw-w64
offering that doesn't support pthreads would be a significant limitation.
Now that mingw-w64 has winpthreads, it's very little work to modify
the linux gcc <thread> implementation to work on windows.  Plus,
you get the added benefit that you can more easily mix pthreads
code with c++11 <thread> code because they use the same
underlying threading implementation (if you care).

Also, there are (as would be expected) some performance differences.
I ran some tests about half a year ago.  A parallel_accumulate
"practical" multithreading test was modestly slower with the
winpthreads implementation of <thread> than with the native
implementation; a mutex-contention test was more that an order
of magnitude slower; and a condition-variable test was significantly
faster.

Please let me know if you would like any follow-up information.


Happy Threading!


K. Frank



More information about the Libstdc++ mailing list