Forgot to reply to all, my apologies...
2012/5/9 Jonathan Wakely <[email protected]>
> 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 <[email protected]>
> 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
> >>> <[email protected]> wrote:
> >>>> Including the mingw64 project about this.
> >>>>
> >>>> On Sat, May 5, 2012 at 5:59 PM, Jonathan Wakely <
> [email protected]> 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.)
>
Yes, a different implementation would need a different thread model, unless
some form of startup code could detect OS version (or better, API
availability) and set function pointers accordingly. This would be IMHO the
best solution: new stuff if available, fallback to older (slower) stuff,
and fail (runtime exception) in case of truly missing irreplacable features.
>
> >>> ...
> >> ...
> >> 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
>
Yes, <thread> and associated things work when I configure GCC to use posix
threads (through the winpthreads layer).
There are a couple of reasons not to have this as a final solution:
1) As Kai already mentioned, all/most code built with GCC will depend on
winpthreads through libgcc. This is stupid, and in my eyes, bad.
2) All of GCC's threading stuff goes through the gthread api in libgcc.
winpthreads is a compatibility layer, which admittedly works great, but
really does have slower performance than a bare metal implementation.
The way I would see a practical solution is to implement as much as
possible sanely with widely available APIs (<thread> can do with
beginthreadex and associates, for example).
There are only a limited set of features that are best implemented on top
of the new stuff. For these I would either build a runtime backup codepath
(if the necessary API is not available, fall back to a slower
implementation based on older Windows API, or just plain fail when it's not
sanely possible to implement).
This solution is the only one that a) prevents excessive code duplication,
and b) assures the best performance regardless. This is also the only one
that keeps compatibility and won't require great breaking changes if I see
things correctly.
That said, a new threading model is great, but essentially unusable on
Windows XP. Which today might be a problem for people distributing
binaries. They'll have to build two versions (as I've said before) and
confuse their users even more than the usual 32-bit/64-bit drama people
still experience.
So my vote goes for: one single threading model which extends what is there
now and expands on it with two versions (one vista+ fast version) and one
fallback version which won't win any performance contests, but provide as
much as possible with the "ancient" 2000/XP API. A startup detection of API
functions can settle which versions'll be called. One more indirection
(function pointer set at runtime isn't going to mess up the simplified and
straightforward implementation.
Besides this, the posix threading model can stay on top of winpthreads and
perhaps will have its uses still.
Ruben
>
> >> 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.
>
>
> ------------------------------------------------------------------------------
> Live Security Virtual Conference
> Exclusive live event will cover all the ways today's security and
> threat landscape has changed and how IT managers can respond. Discussions
> will include endpoint security, mobile security and the latest in malware
> threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
> _______________________________________________
> Mingw-w64-public mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
>
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public