Hi Eric,
On 6/28/19 3:42 PM, NightStrike wrote:
FYI, Eric posted this today to the GCC patches list. This may be of
great interest to many who would prefer native threads instead of the
winpthreads posix style interface.
Great work, Eric! I look forward to trying this out!
---------- Forwarded message ---------
From: Eric Botcazou <ebotca...@adacore.com>
Date: Fri, Jun 28, 2019 at 6:51 AM
Subject: [patch] Reimplement GNU threads library on native Windows
To: <gcc-patches@gcc.gnu.org>
Cc: <libstd...@gcc.gnu.org>
Hi,
this reimplements the GNU threads library on native Windows (except for the
Objective-C specific subset) using direct Win32 API calls, in lieu of the
implementation based on semaphores. This base implementations requires
Windows XP/Server 2003, which is the default minimal setting of MinGW-W64.
This also adds the support required for the C++11 threads, using again direct
Win32 API calls; this additional layer requires Windows Vista/Server 2008 and
is enabled only if _GTHREADS_USE_COND is defined to 1.
This also changes libstdc++ to setting _GTHREADS_USE_COND to 1 when the switch
--enable-libstdcxx-threads is passed, which means that C++11 threads are still
disabled by default on native Windows and that you need to explicitly pass the
switch to enable them. The 30_threads chapter of the testsuite is clean.
Tested on i686-pc-mingw32 and x86_64-pc-mingw32, OK for the mainline?
It's indeed great to see this. Thank you!
+/* The implementation strategy for the c++0x thread support is as follows.
+
+ A GNU thread is represented by a Win32 HANDLE that is obtained when the
+ Win32 thread is created, except of course for the initial thread. This
+ Win32 HANDLE is stored in a descriptor keyed from TLS memory for every
+ thread, so the self routine can return it instead of having to duplicate
+ the pseudo-handle returned by GetCurrentThread each time it is invoked.
+ For the initial thread, this Win32 HANDLE is created during the first
+ call to the self routine using the aforementioned technique.
+
+ Note that the equal routine compares the identifier of threads instead
+ of their Win32 HANDLE, which will give the correct positive answer even
+ in the case where distinct Win32 HANDLEs have been created for the same
+ thread by multiple instances of libgcc included in the link. */
Note that this will cause handle leaks if used across multiple libgcc
instances, through.
+#include "gthr-win32.h"
+
+/* The thread descriptor keyed from TLS memory. */
+struct __gthr_win32_thr_desc
+{
+ void *(*func) (void*);
+ void *args;
+ HANDLE h;
+};
+
+/* The TLS key used by one instance of the library. */
+static __gthread_key_t __gthr_win32_tls = TLS_OUT_OF_INDEXES;
+
+/* The initialization device for the TLS key. */
+static __gthread_once_t __gthr_win32_tls_once = __GTHREAD_ONCE_INIT;
+
+/* Initialize the TLS key. */
+
+static void
+__gthr_win32_tls_init (void)
+{
+ if (__gthread_key_create (&__gthr_win32_tls, free))
+ abort ();
+}
You don't really need to store the whole __gthr_win32_thr_desc in TLS. If you
stored just the handle, this wouldn't need a destructor.
Thanks,
Jacek