This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


On 9 May 2012 16:58, K. Frank wrote:
> Hello Jonathan!
>
> I've taken the liberty of cross-posting this to the mingw list
> (a separate project from mingw-w64), as they are the other
> big windows-focused "downstream" consumer of gcc.
>
> On Wed, May 9, 2012 at 9:29 AM, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>> On 7 May 2012 18:28, K. Frank wrote:
>>> 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.
>>
>> Well currently you get none of the thread support when GCC is built
>> with --enable-threads=win32. ?IMHO that's an even more significant
>> limitation than no <condition_variable>
>
> Ah, okay. ?I don't use ?--enable-threads=win32 or really know what
> it is. ?With what I think is the thoughtful and powerful threading
> support in c++11, my main focus has been to write standard,
> portable threading code using <thread>, hence my motivation
> to get <thread> working on mingw / mingw-w64.
>
> One note: ?In my experimentation, I wrote some windows-api
> threading programs and built them without specifying
> ?--enable-threads=win32, and they all seemed to work., ?So I
> guess I don't understand what ?--enable-threads=win32 is
> supposed to do.

You use it when GCC is *built* not when you invoke GCC. It sets the
value shown for "Thread model" when you run "gcc -v"



>> ...
>>>>> 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.)
>>
>> Too late. That's how they're implemented when GCC is built with
>> --enable-threads=win32
>
> Again, I'm not all that big on backward compatibility, and, as noted
> above, I don't understand what ?--enable-threads=win32 is for. ?But
> my gut reaction is if that the gcc implementation (with
> ?--enable-threads=win32) is sub-optimal, maybe it makes sense to
> do it "right," even at the cost of backward compatibility.

That's not an option.  If there is to be a non-backwards-compatible
implementation then it must be a new thread model,
e.g.--enable-threads=win64 (yes, that name is wrong, it's just an
example.)

>>> ...
>> ...
>> My first suggestion is to improve that one in limited ways, retaining
>> backwards compatibility but adding <thread> and <mutex> which AFAIK
>> don't currently work.
>
> Yeah, okay. ?I would see value in making incremental improvements
> to something that's already in use.
>
>> My second suggestion is to write a replacement (call it
>> --enable-threads=win64 for the sake of argument) which would use
>> critical sections and support <thread>, <mutex>, <ondition_variable>
>> and <future>.
>
> Just to be clear: ?Why would mingw-w64's winpthreads-based <thread>
> implementation not fit the bill for the replacement you suggest?

Maybe Ruben can confirm but I assume that can be used when GCC is
built with --enable-threads=posix

That's no use for people who use a GCC built with --enable-threads=win32

>> The suggestions are independent of each other.
>
> Yes, I understand that now.
>
>>>?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.
>>
>> Spawning a new thread to block on a mutex seems over the top, but if
>> it works it works.
>
> This approach didn't seem ideal to me, either.
>
> However, given my two self-imposed constraints:
>
> ? use windows critical sections for timed mutexes (for performance
> ? and to keep timed mutexes using the same underlying mechanism
> ? as untimed mutexes)
>
> and
>
> ? not reimplement the core mutex logic (e.g., not maintain my own
> ? queue or set of threads waiting on the mutex)
>
> spawning the helper thread was the only way I could figure out how
> to make timed mutexes work. ?I would be very interested if anyone
> has a suggestion as to how to avoid the helper thread, consistent
> with the above two constraints.
>
>> ...
>>>>> 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.
>>
>> No you wouldn't. ?std::condition_variable only works with std::mutex
>> (which we agree should use a critical section), so it's irrelevant how
>> std::timed_mutex is implemented. ?If you want to use a condition
>> variable with a std:timed_mutex then you have to use
>> std::condition_variable_any and that internally uses a std::mutex, so
>> can internally use native OS condition varaibles.
>
> Yes, okay, that's fair. ?My thinking had been for consistency (foolish
> consistency?) that mutexes and timed mutexes "ought" to be based
> on the same underlying synchronization method.

There's no resson they have to be, and if std::mutex is based on
critical sections, and they don't support timed waits, then there's a
good reason for them not to be.

(This seems to be going in circles, this is what I said in my initial
email which Gaby forwarded to the mingw list!)


>>> ...
>>> 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.
>>
>> There isn't a linux <thread> implementation, there is a POSIX one,
>> used by building GCC with --enable-threads=posix. ?I expect that
>> already works on Windows, I'm only talking about
>> --enable-threads=win32
>
> I'm not sure I understand this. ?I am under the impression that if I get
> a generic linux gcc (of late enough vintage), and use "--std=c++0x",
> then <thread> works (just like it does on windows with Ruben's
> build).

Yes, it works, but it's not linux-specific.  There's a generic "posix"
thread model based on pthreads which works on linux and all other
POSIX system.


> Maybe it's just semantics, but why doesn't that count as a "linux
> <thread> implementation"?

Because it's used on Solaris and Mac and BSD and AIX etc.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]