Message ID | 0f1f223a-3756-1da3-bd1d-b87edd34e1f9@126.com |
---|---|
State | New, archived |
Headers |
Return-Path: <gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp338204wrs; Sat, 1 Oct 2022 11:36:16 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6z9m6Wyzzh4RhEYmQIaqm82hruAkYmXWzLP07OXuWITgzZQ4RArMC8HpdEZz05f4X0ep7n X-Received: by 2002:a17:907:3205:b0:770:8554:c4ee with SMTP id xg5-20020a170907320500b007708554c4eemr10598247ejb.39.1664649375947; Sat, 01 Oct 2022 11:36:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664649375; cv=none; d=google.com; s=arc-20160816; b=Lh1R+sUM+HohamiTY+7Ea1U4ReIvkLfT5IZqGkuX7ur3dxNDNHftvjk+bzIg1Hla6B kDPB5zimYbr1LLoCmYKcvSzFwBkBYraJvwxgWAlwE/tJsIGpuzXYl+no0tpvkYcFM1Xj 5LwahlhIJLu5SkuXlO7sObGEw0xGkYpLojHAcgqJEYO2shoUZstaMzHyMcH4UdP+WSnO Whx3NIxK3PScneqewaMsoM8MXpN/HS18z2SxCKyRde4JTvj3xwPCs5GcizAjsf3ty5lw ui4PKIan0mMV7PHmc6PiUfPS58o6r5JpKWf279Kup4xcjSGYy9wL3x2rwuW6uk91c7kn fpag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:to :content-language:user-agent:mime-version:date:message-id :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=kRZpRSV+HU4+v9bti/+C9z6ELD5WgLRkxfzMriyC1Dc=; b=aGFmSUh9Q6+MFQav1Vaha/QNUAQ9SPG0kfi93PFVW1mRvTCpZOs5iZf92zABq5OEoF 0thhxpDO8QtEfPwtzg5cyuYh8OriCTFsiOZTO8/TdossjYGK30BSVxAv6yhh6QJpXJ4C 2MlPEDHyv18ox309PtR9KWM5JMnH/Z3OydEJowVLv6e++yzjnenbQhrc947LAW9KFyg0 N+kVkDdsWXCOKE5YRtxFsnfmldv9Id3rhViSYoEW0H5zQgFqAXrqQl230DmLyitzdhyq kkHALWMJx3H4KINxhrSboYcbmrjQD0/JQJBfa+d6L66DHhYjgbVSFo5KV93Bzx5G0BEl wzOw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=OcbiUYGv; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id gm1-20020a1709073d0100b0078034101c0esi5171805ejc.978.2022.10.01.11.36.15 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Oct 2022 11:36:15 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=OcbiUYGv; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 30E113854163 for <ouuuleilei@gmail.com>; Sat, 1 Oct 2022 18:35:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 30E113854163 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1664649350; bh=kRZpRSV+HU4+v9bti/+C9z6ELD5WgLRkxfzMriyC1Dc=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=OcbiUYGvnSgK5k/lDV5YqWez88YjiBECfj+TRH7Vn5eG25+Wj9yvMgX4c4V0XykXK 3PbBWaId3OkgXENpx7u9FF8+HDNbtAdLm6X8d07H+3AAA8W4LujiE2f06MNHgFfWQI JOXN1KoLZT5xBsfS852gjorbmk00fjzaLXWX3RCc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from m15111.mail.126.com (m15111.mail.126.com [220.181.15.111]) by sourceware.org (Postfix) with ESMTP id 24DD83858D38; Sat, 1 Oct 2022 18:34:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 24DD83858D38 Received: from [192.168.1.2] (unknown [101.93.199.8]) by smtp1 (Coremail) with SMTP id C8mowABnSm5FiDhjozY_Cg--.25468S2; Sun, 02 Oct 2022 02:34:46 +0800 (CST) Message-ID: <0f1f223a-3756-1da3-bd1d-b87edd34e1f9@126.com> Date: Sun, 2 Oct 2022 02:34:45 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.3.0 Content-Language: en-US To: gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org Subject: Adding a new thread model to GCC Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="------------B0K5ZSFzZk0htVf0iXLWQYpi" X-CM-TRANSID: C8mowABnSm5FiDhjozY_Cg--.25468S2 X-Coremail-Antispam: 1Uf129KBjvJXoW7KF1UCw18uFWUAFWruFWkXrb_yoW8Gw4rpr W5Wrn0grWvyry7u3WkJan3Xr48Ja18ZF9rWa4rJryvva1rWF48WFy8KFZ0va45Ar95Gw17 AF45Zrn5Aa1qvFJanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jJ6pPUUUUU= X-Originating-IP: [101.93.199.8] X-CM-SenderInfo: 5okbz0xxvhqiyswou0bp/1tbiFweNRlpEE+qNkQAAsg X-Spam-Status: No, score=-3132.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_VALIDITY_RPBL, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_SBL_A autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> From: LIU Hao via Gcc-patches <gcc-patches@gcc.gnu.org> Reply-To: LIU Hao <lh_mouse@126.com> Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org> X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1745511384143160039?= X-GMAIL-MSGID: =?utf-8?q?1745511384143160039?= |
Series |
Adding a new thread model to GCC
|
|
Commit Message
LIU Hao
Oct. 1, 2022, 6:34 p.m. UTC
Greetings.
After some years I think it's time to put on this topic again.
This patch series is an attempt to add a new thread model basing on the mcfgthread library
(https://github.com/lhmouse/mcfgthread), which provides efficient implementations of mutexes,
condition variables, once flags, etc. for native Windows.
The first patch is necessary because somewhere in libgfortran, `pthread_t` is referenced. If the
thread model is not `posix`, it fails to compile.
The second patch implements `std::thread::hardware_concurrency()` for non-posix thread models. This
would also work for the win32 thread model if `std::thread` would be supported in the future.
The third patch adds the `mcf` thread model for GCC and its libraries. A new builtin macro
`__USING_MCFGTHREAD__` is added to indicate whether this new thread model is in effect. This grants
`std::mutex` and `std::once_flag` trivial destructors; `std::condition_variable` is a bit
unfortunate because its destructor is non-trivial, but in reality no cleanup is performed.
I have been bootstrapping GCC with the MCF thread model for more than five years. At the moment, C,
C++ and Fortran are supported. Ada is untested because I don't know how to bootstrap it. Objective-C
is not supported, because threading APIs for libobjc have not been implemented.
Please review. If there are any changes that I have to make, let me know.
--
Best regards,
LIU Hao
From c522fa74c791ee8904b5906c6e18908b56071db5 Mon Sep 17 00:00:00 2001
From: LIU Hao <lh_mouse@126.com>
Date: Fri, 27 May 2022 23:12:48 +0800
Subject: [PATCH 1/3] libgfortran: Use `__gthread_t` instead of `pthread_t`
It used to cause errors if a thread model other than `posix` was selected,
which looks like a leftover from a79878585a1c5e32bafbc6d1e73f91fd6e4293bf.
libgfortran/ChangeLog:
* io/async.h (struct async_unit): Use `__gthread_t` instead
of `pthread_t`.
---
libgfortran/io/async.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Comments
On 1 October 2022 20:34:45 CEST, LIU Hao via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: >Greetings. >The first patch is necessary because somewhere in libgfortran, `pthread_t` is referenced. If the thread model is not `posix`, it fails to compile. One of several shortcomings mentioned already on Sun, 02 Sep 2018 15:40:28 -0700 in https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg196212.html
在 2022-10-02 04:02, Bernhard Reutner-Fischer 写道: > On 1 October 2022 20:34:45 CEST, LIU Hao via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: >> Greetings. > >> The first patch is necessary because somewhere in libgfortran, `pthread_t` is referenced. If the thread model is not `posix`, it fails to compile. > > One of several shortcomings mentioned already on Sun, 02 Sep 2018 15:40:28 -0700 in > https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg196212.html > Forgive me but I didn't get your point. Is the 'shortcoming' the fact that `pthread_t` must be preferred to `__gthread_t`? For non-posix thread models, <pthread.h> is not included, so `pthread_t` is not declared. I haven't looked at other code in libgfortran, but changing `pthread_t` to `__gthread_t` does allow libgfortran to build. I don't know how to test it though, as I don't write Fortran myself. -- Best regards, LIU Hao
On 2 October 2022 14:54:54 CEST, LIU Hao <lh_mouse@126.com> wrote: >在 2022-10-02 04:02, Bernhard Reutner-Fischer 写道: >> On 1 October 2022 20:34:45 CEST, LIU Hao via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: >>> Greetings. >> >>> The first patch is necessary because somewhere in libgfortran, `pthread_t` is referenced. If the thread model is not `posix`, it fails to compile. >> >> One of several shortcomings mentioned already on Sun, 02 Sep 2018 15:40:28 -0700 in >> https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg196212.html >> > >Forgive me but I didn't get your point. Is the 'shortcoming' the fact that `pthread_t` must be preferred to `__gthread_t`? No, sorry for my brevity. Using __gthread_t like in your patch is correct. thanks, > >For non-posix thread models, <pthread.h> is not included, so `pthread_t` is not declared. I haven't looked at other code in libgfortran, but changing `pthread_t` to `__gthread_t` does allow libgfortran to build. I don't know how to test it though, as I don't write Fortran myself. > >
在 2022-10-03 13:03, Bernhard Reutner-Fischer 写道: > > No, sorry for my brevity. > Using __gthread_t like in your patch is correct. > I see. In 'libgfortran/io/async.c' there is ``` async_unit *au = u->au; LOCK (&au->lock); thread_unit = u; au->thread = __gthread_self (); ``` so indeed `thread` should be `__gthread_t`. By the way I reported this issue four months ago and haven't received any response so far: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105764 -- Best regards, LIU Hao
Attached are revised patches. These are exported from trunk.
There is a change since my last message:
* A new Makefile variable `SHLIB_MCFGTHREAD_LIBS` has been introduced, to keep
the other thread models from being affected.
After applying these patches, configure scripts in these subdirectories need to be regenerated:
* gcc
* libgcc
* libatomic
* libstdc++-v3
The patch for libgfortran fixes
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105764
I have successfully bootstrapped GCC 12 with these patches, on i686-w64-mingw32 (with MSVCRT) and
x86_64-w64-mingw32 (with MSVCRT and UCRT). No errors have been observed so far.
Once these patches land in GCC, we can start the work in mingw-w64 basing on `__USING_MCFGTHREAD__`.
--
Best regards,
LIU Hao
From e1ab15fc95ac8180156feed410cacb64a41a9567 Mon Sep 17 00:00:00 2001
From: LIU Hao <lh_mouse@126.com>
Date: Fri, 27 May 2022 23:12:48 +0800
Subject: [PATCH 1/3] libgfortran: Use `__gthread_t` instead of `pthread_t`
It used to cause errors if a thread model other than `posix` was selected,
which looks like a leftover from a79878585a1c5e32bafbc6d1e73f91fd6e4293bf.
libgfortran/ChangeLog:
* io/async.h (struct async_unit): Use `__gthread_t` instead
of `pthread_t`.
---
libgfortran/io/async.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libgfortran/io/async.h b/libgfortran/io/async.h
index efd542a45e82..d57722a95e44 100644
--- a/libgfortran/io/async.h
+++ b/libgfortran/io/async.h
@@ -351,7 +351,7 @@ typedef struct async_unit
struct adv_cond work;
struct adv_cond emptysignal;
struct st_parameter_dt *pdt;
- pthread_t thread;
+ __gthread_t thread;
struct transfer_queue *head;
struct transfer_queue *tail;
I don't really understand MinGW, but some "non-technical" things: On Tue, 2022-10-04 at 20:44 +0800, LIU Hao via Gcc-patches wrote: > After applying these patches, configure scripts in these > subdirectories need to be regenerated: > > * gcc > * libgcc > * libatomic > * libstdc++-v3 In GCC development we usually include the configure regeneration in the patch because the scripts are also version controlled. > The patch for libgfortran fixes > > * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105764 It's better to include the ID in the subject and ChangeLog of the patch. Like: [PATCH 1/3] libgfortran: Use `__gthread_t` instead of `pthread_t` [PR 105764] It used to cause errors if a thread model other than `posix` was selected, which looks like a leftover from a79878585a1c5e32bafbc6d1e73f91fd6e4293bf. libgfortran/ChangeLog: PR libgfortran/105764 * io/async.h (struct async_unit): Use `__gthread_t` instead of `pthread_t`. This allows a git hook to append a message into the PR 105764 entry in bugzilla once the patch is committed into trunk. Normally I leave an empty line after "ChangeLog:" but I'm not sure if it's strictly needed. > gcc/config/ChangeLog: > * i386/mingw-mcfgthread.h: New file > * i386/mingw32.h: Add builtin macro and default libraries for > mcfgthread when thread model is `mcf` Normally I leave a "." for each ChangeLog entry, but I'm not sure if it's strictly needed. However there is no gcc/config/ChangeLog, use gcc/ChangeLog instead. And, from https://gcc.gnu.org/contribute.html#patches: "It is strongly discouraged to post patches as MIME parts of type application/whatever, disposition attachment or encoded as base64 or quoted-printable." Just try "git send-email", it will do the correct thing. Mimicking its behavior in a mail client is also possible but error-prune (the mail client can destroy your patch by replacing your tabs with spaces, etc.)
在 2022-10-04 21:13, Xi Ruoyao 写道: > > In GCC development we usually include the configure regeneration in the > patch because the scripts are also version controlled. > There is a reason for not doing that: Generated contents can't be reviewed. In mingw-w64 we do the opposite: The person who commits a patch is responsible for update configure, Makefile.in, etc. The patch itself doesn't include generated contents. > It's better to include the ID in the subject and ChangeLog of the patch. > Like: > > [PATCH 1/3] libgfortran: Use `__gthread_t` instead of `pthread_t` [PR 105764] > > It used to cause errors if a thread model other than `posix` was selected, > which looks like a leftover from a79878585a1c5e32bafbc6d1e73f91fd6e4293bf. > > libgfortran/ChangeLog: > > PR libgfortran/105764 > * io/async.h (struct async_unit): Use `__gthread_t` instead > of `pthread_t`. > Yes I think this change is good. > > And, from https://gcc.gnu.org/contribute.html#patches: > > "It is strongly discouraged to post patches as MIME parts of type > application/whatever, disposition attachment or encoded as base64 or > quoted-printable." > > Just try "git send-email", it will do the correct thing. Mimicking its > behavior in a mail client is also possible but error-prune (the mail > client can destroy your patch by replacing your tabs with spaces, etc.) > It's 'discouraged'. It is not forbidden. I expect everywhere people who receive emails to accept attachments. Thunderbird has a nice feature to display text attachments inline, so there is no need to download it and open it with an external editor, or whatever. And, I never get `git send-mail` work on my machine: ``` Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): y Unable to initialize SMTP properly. Check config and use --smtp-debug. VA LUES: server=smtp.126.com encryption=tls hello=localhost.localdomain port =465 at /usr/lib/git-core/git-send-email line 1684, <FIN> line 3. ``` -- Best regards, LIU Hao
On 4 October 2022 10:06:00 CEST, LIU Hao <lh_mouse@126.com> wrote: >在 2022-10-03 13:03, Bernhard Reutner-Fischer 写道: >> >> No, sorry for my brevity. >> Using __gthread_t like in your patch is correct. >> > >I see. In 'libgfortran/io/async.c' there is > > ``` > async_unit *au = u->au; > LOCK (&au->lock); > thread_unit = u; > au->thread = __gthread_self (); > ``` > >so indeed `thread` should be `__gthread_t`. Yes. > By the way I reported this issue four months ago and haven't received any response so far: > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105764 So, ideally, you would mention this PR in your patch. LGTM (obvious even) but I cannot formally approve it. thanks,
On Tue, 2022-10-04 at 21:45 +0800, LIU Hao wrote: > 在 2022-10-04 21:13, Xi Ruoyao 写道: > > > > In GCC development we usually include the configure regeneration in the > > patch because the scripts are also version controlled. > > > > There is a reason for not doing that: Generated contents can't be reviewed. > > In mingw-w64 we do the opposite: The person who commits a patch is responsible for update configure, > Makefile.in, etc. The patch itself doesn't include generated contents. The reviewer can simply skip the changes in configure. But including the configure allows the potential testers to test the change without autoconf-2.69 installed. Maybe we can make a compromise: put the line "configure: Regenerate." in the ChangeLog, but do not actually include the change. Now if the committer forgot to regenerate it, the git hook will reject the push immediately. (Just my 2 cents.)
在 2022-10-04 20:44, LIU Hao 写道: > Attached are revised patches. These are exported from trunk. > Revised further. The patch for libgfortran has been committed to trunk today, so I include only the other two. * In the second patch, a space character has been inserted after `(int)` for clearness. * The macro controlling how to build GCC itself has been renamed to `TARGET_USING_MCFGTHREAD` for consistency. * Checks against `TARGET_USING_MCFGTHREAD` have been updated in a more friendly way. * When not using mcfgthread, NTDLL is no longer a default library. Although all recent Windows versions are based on the NT kernel, there could still be people who want to target 9x or CE; thus NTDLL is only added when it is potentially necessary, for example when linking against the static libgcc. -- Best regards, LIU Hao From b371849927adba290d1e17e2a43866cc3465eb4c Mon Sep 17 00:00:00 2001 From: LIU Hao <lh_mouse@126.com> Date: Sun, 2 Oct 2022 00:57:08 +0800 Subject: [PATCH 1/2] libstdc++/thread: Implement `_GLIBCXX_NPROCS` for Windows This makes `std::thread::hardware_concurrency()` return the number of logical processors, instead of zero. libstdc++-v3/ChangeLog: * src/c++11/thread.cc (get_nprocs): Add new implementation for native Windows targets --- libstdc++-v3/src/c++11/thread.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libstdc++-v3/src/c++11/thread.cc b/libstdc++-v3/src/c++11/thread.cc index 707a4ad415b9..a54bc3e939a0 100644 --- a/libstdc++-v3/src/c++11/thread.cc +++ b/libstdc++-v3/src/c++11/thread.cc @@ -68,6 +68,15 @@ static inline int get_nprocs() #elif defined(_GLIBCXX_USE_SC_NPROC_ONLN) # include <unistd.h> # define _GLIBCXX_NPROCS sysconf(_SC_NPROC_ONLN) +#elif defined(_WIN32) +# include <windows.h> +static inline int get_nprocs() +{ + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return (int) sysinfo.dwNumberOfProcessors; +} +# define _GLIBCXX_NPROCS get_nprocs() #else # define _GLIBCXX_NPROCS 0 #endif
在 2022-10-10 23:56, LIU Hao 写道: > 在 2022-10-04 20:44, LIU Hao 写道: >> Attached are revised patches. These are exported from trunk. >> > > Revised further. The patch for libgfortran has been committed to trunk today, so I include only the > other two. > > * In the second patch, a space character has been inserted after > `(int)` for clearness. > > * The macro controlling how to build GCC itself has been renamed to > `TARGET_USING_MCFGTHREAD` for consistency. > > * Checks against `TARGET_USING_MCFGTHREAD` have been updated in a > more friendly way. > > * When not using mcfgthread, NTDLL is no longer a default library. > Although all recent Windows versions are based on the NT kernel, > there could still be people who want to target 9x or CE; thus > NTDLL is only added when it is potentially necessary, for example > when linking against the static libgcc. > > Attached is the (previous) third patch, with configure scripts regenerated. -- Best regards, LIU Hao From c32690fa4878d8824a0e05e54f614a8dd9ed68b7 Mon Sep 17 00:00:00 2001 From: LIU Hao <lh_mouse@126.com> Date: Sat, 16 Apr 2022 00:46:23 +0800 Subject: [PATCH 2/2] gcc: Add 'mcf' thread model support from mcfgthread This patch adds the new thread model `mcf`, which implements mutexes and condition variables with the mcfgthread library. Source code for mcfgthread is available at <https://github.com/lhmouse/mcfgthread>. config/ChangeLog: * gthr.m4 (GCC_AC_THREAD_HEADER): Add new case for `mcf` thread model gcc/config/ChangeLog: * i386/mingw-mcfgthread.h: New file * i386/mingw32.h: Add builtin macro and default libraries for mcfgthread when thread model is `mcf` gcc/ChangeLog: * config.gcc: Include 'i386/mingw-mcfgthread.h' when thread model is `mcf` * configure.ac: Recognize `mcf` as a valid thread model * configure: Regenerate libatomic/ChangeLog: * configure.tgt: Add new case for `mcf` thread model libgcc/ChangeLog: * config.host: Add new cases for `mcf` thread model * config/i386/gthr-mcf.h: New file * config/i386/t-mingw-mcfgthread: New file * config/i386/t-slibgcc-cygming: Add mcfgthread for libgcc DLL * configure: Regenerate libstdc++-v3/ChangeLog: * libsupc++/atexit_thread.cc (__cxa_thread_atexit): Use implementation from mcfgthread if available * libsupc++/guard.cc (__cxa_guard_acquire, __cxa_guard_release, __cxa_guard_abort): Use implementations from mcfgthread if available * configure: Regenerate --- config/gthr.m4 | 1 + gcc/config.gcc | 3 +++ gcc/config/i386/mingw-mcfgthread.h | 1 + gcc/config/i386/mingw32.h | 13 ++++++++++- gcc/configure | 2 +- gcc/configure.ac | 2 +- libatomic/configure.tgt | 2 +- libgcc/config.host | 6 +++++ libgcc/config/i386/gthr-mcf.h | 1 + libgcc/config/i386/t-mingw-mcfgthread | 1 + libgcc/config/i386/t-slibgcc-cygming | 6 ++++- libgcc/configure | 1 + libstdc++-v3/configure | 13 ++++++----- libstdc++-v3/libsupc++/atexit_thread.cc | 20 ++++++++++++++++ libstdc++-v3/libsupc++/guard.cc | 31 +++++++++++++++++++++++++ 15 files changed, 92 insertions(+), 11 deletions(-) create mode 100644 gcc/config/i386/mingw-mcfgthread.h create mode 100644 libgcc/config/i386/gthr-mcf.h create mode 100644 libgcc/config/i386/t-mingw-mcfgthread diff --git a/config/gthr.m4 b/config/gthr.m4 index 4b937306ad08..11996247f150 100644 --- a/config/gthr.m4 +++ b/config/gthr.m4 @@ -22,6 +22,7 @@ case $1 in tpf) thread_header=config/s390/gthr-tpf.h ;; vxworks) thread_header=config/gthr-vxworks.h ;; win32) thread_header=config/i386/gthr-win32.h ;; + mcf) thread_header=config/i386/gthr-mcf.h ;; esac AC_SUBST(thread_header) ]) diff --git a/gcc/config.gcc b/gcc/config.gcc index eec544ff1bac..1f6adea1ab9b 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -2091,6 +2091,9 @@ i[34567]86-*-mingw* | x86_64-*-mingw*) if test x$enable_threads = xposix ; then tm_file="${tm_file} i386/mingw-pthread.h" fi + if test x$enable_threads = xmcf ; then + tm_file="${tm_file} i386/mingw-mcfgthread.h" + fi tm_file="${tm_file} i386/mingw32.h" # This makes the logic if mingw's or the w64 feature set has to be used case ${target} in diff --git a/gcc/config/i386/mingw-mcfgthread.h b/gcc/config/i386/mingw-mcfgthread.h new file mode 100644 index 000000000000..7d4eda3ed494 --- /dev/null +++ b/gcc/config/i386/mingw-mcfgthread.h @@ -0,0 +1 @@ +#define TARGET_USING_MCFGTHREAD 1 diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h index d3ca0cd0279d..b5f31c3da0ac 100644 --- a/gcc/config/i386/mingw32.h +++ b/gcc/config/i386/mingw32.h @@ -32,6 +32,10 @@ along with GCC; see the file COPYING3. If not see | MASK_STACK_PROBE | MASK_ALIGN_DOUBLE \ | MASK_MS_BITFIELD_LAYOUT) +#ifndef TARGET_USING_MCFGTHREAD +#define TARGET_USING_MCFGTHREAD 0 +#endif + /* See i386/crtdll.h for an alternative definition. _INTEGRAL_MAX_BITS is for compatibility with native compiler. */ #define EXTRA_OS_CPP_BUILTINS() \ @@ -50,6 +54,8 @@ along with GCC; see the file COPYING3. If not see builtin_define_std ("WIN64"); \ builtin_define ("_WIN64"); \ } \ + if (TARGET_USING_MCFGTHREAD) \ + builtin_define ("__USING_MCFGTHREAD__"); \ } \ while (0) @@ -181,11 +187,16 @@ along with GCC; see the file COPYING3. If not see #else #define SHARED_LIBGCC_SPEC " -lgcc " #endif +#if TARGET_USING_MCFGTHREAD +#define MCFGTHREAD_SPEC " -lmcfgthread -lkernel32 -lntdll " +#else +#define MCFGTHREAD_SPEC "" +#endif #undef REAL_LIBGCC_SPEC #define REAL_LIBGCC_SPEC \ "%{mthreads:-lmingwthrd} -lmingw32 \ " SHARED_LIBGCC_SPEC " \ - -lmoldname -lmingwex -lmsvcrt -lkernel32" + -lmoldname -lmingwex -lmsvcrt -lkernel32 " MCFGTHREAD_SPEC #undef STARTFILE_SPEC #define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \ diff --git a/gcc/configure b/gcc/configure index b512580414a6..421093f5868c 100755 --- a/gcc/configure +++ b/gcc/configure @@ -12900,7 +12900,7 @@ case ${enable_threads} in target_thread_file='single' ;; aix | dce | lynx | mipssde | posix | rtems | \ - single | tpf | vxworks | win32) + single | tpf | vxworks | win32 | mcf) target_thread_file=${enable_threads} ;; *) diff --git a/gcc/configure.ac b/gcc/configure.ac index e48fcbfe18ea..e1ef2ecf0267 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1991,7 +1991,7 @@ case ${enable_threads} in target_thread_file='single' ;; aix | dce | lynx | mipssde | posix | rtems | \ - single | tpf | vxworks | win32) + single | tpf | vxworks | win32 | mcf) target_thread_file=${enable_threads} ;; *) diff --git a/libatomic/configure.tgt b/libatomic/configure.tgt index 33f8c91ce771..86a59475b6e7 100644 --- a/libatomic/configure.tgt +++ b/libatomic/configure.tgt @@ -159,7 +159,7 @@ case "${target}" in *-*-mingw*) # OS support for atomic primitives. case ${target_thread_file} in - win32) + win32 | mcf) config_path="${config_path} mingw" ;; posix) diff --git a/libgcc/config.host b/libgcc/config.host index 9dcc2538dc86..44a8218a31d3 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -825,6 +825,9 @@ i[34567]86-*-mingw*) posix) tmake_file="i386/t-mingw-pthread $tmake_file" ;; + mcf) + tmake_file="i386/t-mingw-mcfgthread $tmake_file" + ;; esac # This has to match the logic for DWARF2_UNWIND_INFO in gcc/config/i386/cygming.h if test x$ac_cv_sjlj_exceptions = xyes; then @@ -849,6 +852,9 @@ x86_64-*-mingw*) posix) tmake_file="i386/t-mingw-pthread $tmake_file" ;; + mcf) + tmake_file="i386/t-mingw-mcfgthread $tmake_file" + ;; esac # This has to match the logic for DWARF2_UNWIND_INFO in gcc/config/i386/cygming.h if test x$ac_cv_sjlj_exceptions = xyes; then diff --git a/libgcc/config/i386/gthr-mcf.h b/libgcc/config/i386/gthr-mcf.h new file mode 100644 index 000000000000..58131bb7ca92 --- /dev/null +++ b/libgcc/config/i386/gthr-mcf.h @@ -0,0 +1 @@ +#include <mcfgthread/gthr.h> diff --git a/libgcc/config/i386/t-mingw-mcfgthread b/libgcc/config/i386/t-mingw-mcfgthread new file mode 100644 index 000000000000..c5b817f09b71 --- /dev/null +++ b/libgcc/config/i386/t-mingw-mcfgthread @@ -0,0 +1 @@ +SHLIB_MCFGTHREAD_LIBS = -lmcfgthread -lkernel32 -lntdll diff --git a/libgcc/config/i386/t-slibgcc-cygming b/libgcc/config/i386/t-slibgcc-cygming index 6236c78e4668..6871498cf60e 100644 --- a/libgcc/config/i386/t-slibgcc-cygming +++ b/libgcc/config/i386/t-slibgcc-cygming @@ -27,6 +27,9 @@ endif ifndef SHLIB_PTHREAD_LDFLAG SHLIB_PTHREAD_LDFLAG = endif +ifndef SHLIB_MCFGTHREAD_LIBS +SHLIB_MCFGTHREAD_LIBS = +endif SHLIB_LINK = $(LN_S) -f $(SHLIB_MAP) $(SHLIB_MAP).def && \ if [ ! -d $(SHLIB_DIR) ]; then \ @@ -37,7 +40,8 @@ SHLIB_LINK = $(LN_S) -f $(SHLIB_MAP) $(SHLIB_MAP).def && \ $(SHLIB_MAP).def \ -Wl,--out-implib,$(SHLIB_DIR)/$(SHLIB_IMPLIB).tmp \ -o $(SHLIB_DIR)/$(SHLIB_SONAME).tmp @multilib_flags@ \ - $(SHLIB_OBJS) ${SHLIB_PTHREAD_LDFLAG} $(SHLIB_LC) && \ + $(SHLIB_OBJS) ${SHLIB_PTHREAD_LDFLAG} $(SHLIB_LC) \ + $(SHLIB_MCFGTHREAD_LIBS) && \ if [ -f $(SHLIB_DIR)/$(SHLIB_SONAME) ]; then \ mv -f $(SHLIB_DIR)/$(SHLIB_SONAME) \ $(SHLIB_DIR)/$(SHLIB_SONAME).backup; \ diff --git a/libgcc/configure b/libgcc/configure index 61f3ace2891c..be5d45f1755c 100755 --- a/libgcc/configure +++ b/libgcc/configure @@ -5699,6 +5699,7 @@ case $target_thread_file in tpf) thread_header=config/s390/gthr-tpf.h ;; vxworks) thread_header=config/gthr-vxworks.h ;; win32) thread_header=config/i386/gthr-win32.h ;; + mcf) thread_header=config/i386/gthr-mcf.h ;; esac diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 7ead77a5c800..08b0c4e7fcfd 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -15802,6 +15802,7 @@ case $target_thread_file in tpf) thread_header=config/s390/gthr-tpf.h ;; vxworks) thread_header=config/gthr-vxworks.h ;; win32) thread_header=config/i386/gthr-win32.h ;; + mcf) thread_header=config/i386/gthr-mcf.h ;; esac @@ -16009,7 +16010,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; } # Fake what AC_TRY_COMPILE does. cat > conftest.$ac_ext << EOF -#line 16012 "configure" +#line 16013 "configure" int main() { typedef bool atomic_type; @@ -16044,7 +16045,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 16047 "configure" +#line 16048 "configure" int main() { typedef short atomic_type; @@ -16079,7 +16080,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 16082 "configure" +#line 16083 "configure" int main() { // NB: _Atomic_word not necessarily int. @@ -16115,7 +16116,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 16118 "configure" +#line 16119 "configure" int main() { typedef long long atomic_type; @@ -16271,7 +16272,7 @@ $as_echo "mutex" >&6; } # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 16274 "configure" +#line 16275 "configure" int main() { _Decimal32 d1; @@ -16313,7 +16314,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 16316 "configure" +#line 16317 "configure" template<typename T1, typename T2> struct same { typedef T2 type; }; diff --git a/libstdc++-v3/libsupc++/atexit_thread.cc b/libstdc++-v3/libsupc++/atexit_thread.cc index a2693d0424e1..2f936ab02ce2 100644 --- a/libstdc++-v3/libsupc++/atexit_thread.cc +++ b/libstdc++-v3/libsupc++/atexit_thread.cc @@ -25,6 +25,24 @@ #include <cstdlib> #include <new> #include "bits/gthr.h" + +#ifdef __USING_MCFGTHREAD__ + +#include <mcfgthread/cxa.h> + +namespace __cxxabiv1 { + +extern "C" int +__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *), + void *obj, void *dso_handle) _GLIBCXX_NOTHROW +{ + return __MCF_cxa_thread_atexit (dtor, obj, dso_handle); +} + +} // namespace __cxxabiv1 + +#else // __USING_MCFGTHREAD__ + #ifdef _GLIBCXX_THREAD_ATEXIT_WIN32 #define WIN32_LEAN_AND_MEAN #include <windows.h> @@ -173,3 +191,5 @@ __cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *), } #endif /* _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */ + +#endif // __USING_MCFGTHREAD__ diff --git a/libstdc++-v3/libsupc++/guard.cc b/libstdc++-v3/libsupc++/guard.cc index abb57117cdfd..0f81a22c6845 100644 --- a/libstdc++-v3/libsupc++/guard.cc +++ b/libstdc++-v3/libsupc++/guard.cc @@ -28,6 +28,35 @@ #include <cxxabi.h> #include <exception> #include <new> + +#ifdef __USING_MCFGTHREAD__ + +#include <mcfgthread/cxa.h> + +namespace __cxxabiv1 { + +extern "C" int +__cxa_guard_acquire (__guard* g) _GLIBCXX_NOTHROW + { + return __MCF_cxa_guard_acquire(g); + } + +extern "C" void +__cxa_guard_release (__guard* g) _GLIBCXX_NOTHROW + { + __MCF_cxa_guard_release(g); + } + +extern "C" void +__cxa_guard_abort (__guard* g) _GLIBCXX_NOTHROW + { + __MCF_cxa_guard_abort(g); + } + +} // namespace __cxxabiv1 + +#else // __USING_MCFGTHREAD__ + #include <ext/atomicity.h> #include <ext/concurrence.h> #include <bits/atomic_lockfree_defines.h> @@ -458,3 +487,5 @@ namespace __cxxabiv1 #endif } } + +#endif // __USING_MCFGTHREAD__
On 10/11/22 13:22, LIU Hao wrote: > 在 2022-10-10 23:56, LIU Hao 写道: >> 在 2022-10-04 20:44, LIU Hao 写道: >>> Attached are revised patches. These are exported from trunk. >>> >> >> Revised further. The patch for libgfortran has been committed to trunk >> today, so I include only the other two. >> >> * In the second patch, a space character has been inserted after >> `(int)` for clearness. >> >> * The macro controlling how to build GCC itself has been renamed to >> `TARGET_USING_MCFGTHREAD` for consistency. >> >> * Checks against `TARGET_USING_MCFGTHREAD` have been updated in a >> more friendly way. >> >> * When not using mcfgthread, NTDLL is no longer a default library. >> Although all recent Windows versions are based on the NT kernel, >> there could still be people who want to target 9x or CE; thus >> NTDLL is only added when it is potentially necessary, for example >> when linking against the static libgcc. >> >> > > Attached is the (previous) third patch, with configure scripts regenerated. > > Any more comments?
On 10/14/22 09:39, Jonathan Yong wrote: > On 10/11/22 13:22, LIU Hao wrote: >> 在 2022-10-10 23:56, LIU Hao 写道: >>> 在 2022-10-04 20:44, LIU Hao 写道: >>>> Attached are revised patches. These are exported from trunk. >>>> >>> >>> Revised further. The patch for libgfortran has been committed to >>> trunk today, so I include only the other two. >>> >>> * In the second patch, a space character has been inserted after >>> `(int)` for clearness. >>> >>> * The macro controlling how to build GCC itself has been renamed to >>> `TARGET_USING_MCFGTHREAD` for consistency. >>> >>> * Checks against `TARGET_USING_MCFGTHREAD` have been updated in a >>> more friendly way. >>> >>> * When not using mcfgthread, NTDLL is no longer a default library. >>> Although all recent Windows versions are based on the NT kernel, >>> there could still be people who want to target 9x or CE; thus >>> NTDLL is only added when it is potentially necessary, for example >>> when linking against the static libgcc. >>> >>> >> >> Attached is the (previous) third patch, with configure scripts >> regenerated. >> >> > > Any more comments? Just pushed to master branch.
On Wed, 19 Oct 2022 at 15:56, Jonathan Yong via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
> Just pushed to master branch.
Wouldn't you want to cut down on the libs respectively refine the
order of the libs, though?
You've now got:
+#define MCFGTHREAD_SPEC " -lmcfgthread -lkernel32 -lntdll "
+#else
+#define MCFGTHREAD_SPEC ""
+#endif
#undef REAL_LIBGCC_SPEC
#define REAL_LIBGCC_SPEC \
"%{mthreads:-lmingwthrd} -lmingw32 \
" SHARED_LIBGCC_SPEC " \
- -lmoldname -lmingwex -lmsvcrt -lkernel32"
+ -lmoldname -lmingwex -lmsvcrt -lkernel32 " MCFGTHREAD_SPEC
which has kernel32 twice, which might not be ideal for the speed of linking?
I'm not familiar with the content of ntdll so cannot judge if you'd put that in
MCFGTHREAD_SPEC and drop kernel32 there, though, and put the whole
MCFG spec simply before the kernel32 in the REAL_LIBGCC_SPEC.
i.e.
+#define MCFGTHREAD_SPEC " -lmcfgthread -lntdll "
...
+ -lmoldname -lmingwex -lmsvcrt " MCFGTHREAD_SPEC " -lkernel32 "
I hope this is constructive.
thanks,
在 2022/10/20 03:53, Bernhard Reutner-Fischer 写道: > > which has kernel32 twice, which might not be ideal for the speed of linking? > I'm not familiar with the content of ntdll so cannot judge if you'd put that in > MCFGTHREAD_SPEC and drop kernel32 there, though, and put the whole > MCFG spec simply before the kernel32 in the REAL_LIBGCC_SPEC. > > i.e. > +#define MCFGTHREAD_SPEC " -lmcfgthread -lntdll " > ... > + -lmoldname -lmingwex -lmsvcrt " MCFGTHREAD_SPEC " -lkernel32 " > > I hope this is constructive. > thanks, NTDLL is the user-mode syscall library i.e. it mainly provides syscalls as functions. Putting `-lmcfgthread` before `-lkernel32` was what I did in the beginning. However, I had an impression that NTDLL and KERNEL32 may both export some functions (I believe this is no longer the case now). Since MSVCRT in mingw-w64 is not a 'pure' import library and contains some functions that we implement on top of KERNEL32, the ideal solution would be ``` #define MCFGTHREAD_SPEC " -lmcfgthread " #define MCFGTHREAD_NTDLL_SPEC " -lntdll " ... -lmsvcrt " MCFGTHREAD_SPEC " -lkernel32 " MCFGTHREAD_NTDLL_SPEC ``` (NTDLL is only necessary when linking against the shared library.) The committed patch inserted MCFGTHREAD after KERNEL32 for simplicity, but if you do think we had better not repeat KERNEL32 twice, I can propose another patch. -- Best regards, LIU Hao
How does this compare with Eric B's proposal at https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? It would be good if we can accept one of them for GCC 13, but I don't know Windows well enough to determine which is better. On Sat, 1 Oct 2022 at 19:35, LIU Hao via Libstdc++ <libstdc++@gcc.gnu.org> wrote: > > Greetings. > > After some years I think it's time to put on this topic again. > > This patch series is an attempt to add a new thread model basing on the mcfgthread library > (https://github.com/lhmouse/mcfgthread), which provides efficient implementations of mutexes, > condition variables, once flags, etc. for native Windows. > > > The first patch is necessary because somewhere in libgfortran, `pthread_t` is referenced. If the > thread model is not `posix`, it fails to compile. > > The second patch implements `std::thread::hardware_concurrency()` for non-posix thread models. This > would also work for the win32 thread model if `std::thread` would be supported in the future. > > The third patch adds the `mcf` thread model for GCC and its libraries. A new builtin macro > `__USING_MCFGTHREAD__` is added to indicate whether this new thread model is in effect. This grants > `std::mutex` and `std::once_flag` trivial destructors; `std::condition_variable` is a bit > unfortunate because its destructor is non-trivial, but in reality no cleanup is performed. > > > I have been bootstrapping GCC with the MCF thread model for more than five years. At the moment, C, > C++ and Fortran are supported. Ada is untested because I don't know how to bootstrap it. Objective-C > is not supported, because threading APIs for libobjc have not been implemented. > > Please review. If there are any changes that I have to make, let me know. > > > -- > Best regards, > LIU Hao
On 2022-10-21 09:58, Jonathan Wakely via Libstdc++ wrote: > How does this compare with Eric B's proposal at > https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? > > It would be good if we can accept one of them for GCC 13, but I don't > know Windows well enough to determine which is better. I had the same question... I would like to understand what is the difference? Moreover I would like to understand what is the difference with the already added support for the winpthreads library? @LIU Hao, could you explain please? best! > On Sat, 1 Oct 2022 at 19:35, LIU Hao via Libstdc++ > <libstdc++@gcc.gnu.org> wrote: >> >> Greetings. >> >> After some years I think it's time to put on this topic again. >> >> This patch series is an attempt to add a new thread model basing on >> the mcfgthread library >> (https://github.com/lhmouse/mcfgthread), which provides efficient >> implementations of mutexes, >> condition variables, once flags, etc. for native Windows. >> >> >> The first patch is necessary because somewhere in libgfortran, >> `pthread_t` is referenced. If the >> thread model is not `posix`, it fails to compile. >> >> The second patch implements `std::thread::hardware_concurrency()` for >> non-posix thread models. This >> would also work for the win32 thread model if `std::thread` would be >> supported in the future. >> >> The third patch adds the `mcf` thread model for GCC and its libraries. >> A new builtin macro >> `__USING_MCFGTHREAD__` is added to indicate whether this new thread >> model is in effect. This grants >> `std::mutex` and `std::once_flag` trivial destructors; >> `std::condition_variable` is a bit >> unfortunate because its destructor is non-trivial, but in reality no >> cleanup is performed. >> >> >> I have been bootstrapping GCC with the MCF thread model for more than >> five years. At the moment, C, >> C++ and Fortran are supported. Ada is untested because I don't know >> how to bootstrap it. Objective-C >> is not supported, because threading APIs for libobjc have not been >> implemented. >> >> Please review. If there are any changes that I have to make, let me >> know. >> >> >> -- >> Best regards, >> LIU Hao
On Fri, 21 Oct 2022 at 11:10, i.nixman--- via Libstdc++ <libstdc++@gcc.gnu.org> wrote: > > On 2022-10-21 09:58, Jonathan Wakely via Libstdc++ wrote: > > How does this compare with Eric B's proposal at > > https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? > > > > It would be good if we can accept one of them for GCC 13, but I don't > > know Windows well enough to determine which is better. > > I had the same question... > I would like to understand what is the difference? > Moreover I would like to understand what is the difference with the > already added support for the winpthreads library? Well that one's easy, you don't need to use winpthreads if there's a native thread model, so you don't need to go through two abstraction layers (gthreads and winpthreads), just one (gthreads). The benefits of using the native thread model for the OS seems obvious. The question is which patch to do that should we use.
On 2022-10-21 10:48, Jonathan Wakely wrote: > On Fri, 21 Oct 2022 at 11:10, i.nixman--- via Libstdc++ > <libstdc++@gcc.gnu.org> wrote: >> >> On 2022-10-21 09:58, Jonathan Wakely via Libstdc++ wrote: >> > How does this compare with Eric B's proposal at >> > https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? >> > >> > It would be good if we can accept one of them for GCC 13, but I don't >> > know Windows well enough to determine which is better. >> >> I had the same question... >> I would like to understand what is the difference? >> Moreover I would like to understand what is the difference with the >> already added support for the winpthreads library? > > Well that one's easy, you don't need to use winpthreads if there's a > native thread model, so you don't need to go through two abstraction > layers (gthreads and winpthreads), just one (gthreads). sure! nevertheless I would like to understand why we have two separate implementations (winthreads and mcfgthread)? what is the difference? best!
在 2022/10/21 18:09, i.nixman@autistici.org 写道: > On 2022-10-21 09:58, Jonathan Wakely via Libstdc++ wrote: >> How does this compare with Eric B's proposal at >> https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? >> >> It would be good if we can accept one of them for GCC 13, but I don't >> know Windows well enough to determine which is better. > > I had the same question... > I would like to understand what is the difference? > Moreover I would like to understand what is the difference with the already added support for the > winpthreads library? > > @LIU Hao, could you explain please? > > > Thank you for your interest. I'm glad to make an introduction of it. I have read this patch before. Let's take the mutex as an example: There are a lot of ways to implement a mutex on Windows. Basically, a non-recursive mutex can be implemented with an atomic counter + a binary semaphore / auto-reset event. This proposed patch contains a `__gthr_win32_CRITICAL_SECTION` definition that I think is a duplicate of the internal `CRITICAL_SECTION` structure, so should also work the same way as it. The problem about this approach is that, semaphores are valuable kernel objects, and the maximum number of HANDLEs that a process can open concurrently has a limit (like FDs on Linux), while 'many critical sections are used only occasionally (or never at all), meaning the auto-reset event often isn’t even necessary' [1], the semaphores are actually allocated on demand. This means that locking can fail. There is a story in article [1] which also explains the origination of keyed events; it's worth reading. And, since Vista we also have native win32 condition variables, also implemented basing on keyed events. The keyed events are undocumented and are only exposed via syscalls. However, as with other documented syscalls, available from Windows Drivers Kit, there are several advantages: * There is a global keyed event, which requires no initialization, but can be utilized by all processes. Basing on that, mcfgthread provides mutexs, condition variables, once flags, etc. that are all one-pointer size structs, consume absolutely no additional resource, allow constexpr initialization, and require no cleanup, much like on Linux. * The wait syscalls take a 64-bit integer, whose positive value denotes the number of 10^-7 seconds since 1600-01-01 00:00:00 Z, and whose negative value denotes a relative timeout. Hence it's much more simpler to implement `__gthread_mutex_timedlock()` and `__gthread_cond_wait()` which take absolute timeouts. On the other hand, Win32 APIs generally take a 32-bit relative timeout in milliseconds, which not only requires translation from an absolute timepoint argument, but can also easily get overflown. * Building mutexes on top of syscalls allows a better designed algorithm [2], and sometimes it can even outperform native `SRWLOCK`s [3]. * mcfgthread also provides standard-conforming `__cxa_atexit()` and `__cxa_thread_atexit()` functions, for working around some strange, weird, and broken behaviors [4][5][6]. On Linux it's glibc that provides them, so this as a whole requires a little modification in mingw-w64. I am working on it however; hopefully we can land it soon. [1] http://joeduffyblog.com/2006/11/28/windows-keyed-events-critical-sections-and-new-vista-synchronization-features/ [2] https://github.com/lhmouse/mcfgthread/blob/master/MUTEX.md [3] https://github.com/lhmouse/mcfgthread#benchmarking [4] https://sourceforge.net/p/mingw-w64/mailman/message/37268447/ [5] https://reviews.llvm.org/D102944 [6] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80816 -- Best regards, LIU Hao
> How does this compare with Eric B's proposal at > https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? My proposal was to reimplement (and extend) the native thread model (win32) instead of adding a new one, the advantage being that you don't need an extra threading layer between GCC and Windows.
On 2022-10-21 11:36, LIU Hao wrote: > 在 2022/10/21 18:09, i.nixman@autistici.org 写道: >> On 2022-10-21 09:58, Jonathan Wakely via Libstdc++ wrote: >>> How does this compare with Eric B's proposal at >>> https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? >>> >>> It would be good if we can accept one of them for GCC 13, but I don't >>> know Windows well enough to determine which is better. >> >> I had the same question... >> I would like to understand what is the difference? >> Moreover I would like to understand what is the difference with the >> already added support for the winpthreads library? >> >> @LIU Hao, could you explain please? >> >> >> > > Thank you for your interest. I'm glad to make an introduction of it. > > > I have read this patch before. Let's take the mutex as an example: > > There are a lot of ways to implement a mutex on Windows. Basically, a > non-recursive mutex can be implemented with an atomic counter + a > binary semaphore / auto-reset event. This proposed patch contains a > `__gthr_win32_CRITICAL_SECTION` definition that I think is a duplicate > of the internal `CRITICAL_SECTION` structure, so should also work the > same way as it. > > The problem about this approach is that, semaphores are valuable > kernel objects, and the maximum number of HANDLEs that a process can > open concurrently has a limit (like FDs on Linux), while 'many > critical sections are used only occasionally (or never at all), > meaning the auto-reset event often isn’t even necessary' [1], the > semaphores are actually allocated on demand. This means that locking > can fail. There is a story in article [1] which also explains the > origination of keyed events; it's worth reading. > > And, since Vista we also have native win32 condition variables, also > implemented basing on keyed events. > > > The keyed events are undocumented and are only exposed via syscalls. > However, as with other documented syscalls, available from Windows > Drivers Kit, there are several advantages: > > * There is a global keyed event, which requires no initialization, > but > can be utilized by all processes. Basing on that, mcfgthread > provides > mutexs, condition variables, once flags, etc. that are all > one-pointer > size structs, consume absolutely no additional resource, allow > constexpr initialization, and require no cleanup, much like on > Linux. > > * The wait syscalls take a 64-bit integer, whose positive value > denotes > the number of 10^-7 seconds since 1600-01-01 00:00:00 Z, and whose > negative value denotes a relative timeout. Hence it's much more > simpler > to implement `__gthread_mutex_timedlock()` and > `__gthread_cond_wait()` > which take absolute timeouts. On the other hand, Win32 APIs > generally > take a 32-bit relative timeout in milliseconds, which not only > requires > translation from an absolute timepoint argument, but can also > easily > get overflown. > > * Building mutexes on top of syscalls allows a better designed > algorithm > [2], and sometimes it can even outperform native `SRWLOCK`s [3]. > > * mcfgthread also provides standard-conforming `__cxa_atexit()` and > `__cxa_thread_atexit()` functions, for working around some strange, > weird, and broken behaviors [4][5][6]. On Linux it's glibc that > provides them, so this as a whole requires a little modification in > mingw-w64. I am working on it however; hopefully we can land it > soon. > > thank you LIU Hao for the explanation! I have a questions: 1) wouldn't it be logical not to write yet another implementation of pthreads-wor-windows, but to make changes to the winpthreads library because it's already supported by GCC? (maybe I don’t know about some reasons why it wasn’t done ...) It seems to me the ideal and logical option is to make your implementation part of GCC, as suggested by Eric B. the advantages are as follows: 1) we will get a high-quality native implementation. 2) there is no need to add another thread model for GCC. 3) with dynamic linking there is no need to ship another dll with the program. (Windows users really don't like this =)) best! > [1] > http://joeduffyblog.com/2006/11/28/windows-keyed-events-critical-sections-and-new-vista-synchronization-features/ > > [2] https://github.com/lhmouse/mcfgthread/blob/master/MUTEX.md > [3] https://github.com/lhmouse/mcfgthread#benchmarking > > [4] https://sourceforge.net/p/mingw-w64/mailman/message/37268447/ > [5] https://reviews.llvm.org/D102944 > [6] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80816
On 2022-10-21 11:44, Eric Botcazou via Libstdc++ wrote: >> How does this compare with Eric B's proposal at >> https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? > > My proposal was to reimplement (and extend) the native thread model > (win32) > instead of adding a new one, the advantage being that you don't need an > extra > threading layer between GCC and Windows. I agree! best!
> The problem about this approach is that, semaphores are valuable kernel objects, and the maximum > number of HANDLEs that a process can open concurrently has a limit (like FDs on Linux), while 'many > critical sections are used only occasionally (or never at all), meaning the auto-reset event often > isn’t even necessary' [1], the semaphores are actually allocated on demand. This means that locking > can fail. There is a story in article [1] which also explains the origination of keyed events; it's > worth reading. This is not true for past 15 years, CRITICAL_SECTIONS use something like RtlWaitOnAddress (an equivalent of futexes) since Vista, see Wine implementation for details: https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/sync.c#L190 Jacek
在 2022/10/21 19:54, i.nixman@autistici.org 写道: > > I have a questions: > 1) wouldn't it be logical not to write yet another implementation of pthreads-wor-windows, but to > make changes to the winpthreads library because it's already supported by GCC? (maybe I don’t know > about some reasons why it wasn’t done ...) > While it is possible to rebuild winpthreads from scratch, I don't think it's worth: * There are many POSIX facilities that we don't support: rwlock, cancellation, signals, etc. * GCC can choose to implement `std::thread` etc. on C11 <threads.h>, which libcxx already has, but I haven't tested it. (mcfgthread also has a C11 header, but not one for libcxx.) > It seems to me the ideal and logical option is to make your implementation part of GCC, as suggested > by Eric B. > the advantages are as follows: > 1) we will get a high-quality native implementation. > 2) there is no need to add another thread model for GCC. > 3) with dynamic linking there is no need to ship another dll with the program. (Windows users really > don't like this =)) > Jacek Caban, who is also a mingw-w64 developer, expressed the same idea a few days ago. While integrating mcfgthread into gcc is practically possible, my concerns are: * GCC never provides a threading library. It always depends on glibc, musl, win32 APIs, winpthreads, etc. * Tampering with the win32 thread model in a dramatic way is not acceptiable due to backwards compatibility. There are distributions that have win32 as the default thread model, such as Debian. * I personally need more control for future development, for example, re-implement pthread or adding libcxx support, which doesn't fit in GCC. -- Best regards, LIU Hao
在 2022/10/21 20:13, Jacek Caban 写道: > > This is not true for past 15 years, CRITICAL_SECTIONS use something like RtlWaitOnAddress (an equivalent of futexes) since Vista, see Wine implementation for details: > https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/sync.c#L190 > > Ah Jacek, nice to see you here. I haven't dug into this too much, though. From my limited knowledge (mostly from reading disassembly) now CRITICAL_SECTION uses `NtWaitForAlertByThreadId` (and no longer keyed events or semaphores). As with `WaitOnAddress()`, there seems to be some global data structure, protected by a spin lock. It's just another undocumented syscall. Keyed events are still functional. -- Best regards, LIU Hao
On 2022-10-21 11:44, Eric Botcazou via Libstdc++ wrote: >>>/How does this compare with Eric B's proposal at />>>/https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? />>//>>/My proposal was to reimplement (and extend) the native thread model />>/(win32) />>/instead of adding a new one, the advantage being that you don't need an />>/extra />/> threading layer between GCC and Windows. /> > I agree! I agree as well and I expressed that on mingw-w64 ML when the patch was introduced [1]. My main concern with the new threading model is that instead of solving root of the problem, it introduces more fragmentation with no clear benefit. On top of that, mcfgthread library is way more invasive than it needs to be. It requires maintaining per-thread struct and reimplements a number of things instead of leveraging OS capabilities. Author also plans to make invasive changes to mingw-w64-crt, which go against it current approach of being agnostic to threading model. Jacek [1] https://sourceforge.net/p/mingw-w64/mailman/message/37719727/
On 2022-10-21 12:19, LIU Hao wrote: > 在 2022/10/21 19:54, i.nixman@autistici.org 写道: <skip> > Jacek Caban, who is also a mingw-w64 developer, expressed the same > idea a few days ago. > > While integrating mcfgthread into gcc is practically possible, my > concerns are: > > * GCC never provides a threading library. It always depends on glibc, > musl, win32 APIs, winpthreads, etc. I think you didn't understand me. I mean not to integrate your library into GCC as real separate library. I mean to do changes on config/i386/gthr-win32.h+config/i386/gthr-win32.c+config/i386/gthr-win32-cond.c etc using your code to have an implementation of everything needed for C/C++ threads on Windows. > * Tampering with the win32 thread model in a dramatic way is not > acceptiable due to backwards compatibility. There are distributions > that have win32 as the default thread model, such as Debian. > > * I personally need more control for future development, for example, > re-implement pthread or adding libcxx support, which doesn't fit in > GCC. got it... anyway it seems logical to me the way I proposed :) best!
On 10/21/22 14:29, LIU Hao wrote: > 在 2022/10/21 20:13, Jacek Caban 写道: >> >> This is not true for past 15 years, CRITICAL_SECTIONS use something >> like RtlWaitOnAddress (an equivalent of futexes) since Vista, see >> Wine implementation for details: >> https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/sync.c#L190 >> >> > > Ah Jacek, nice to see you here. > > I haven't dug into this too much, though. From my limited knowledge > (mostly from reading disassembly) now CRITICAL_SECTION uses > `NtWaitForAlertByThreadId` (and no longer keyed events or semaphores). > As with `WaitOnAddress()`, there seems to be some global data > structure, protected by a spin lock. It's just another undocumented > syscall. Keyed events are still functional. NtWaitForAlertByThreadId() is an underlying syscall that's used by WaitOnAddress(). Anyway, you don't need to worry about that if you just use public CRITICAL_SECTION APIs. Jacek
On Fri, Oct 21, 2022 at 8:33 AM Jacek Caban via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > On 2022-10-21 11:44, Eric Botcazou via Libstdc++ wrote: > >>>/How does this compare with Eric B's proposal at />>>/https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? />>//>>/My proposal was to reimplement (and extend) the native thread model />>/(win32) />>/instead of adding a new one, the advantage being that you don't need an />>/extra />/> threading layer between GCC and Windows. /> > > I agree! > > I agree as well and I expressed that on mingw-w64 ML when the patch was introduced [1]. My main concern with the new threading model is that instead of solving root of the problem, it introduces more fragmentation with no clear benefit. > > On top of that, mcfgthread library is way more invasive than it needs to be. It requires maintaining per-thread struct and reimplements a number of things instead of leveraging OS capabilities. Author also plans to make invasive changes to mingw-w64-crt, which go against it current approach of being agnostic to threading model. > > Jacek > > [1] https://sourceforge.net/p/mingw-w64/mailman/message/37719727/ FWIW, Eric's proposal makes more practical sense. Right now, people ship many permutations of the compiler: x86, x64, x86+x64 dw2, sjlj (rarely), seh win32, posix+winpthread This is not sustainable, and certain combinations are largely incompatible (which makes for instance providing a windows release of MySpecialLibrary.dll confusing). We used to have a matrix of combinations on the website, but I see that that's no longer present. In any case, it took a long time for sjlj to fall out of vogue (maybe old habits die hard?). That implies, to me, that winpthreads similarly won't be deprecated, it'll just be yet another set of archives to download and confuse people with.
在 2022/10/21 20:34, i.nixman@autistici.org 写道: > > got it... > anyway it seems logical to me the way I proposed :) > > Below is a message forwarded from mingw-w64-public, elaborating the necessity of a new thread model. As there are objections from other mingw-w64 developers, I am putting those patches against mingw-w64-crt on hold for now. Despite that, all threading facilities - mutexes, condition variables, once flags, etc. - are still fully functional within the mcf thread model. In addition, I will keep maintaining my personal builds (from GCC 12 release branch) with these patches at https://gcc-mcf.lhmouse.com/. -------- Forwarded Message -------- 在 2022/10/23 18:06, Jacek Caban 写道: > > Please, let's not do that. It's possible to fix existing implementations, we don't need to make > things more complicated than they are. > Okay okay, I think I have to compose a thorough list of problems that we are facing at the moment, and had better have a permalink to the mailing list archive that I can reference elsewhere. I have been tired of repeating the same grounds of arguments again and again: 1. In a DLL, destructors of static objects and callbacks that are registered with `atexit()`, are executed by `LdrShutdownProcess()`, after all the other thread have been terminated `ZwTerminateProcessO(NULL, status)`. This means that, if another thread has been terminated while holding a mutex, the mutex can never get unlocked. If a destructor attempts to lock the same mutex, deadlocks will occur. Destructors of executables do not suffer from this issue, because they are executed before `RtlExitUserProcess()`. Standard behavior: Static destructors and exit callbacks should be executed while other threads are running. If another thread attempts to access a destroyed object, the behavior is undefined; the user is responsible to prevent this from happening, by joining or suspending it. 2. Following 1, in a DLL, static destructors and exit callbacks are still invoked when `_Exit()` or `quick_exit()` is called. Standard behavior: `_Exit()` should not perform any cleanup; not even open files are flushed. `quick_exit()` shall invoke all quick-exit callbacks in reverse order, then call `_Exit()`. 3. There is a use-after-free bug [1] about thread-local destructors. I suspect this is caused by emutls, because GCC uses `__cxa_thread_atexit()` to register thread-local destructors, which could interleave with `emutls_destroy()`. Standard behavior: This is not allowed to happen. mcfgthread solves this issue by running thread-local destructors and thread-specific key destructors as two separate passes [3]. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80816 [2] https://github.com/gcc-mirror/gcc/blob/f84e4fb44aa26b71fbc64e0532fd24d96e5caa3f/libgcc/emutls.c#L96 [3] https://github.com/lhmouse/mcfgthread/blob/63e034d375caf585e2921cd3455f1048feb2172d/src/xglobals.c#L249 4. In the win32 thread model, thread-specific key destructors are called at process exit [4], after static destructors. Standard behavior: They shall be called only when a thread exits, and the associated thread-specific values are not a null pointer. They shall not be called when a program terminates; instead, users are responsible for deallocating such resources before calling `exit()`. This requirement is missing in POSIX, but formally specified by ISO/IEC 9899:2017, as the 4th paragraph in '7.26.6.1 The tss_create function'. [4] https://github.com/mingw-w64/mingw-w64/blob/d0a034a04d312434b842c4869a8a900568d8db98/mingw-w64-crt/crt/tlsthrd.c#L134 5. Wait operations, of timed mutexes and condition variables, should take absolute time points as `struct timespec`. Standard behavior: Both POSIX and ISO C specifies them as such, while all Windows APIs take relative durations as a 32-bit integer of milliseconds, which can also easily get overflown. -- Best regards, LIU Hao
On 2022-10-21 11:44, Eric Botcazou via Libstdc++ wrote: >> How does this compare with Eric B's proposal at >> https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? > > My proposal was to reimplement (and extend) the native thread model > (win32) > instead of adding a new one, the advantage being that you don't need an > extra > threading layer between GCC and Windows. Hello Eric, could you please refresh/recheck your patch for the current gcc master and solve the objections noted in the thread? is it possible? best!
> could you please refresh/recheck your patch for the current gcc master > and solve the objections noted in the thread? is it possible? I can do the former, but not the latter as my development setup (mostly testing) on Windows has nearly vanished in the meantime. But this rewritten implementation is the one used by the C/C++/Ada compilers from AdaCore.
On 2022-10-24 08:15, Eric Botcazou wrote: >> could you please refresh/recheck your patch for the current gcc master >> and solve the objections noted in the thread? is it possible? > Hi, > I can do the former, but not the latter as my development setup (mostly > testing) on Windows has nearly vanished in the meantime. But this > rewritten > implementation is the one used by the C/C++/Ada compilers from AdaCore. ah, it's great! thank you very much! best!
On 10/24/22 05:40, LIU Hao via Gcc-patches wrote: > 在 2022/10/21 20:34, i.nixman@autistici.org 写道: >> >> got it... >> anyway it seems logical to me the way I proposed :) >> >> > > Below is a message forwarded from mingw-w64-public, elaborating the > necessity of a new thread model. > > As there are objections from other mingw-w64 developers, I am putting > those patches against mingw-w64-crt on hold for now. Despite that, all > threading facilities - mutexes, condition variables, once flags, etc. > - are still fully functional within the mcf thread model. > > In addition, I will keep maintaining my personal builds (from GCC 12 > release branch) with these patches at https://gcc-mcf.lhmouse.com/. > > > -------- Forwarded Message -------- > 在 2022/10/23 18:06, Jacek Caban 写道: > > > > Please, let's not do that. It's possible to fix existing > implementations, we don't need to make > > things more complicated than they are. > > > > Okay okay, I think I have to compose a thorough list of problems that > we are facing at the moment, and had better have a permalink to the > mailing list archive that I can reference elsewhere. I have been tired > of repeating the same grounds of arguments again and again: > > > 1. In a DLL, destructors of static objects and callbacks that are > registered > with `atexit()`, are executed by `LdrShutdownProcess()`, after all > the other > thread have been terminated `ZwTerminateProcessO(NULL, status)`. > This means > that, if another thread has been terminated while holding a mutex, > the mutex > can never get unlocked. If a destructor attempts to lock the same > mutex, > deadlocks will occur. Destructors of executables do not suffer > from this > issue, because they are executed before `RtlExitUserProcess()`. > > Standard behavior: Static destructors and exit callbacks should be > executed > while other threads are running. If another thread attempts to > access a > destroyed object, the behavior is undefined; the user is > responsible to > prevent this from happening, by joining or suspending it. > > > 2. Following 1, in a DLL, static destructors and exit callbacks are still > invoked when `_Exit()` or `quick_exit()` is called. > > Standard behavior: `_Exit()` should not perform any cleanup; not > even open > files are flushed. `quick_exit()` shall invoke all quick-exit > callbacks in > reverse order, then call `_Exit()`. > > > 3. There is a use-after-free bug [1] about thread-local destructors. I > suspect > this is caused by emutls, because GCC uses `__cxa_thread_atexit()` to > register thread-local destructors, which could interleave with > `emutls_destroy()`. > > Standard behavior: This is not allowed to happen. mcfgthread > solves this > issue by running thread-local destructors and thread-specific key > destructors as two separate passes [3]. > > [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80816 > [2] > https://github.com/gcc-mirror/gcc/blob/f84e4fb44aa26b71fbc64e0532fd24d96e5caa3f/libgcc/emutls.c#L96 > [3] > https://github.com/lhmouse/mcfgthread/blob/63e034d375caf585e2921cd3455f1048feb2172d/src/xglobals.c#L249 > > > 4. In the win32 thread model, thread-specific key destructors are > called at > process exit [4], after static destructors. > > Standard behavior: They shall be called only when a thread exits, > and the > associated thread-specific values are not a null pointer. They > shall not be > called when a program terminates; instead, users are responsible for > deallocating such resources before calling `exit()`. This > requirement is > missing in POSIX, but formally specified by ISO/IEC 9899:2017, as > the 4th > paragraph in '7.26.6.1 The tss_create function'. > > [4] > https://github.com/mingw-w64/mingw-w64/blob/d0a034a04d312434b842c4869a8a900568d8db98/mingw-w64-crt/crt/tlsthrd.c#L134 Those 4 points describes problems that you solve in the new threading model, but there is no reason they can't be fixed for existing threading models. In fact, ideally they would be fixed for all threading models. Except now we need to worry about one more threading model, meaning that future bugs will be even harder to fix. > > 5. Wait operations, of timed mutexes and condition variables, should take > absolute time points as `struct timespec`. > > Standard behavior: Both POSIX and ISO C specifies them as such, > while all > Windows APIs take relative durations as a 32-bit integer of > milliseconds, > which can also easily get overflown. This also may be supported in existing threading models. Overflow is trivial to fix by waiting in a loop. (There are other reasons why OS support for absolute timeout is slightly better, but the price of this design decision makes it questionable. I plan to elaborate more on that on mingw ML, but I need to find time to do a bit of research first). Jacek
> could you please refresh/recheck your patch for the current gcc master > and solve the objections noted in the thread? is it possible? I have attached a revised version of the original patch at: https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html 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 was the default minimal setting of MinGW-W64 until end of 2020. 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 _WIN32_WINNT >= 0x0600. This also changes libstdc++ to pass -D_WIN32_WINNT=0x0600 but only when the switch --enable-libstdcxx-threads is passed, which means that C++11 threads are still disabled by default *unless* MinGW-W64 itself is configured for Windows Vista/Server 2008 or later by default (this has been the case in the development version since end of 2020, for earlier versions you can configure it --with-default-win32-winnt=0x0600 to get the same effect). I only manually tested it on i686-w64-mingw32 and x86_64-w64-mingw32 but AdaCore has used it in their C/C++/Ada compilers for 3 years now and the 30_threads chapter of the libstdc++ testsuite was clean at the time. 2022-10-31 Eric Botcazou <ebotcazou@adacore.com> libgcc/ * config.host (i[34567]86-*-mingw*): Add thread fragment after EH one as well as new i386/t-slibgcc-mingw fragment. (x86_64-*-mingw*): Likewise. * config/i386/gthr-win32.h: If _WIN32_WINNT is at least 0x0600, define both __GTHREAD_HAS_COND and __GTHREADS_CXX0X to 1. Error out if _GTHREAD_USE_MUTEX_TIMEDLOCK is 1. Include stdlib.h instead of errno.h and do not include _mingw.h. (CONST_CAST2): Add specific definition for C++. (ATTRIBUTE_UNUSED): New macro. (__UNUSED_PARAM): Delete. Define WIN32_LEAN_AND_MEAN before including windows.h. (__gthread_objc_data_tls): Use TLS_OUT_OF_INDEXES instead of (DWORD)-1. (__gthread_objc_init_thread_system): Likewise. (__gthread_objc_thread_get_data): Minor tweak. (__gthread_objc_condition_allocate): Use ATTRIBUTE_UNUSED. (__gthread_objc_condition_deallocate): Likewise. (__gthread_objc_condition_wait): Likewise. (__gthread_objc_condition_broadcast): Likewise. (__gthread_objc_condition_signal): Likewise. Include sys/time.h. (__gthr_win32_DWORD): New typedef. (__gthr_win32_HANDLE): Likewise. (__gthr_win32_CRITICAL_SECTION): Likewise. (__gthr_win32_CONDITION_VARIABLE): Likewise. (__gthread_t): Adjust. (__gthread_key_t): Likewise. (__gthread_mutex_t): Likewise. (__gthread_recursive_mutex_t): Likewise. (__gthread_cond_t): New typedef. (__gthread_time_t): Likewise. (__GTHREAD_MUTEX_INIT_DEFAULT): Delete. (__GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT): Likewise. (__GTHREAD_COND_INIT_FUNCTION): Define. (__GTHREAD_TIME_INIT): Likewise. (__gthr_i486_lock_cmp_xchg): Delete. (__gthr_win32_create): Declare. (__gthr_win32_join): Likewise. (__gthr_win32_self): Likewise. (__gthr_win32_detach): Likewise. (__gthr_win32_equal): Likewise. (__gthr_win32_yield): Likewise. (__gthr_win32_mutex_destroy): Likewise. (__gthr_win32_cond_init_function): Likewise if __GTHREADS_HAS_COND is 1. (__gthr_win32_cond_broadcast): Likewise. (__gthr_win32_cond_signal): Likewise. (__gthr_win32_cond_wait): Likewise. (__gthr_win32_cond_timedwait): Likewise. (__gthr_win32_recursive_mutex_init_function): Delete. (__gthr_win32_recursive_mutex_lock): Likewise. (__gthr_win32_recursive_mutex_unlock): Likewise. (__gthr_win32_recursive_mutex_destroy): Likewise. (__gthread_create): New inline function. (__gthread_join): Likewise. (__gthread_self): Likewise. (__gthread_detach): Likewise. (__gthread_equal): Likewise. (__gthread_yield): Likewise. (__gthread_cond_init_function): Likewise if __GTHREADS_HAS_COND is 1. (__gthread_cond_broadcast): Likewise. (__gthread_cond_signal): Likewise. (__gthread_cond_wait): Likewise. (__gthread_cond_timedwait): Likewise. (__GTHREAD_WIN32_INLINE): New macro. (__GTHREAD_WIN32_COND_INLINE): Likewise. (__GTHREAD_WIN32_ACTIVE_P): Likewise. Define WIN32_LEAN_AND_MEAN before including windows.h. (__gthread_once): Minor tweaks. (__gthread_key_create): Use ATTRIBUTE_UNUSED and TLS_OUT_OF_INDEXES. (__gthread_key_delete): Minor tweak. (__gthread_getspecific): Likewise. (__gthread_setspecific): Likewise. (__gthread_mutex_init_function): Reimplement. (__gthread_mutex_destroy): Likewise. (__gthread_mutex_lock): Likewise. (__gthread_mutex_trylock): Likewise. (__gthread_mutex_unlock): Likewise. (__gthr_win32_abs_to_rel_time): Declare. (__gthread_recursive_mutex_init_function): Reimplement. (__gthread_recursive_mutex_destroy): Likewise. (__gthread_recursive_mutex_lock): Likewise. (__gthread_recursive_mutex_trylock): Likewise. (__gthread_recursive_mutex_unlock): Likewise. (__gthread_cond_destroy): New inline function. (__gthread_cond_wait_recursive): Likewise. * config/i386/gthr-win32.c: Delete everything. Include gthr-win32.h to get the out-of-line version of inline routines. Add compile-time checks for the local version of the Win32 types. * config/i386/gthr-win32-cond.c: New file. * config/i386/gthr-win32-thread.c: Likewise. * config/i386/t-gthr-win32: Add config/i386/gthr-win32-thread.c to the EH part, config/i386/gthr-win32-cond.c and config/i386/gthr-win32.c to the static version of libgcc. * config/i386/t-slibgcc-mingw: New file. * config/i386/libgcc-mingw.ver: Likewise. libstdc++-v3/ * acinclude.m4 (GLIBCXX_EXPORT_FLAGS): Substitute CPPFLAGS. (GLIBCXX_ENABLE_LIBSTDCXX_TIME): Set ac_has_sched_yield and ac_has_win32_sleep to yes for MinGW. Change HAVE_WIN32_SLEEP into _GLIBCXX_USE_WIN32_SLEEP. (GLIBCXX_CHECK_GTHREADS): Add _WIN32_THREADS to compilation flags for Win32 threads and force _GTHREAD_USE_MUTEX_TIMEDLOCK to 0 for them. Add -D_WIN32_WINNT=0x0600 to compilation flags if yes was configured and add it to CPPFLAGS on success. * config.h.in: Regenerate. * configure: Likewise. * config/os/mingw32-w64/os_defines.h (_GLIBCXX_USE_GET_NPROCS_WIN32): Define to 1. * config/os/mingw32/os_defines.h (_GLIBCXX_USE_GET_NPROCS_WIN32): Ditto * src/c++11/thread.cc (get_nprocs): Provide Win32 implementation if _GLIBCXX_USE_GET_NPROCS_WIN32 is defined. Replace HAVE_WIN32_SLEEP with USE_WIN32_SLEEP. * testsuite/19_diagnostics/headers/system_error/errc_std_c++0x.cc: Add missing conditional compilation. * testsuite/lib/libstdc++.exp (check_v3_target_sleep): Add support for _GLIBCXX_USE_WIN32_SLEEP. (check_v3_target_nprocs): Likewise for _GLIBCXX_USE_GET_NPROCS_WIN32.
On 2022-10-31 09:18, Eric Botcazou wrote: Hi Eric! thank you very much for the job! I will try to build our (MinGW-Builds project) builds using this patch and will report back. @Jonathan what the next steps to be taken to accept this patch? best! > I have attached a revised version of the original patch at: > https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html > > 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 was the default minimal setting of > MinGW-W64 > until end of 2020. 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 _WIN32_WINNT >= 0x0600. > > This also changes libstdc++ to pass -D_WIN32_WINNT=0x0600 but only when > the > switch --enable-libstdcxx-threads is passed, which means that C++11 > threads > are still disabled by default *unless* MinGW-W64 itself is configured > for > Windows Vista/Server 2008 or later by default (this has been the case > in > the development version since end of 2020, for earlier versions you can > configure it --with-default-win32-winnt=0x0600 to get the same effect). > > I only manually tested it on i686-w64-mingw32 and x86_64-w64-mingw32 > but > AdaCore has used it in their C/C++/Ada compilers for 3 years now and > the > 30_threads chapter of the libstdc++ testsuite was clean at the time. > > > 2022-10-31 Eric Botcazou <ebotcazou@adacore.com> > > libgcc/ > * config.host (i[34567]86-*-mingw*): Add thread fragment after EH one > as well as new i386/t-slibgcc-mingw fragment. > (x86_64-*-mingw*): Likewise. > * config/i386/gthr-win32.h: If _WIN32_WINNT is at least 0x0600, define > both __GTHREAD_HAS_COND and __GTHREADS_CXX0X to 1. > Error out if _GTHREAD_USE_MUTEX_TIMEDLOCK is 1. > Include stdlib.h instead of errno.h and do not include _mingw.h. > (CONST_CAST2): Add specific definition for C++. > (ATTRIBUTE_UNUSED): New macro. > (__UNUSED_PARAM): Delete. > Define WIN32_LEAN_AND_MEAN before including windows.h. > (__gthread_objc_data_tls): Use TLS_OUT_OF_INDEXES instead of > (DWORD)-1. > (__gthread_objc_init_thread_system): Likewise. > (__gthread_objc_thread_get_data): Minor tweak. > (__gthread_objc_condition_allocate): Use ATTRIBUTE_UNUSED. > (__gthread_objc_condition_deallocate): Likewise. > (__gthread_objc_condition_wait): Likewise. > (__gthread_objc_condition_broadcast): Likewise. > (__gthread_objc_condition_signal): Likewise. > Include sys/time.h. > (__gthr_win32_DWORD): New typedef. > (__gthr_win32_HANDLE): Likewise. > (__gthr_win32_CRITICAL_SECTION): Likewise. > (__gthr_win32_CONDITION_VARIABLE): Likewise. > (__gthread_t): Adjust. > (__gthread_key_t): Likewise. > (__gthread_mutex_t): Likewise. > (__gthread_recursive_mutex_t): Likewise. > (__gthread_cond_t): New typedef. > (__gthread_time_t): Likewise. > (__GTHREAD_MUTEX_INIT_DEFAULT): Delete. > (__GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT): Likewise. > (__GTHREAD_COND_INIT_FUNCTION): Define. > (__GTHREAD_TIME_INIT): Likewise. > (__gthr_i486_lock_cmp_xchg): Delete. > (__gthr_win32_create): Declare. > (__gthr_win32_join): Likewise. > (__gthr_win32_self): Likewise. > (__gthr_win32_detach): Likewise. > (__gthr_win32_equal): Likewise. > (__gthr_win32_yield): Likewise. > (__gthr_win32_mutex_destroy): Likewise. > (__gthr_win32_cond_init_function): Likewise if __GTHREADS_HAS_COND is > 1. > (__gthr_win32_cond_broadcast): Likewise. > (__gthr_win32_cond_signal): Likewise. > (__gthr_win32_cond_wait): Likewise. > (__gthr_win32_cond_timedwait): Likewise. > (__gthr_win32_recursive_mutex_init_function): Delete. > (__gthr_win32_recursive_mutex_lock): Likewise. > (__gthr_win32_recursive_mutex_unlock): Likewise. > (__gthr_win32_recursive_mutex_destroy): Likewise. > (__gthread_create): New inline function. > (__gthread_join): Likewise. > (__gthread_self): Likewise. > (__gthread_detach): Likewise. > (__gthread_equal): Likewise. > (__gthread_yield): Likewise. > (__gthread_cond_init_function): Likewise if __GTHREADS_HAS_COND is 1. > (__gthread_cond_broadcast): Likewise. > (__gthread_cond_signal): Likewise. > (__gthread_cond_wait): Likewise. > (__gthread_cond_timedwait): Likewise. > (__GTHREAD_WIN32_INLINE): New macro. > (__GTHREAD_WIN32_COND_INLINE): Likewise. > (__GTHREAD_WIN32_ACTIVE_P): Likewise. > Define WIN32_LEAN_AND_MEAN before including windows.h. > (__gthread_once): Minor tweaks. > (__gthread_key_create): Use ATTRIBUTE_UNUSED and TLS_OUT_OF_INDEXES. > (__gthread_key_delete): Minor tweak. > (__gthread_getspecific): Likewise. > (__gthread_setspecific): Likewise. > (__gthread_mutex_init_function): Reimplement. > (__gthread_mutex_destroy): Likewise. > (__gthread_mutex_lock): Likewise. > (__gthread_mutex_trylock): Likewise. > (__gthread_mutex_unlock): Likewise. > (__gthr_win32_abs_to_rel_time): Declare. > (__gthread_recursive_mutex_init_function): Reimplement. > (__gthread_recursive_mutex_destroy): Likewise. > (__gthread_recursive_mutex_lock): Likewise. > (__gthread_recursive_mutex_trylock): Likewise. > (__gthread_recursive_mutex_unlock): Likewise. > (__gthread_cond_destroy): New inline function. > (__gthread_cond_wait_recursive): Likewise. > * config/i386/gthr-win32.c: Delete everything. > Include gthr-win32.h to get the out-of-line version of inline > routines. > Add compile-time checks for the local version of the Win32 types. > * config/i386/gthr-win32-cond.c: New file. > * config/i386/gthr-win32-thread.c: Likewise. > * config/i386/t-gthr-win32: Add config/i386/gthr-win32-thread.c to the > EH part, config/i386/gthr-win32-cond.c and config/i386/gthr-win32.c to > the static version of libgcc. > * config/i386/t-slibgcc-mingw: New file. > * config/i386/libgcc-mingw.ver: Likewise. > libstdc++-v3/ > * acinclude.m4 (GLIBCXX_EXPORT_FLAGS): Substitute CPPFLAGS. > (GLIBCXX_ENABLE_LIBSTDCXX_TIME): Set ac_has_sched_yield and > ac_has_win32_sleep to yes for MinGW. Change HAVE_WIN32_SLEEP > into _GLIBCXX_USE_WIN32_SLEEP. > (GLIBCXX_CHECK_GTHREADS): Add _WIN32_THREADS to compilation flags for > Win32 threads and force _GTHREAD_USE_MUTEX_TIMEDLOCK to 0 for them. > Add -D_WIN32_WINNT=0x0600 to compilation flags if yes was configured > and add it to CPPFLAGS on success. > * config.h.in: Regenerate. > * configure: Likewise. > * config/os/mingw32-w64/os_defines.h (_GLIBCXX_USE_GET_NPROCS_WIN32): > Define to 1. > * config/os/mingw32/os_defines.h (_GLIBCXX_USE_GET_NPROCS_WIN32): > Ditto > * src/c++11/thread.cc (get_nprocs): Provide Win32 implementation if > _GLIBCXX_USE_GET_NPROCS_WIN32 is defined. Replace HAVE_WIN32_SLEEP > with USE_WIN32_SLEEP. > * testsuite/19_diagnostics/headers/system_error/errc_std_c++0x.cc: Add > missing conditional compilation. > * testsuite/lib/libstdc++.exp (check_v3_target_sleep): Add support for > _GLIBCXX_USE_WIN32_SLEEP. > (check_v3_target_nprocs): Likewise for _GLIBCXX_USE_GET_NPROCS_WIN32.
On 2022-10-31 09:18, Eric Botcazou wrote: hello Eric! > This also changes libstdc++ to pass -D_WIN32_WINNT=0x0600 but only when > the > switch --enable-libstdcxx-threads is passed, which means that C++11 > threads > are still disabled by default *unless* MinGW-W64 itself is configured > for > Windows Vista/Server 2008 or later by default (this has been the case > in > the development version since end of 2020, for earlier versions you can > configure it --with-default-win32-winnt=0x0600 to get the same effect). I have faced with "#error Timed lock primitives are not supported on Windows targets" and I'm not sure I understood the reason correctly. as far as I understand, the definition for `_GTHREAD_USE_MUTEX_TIMEDLOCK` comes from libstdc++/configure as a result of some test. why did I faced with this error? what should I do to avoid this? > you can configure it --with-default-win32-winnt=0x0600 to get the same > effect are you talking about the `--with-default-win32-winnt=` option used on MinGW-builds script? best!
> I have faced with "#error Timed lock primitives are not supported on > Windows targets" and I'm not sure I understood the reason correctly. > > as far as I understand, the definition for > `_GTHREAD_USE_MUTEX_TIMEDLOCK` comes from libstdc++/configure as a > result of some test. > > why did I faced with this error? what should I do to avoid this? Run autoheader + autoconf in the libstdc++-v3 source repository.
hi Eric, Jonathan, I was able to successfully build gcc-trunk using the provided patch. moreover, I was able to successfully build all of the packages used in the toolchain! (gmp, mpfr, mpc, isl, libgnurx, bzip2, termcap, libffi, expat, ncurses, readline, gdbm, tcl, tk, openssl, xz-utils, sqlite, python3, binutils, gdb, make) at first glance everything seems to be working as before! I posted the information about this and the link to the archive on the project page: https://github.com/niXman/mingw-builds/issues/622 best!
> I was able to successfully build gcc-trunk using the provided patch. > moreover, I was able to successfully build all of the packages used in > the toolchain! > (gmp, mpfr, mpc, isl, libgnurx, bzip2, termcap, libffi, expat, ncurses, > readline, gdbm, tcl, tk, openssl, xz-utils, sqlite, python3, binutils, > gdb, make) Great! Did you check that C++ threads are enabled in your build? If they are, you must be able to run the attached C++ test; if they are not (because the MinGW64 build is configured for older versions of Windows), you need to configure the compiler with the option --enable-libstdcxx-threads.
On 2022-11-02 21:27, Eric Botcazou wrote: > Great! Did you check that C++ threads are enabled in your build? If > they > are, you must be able to run the attached C++ test; if they are not > (because > the MinGW64 build is configured for older versions of Windows), you > need to > configure the compiler with the option --enable-libstdcxx-threads. I already checked everything before, but now I re-checked it again - everything works! the output: $ ./t Start thread 0 Start thread 1 Start thread 2 Start thread 3 thank you!
On Mon, 31 Oct 2022 at 09:19, Eric Botcazou via Libstdc++ <libstdc++@gcc.gnu.org> wrote: > I have attached a revised version of the original patch at: > https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html > > 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 was the default minimal setting of MinGW-W64 > until end of 2020. 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 _WIN32_WINNT >= 0x0600. > > This also changes libstdc++ to pass -D_WIN32_WINNT=0x0600 but only when the > switch --enable-libstdcxx-threads is passed, which means that C++11 threads > are still disabled by default *unless* MinGW-W64 itself is configured for > Windows Vista/Server 2008 or later by default (this has been the case in > the development version since end of 2020, for earlier versions you can > configure it --with-default-win32-winnt=0x0600 to get the same effect). > > I only manually tested it on i686-w64-mingw32 and x86_64-w64-mingw32 but > AdaCore has used it in their C/C++/Ada compilers for 3 years now and the > 30_threads chapter of the libstdc++ testsuite was clean at the time. The libgcc parts look reasonable to me, but I can't approve them. Maybe Jonathan Yong can approve those parts as mingw-w64 target maintainer, or maybe a libgcc approver can do so. The libstdc++ parts are OK for trunk. IIUC they could go in separately, they just wouldn't be very much use without the libgcc changes. > 2022-10-31 Eric Botcazou <ebotcazou@adacore.com> > > libgcc/ > * config.host (i[34567]86-*-mingw*): Add thread fragment after EH one > as well as new i386/t-slibgcc-mingw fragment. > (x86_64-*-mingw*): Likewise. > * config/i386/gthr-win32.h: If _WIN32_WINNT is at least 0x0600, define > both __GTHREAD_HAS_COND and __GTHREADS_CXX0X to 1. > Error out if _GTHREAD_USE_MUTEX_TIMEDLOCK is 1. > Include stdlib.h instead of errno.h and do not include _mingw.h. > (CONST_CAST2): Add specific definition for C++. > (ATTRIBUTE_UNUSED): New macro. > (__UNUSED_PARAM): Delete. > Define WIN32_LEAN_AND_MEAN before including windows.h. > (__gthread_objc_data_tls): Use TLS_OUT_OF_INDEXES instead of (DWORD)-1. > (__gthread_objc_init_thread_system): Likewise. > (__gthread_objc_thread_get_data): Minor tweak. > (__gthread_objc_condition_allocate): Use ATTRIBUTE_UNUSED. > (__gthread_objc_condition_deallocate): Likewise. > (__gthread_objc_condition_wait): Likewise. > (__gthread_objc_condition_broadcast): Likewise. > (__gthread_objc_condition_signal): Likewise. > Include sys/time.h. > (__gthr_win32_DWORD): New typedef. > (__gthr_win32_HANDLE): Likewise. > (__gthr_win32_CRITICAL_SECTION): Likewise. > (__gthr_win32_CONDITION_VARIABLE): Likewise. > (__gthread_t): Adjust. > (__gthread_key_t): Likewise. > (__gthread_mutex_t): Likewise. > (__gthread_recursive_mutex_t): Likewise. > (__gthread_cond_t): New typedef. > (__gthread_time_t): Likewise. > (__GTHREAD_MUTEX_INIT_DEFAULT): Delete. > (__GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT): Likewise. > (__GTHREAD_COND_INIT_FUNCTION): Define. > (__GTHREAD_TIME_INIT): Likewise. > (__gthr_i486_lock_cmp_xchg): Delete. > (__gthr_win32_create): Declare. > (__gthr_win32_join): Likewise. > (__gthr_win32_self): Likewise. > (__gthr_win32_detach): Likewise. > (__gthr_win32_equal): Likewise. > (__gthr_win32_yield): Likewise. > (__gthr_win32_mutex_destroy): Likewise. > (__gthr_win32_cond_init_function): Likewise if __GTHREADS_HAS_COND is 1. > (__gthr_win32_cond_broadcast): Likewise. > (__gthr_win32_cond_signal): Likewise. > (__gthr_win32_cond_wait): Likewise. > (__gthr_win32_cond_timedwait): Likewise. > (__gthr_win32_recursive_mutex_init_function): Delete. > (__gthr_win32_recursive_mutex_lock): Likewise. > (__gthr_win32_recursive_mutex_unlock): Likewise. > (__gthr_win32_recursive_mutex_destroy): Likewise. > (__gthread_create): New inline function. > (__gthread_join): Likewise. > (__gthread_self): Likewise. > (__gthread_detach): Likewise. > (__gthread_equal): Likewise. > (__gthread_yield): Likewise. > (__gthread_cond_init_function): Likewise if __GTHREADS_HAS_COND is 1. > (__gthread_cond_broadcast): Likewise. > (__gthread_cond_signal): Likewise. > (__gthread_cond_wait): Likewise. > (__gthread_cond_timedwait): Likewise. > (__GTHREAD_WIN32_INLINE): New macro. > (__GTHREAD_WIN32_COND_INLINE): Likewise. > (__GTHREAD_WIN32_ACTIVE_P): Likewise. > Define WIN32_LEAN_AND_MEAN before including windows.h. > (__gthread_once): Minor tweaks. > (__gthread_key_create): Use ATTRIBUTE_UNUSED and TLS_OUT_OF_INDEXES. > (__gthread_key_delete): Minor tweak. > (__gthread_getspecific): Likewise. > (__gthread_setspecific): Likewise. > (__gthread_mutex_init_function): Reimplement. > (__gthread_mutex_destroy): Likewise. > (__gthread_mutex_lock): Likewise. > (__gthread_mutex_trylock): Likewise. > (__gthread_mutex_unlock): Likewise. > (__gthr_win32_abs_to_rel_time): Declare. > (__gthread_recursive_mutex_init_function): Reimplement. > (__gthread_recursive_mutex_destroy): Likewise. > (__gthread_recursive_mutex_lock): Likewise. > (__gthread_recursive_mutex_trylock): Likewise. > (__gthread_recursive_mutex_unlock): Likewise. > (__gthread_cond_destroy): New inline function. > (__gthread_cond_wait_recursive): Likewise. > * config/i386/gthr-win32.c: Delete everything. > Include gthr-win32.h to get the out-of-line version of inline routines. > Add compile-time checks for the local version of the Win32 types. > * config/i386/gthr-win32-cond.c: New file. > * config/i386/gthr-win32-thread.c: Likewise. > * config/i386/t-gthr-win32: Add config/i386/gthr-win32-thread.c to the > EH part, config/i386/gthr-win32-cond.c and config/i386/gthr-win32.c to > the static version of libgcc. > * config/i386/t-slibgcc-mingw: New file. > * config/i386/libgcc-mingw.ver: Likewise. > libstdc++-v3/ > * acinclude.m4 (GLIBCXX_EXPORT_FLAGS): Substitute CPPFLAGS. > (GLIBCXX_ENABLE_LIBSTDCXX_TIME): Set ac_has_sched_yield and > ac_has_win32_sleep to yes for MinGW. Change HAVE_WIN32_SLEEP > into _GLIBCXX_USE_WIN32_SLEEP. > (GLIBCXX_CHECK_GTHREADS): Add _WIN32_THREADS to compilation flags for > Win32 threads and force _GTHREAD_USE_MUTEX_TIMEDLOCK to 0 for them. > Add -D_WIN32_WINNT=0x0600 to compilation flags if yes was configured > and add it to CPPFLAGS on success. > * config.h.in: Regenerate. > * configure: Likewise. > * config/os/mingw32-w64/os_defines.h (_GLIBCXX_USE_GET_NPROCS_WIN32): > Define to 1. > * config/os/mingw32/os_defines.h (_GLIBCXX_USE_GET_NPROCS_WIN32): Ditto > * src/c++11/thread.cc (get_nprocs): Provide Win32 implementation if > _GLIBCXX_USE_GET_NPROCS_WIN32 is defined. Replace HAVE_WIN32_SLEEP > with USE_WIN32_SLEEP. > * testsuite/19_diagnostics/headers/system_error/errc_std_c++0x.cc: Add > missing conditional compilation. > * testsuite/lib/libstdc++.exp (check_v3_target_sleep): Add support for > _GLIBCXX_USE_WIN32_SLEEP. > (check_v3_target_nprocs): Likewise for _GLIBCXX_USE_GET_NPROCS_WIN32. > > -- > Eric Botcazou
> The libgcc parts look reasonable to me, but I can't approve them. > Maybe Jonathan Yong can approve those parts as mingw-w64 target > maintainer, or maybe a libgcc approver can do so. OK. > The libstdc++ parts are OK for trunk. IIUC they could go in > separately, they just wouldn't be very much use without the libgcc > changes. Sure thing.
On 10/31/22 15:22, i.nixman--- via Gcc-patches wrote: > On 2022-10-31 09:18, Eric Botcazou wrote: > > Hi Eric! > > thank you very much for the job! > I will try to build our (MinGW-Builds project) builds using this patch > and will report back. > > @Jonathan > > what the next steps to be taken to accept this patch? > I don't see any obvious problems with it, looks OK to me.
On 12/16/22 19:20, Eric Botcazou wrote: >> The libgcc parts look reasonable to me, but I can't approve them. >> Maybe Jonathan Yong can approve those parts as mingw-w64 target >> maintainer, or maybe a libgcc approver can do so. > > OK. > >> The libstdc++ parts are OK for trunk. IIUC they could go in >> separately, they just wouldn't be very much use without the libgcc >> changes. > > Sure thing. > Ping, need help to commit it?
On 2022-12-22 12:21, Jonathan Yong wrote: hello, > On 12/16/22 19:20, Eric Botcazou wrote: >>> The libgcc parts look reasonable to me, but I can't approve them. >>> Maybe Jonathan Yong can approve those parts as mingw-w64 target >>> maintainer, or maybe a libgcc approver can do so. >> >> OK. >> >>> The libstdc++ parts are OK for trunk. IIUC they could go in >>> separately, they just wouldn't be very much use without the libgcc >>> changes. >> >> Sure thing. >> > > Ping, need help to commit it? yes, it would be great if we can merge the path into gcc-13! I've tested it on gcc-12-branch and gcc-master for i686/x86_64 windows, with msvcrt and ucrt runtime - works as it should! Eric ^^^ best!
On 12/22/22 12:28, i.nixman@autistici.org wrote: > On 2022-12-22 12:21, Jonathan Yong wrote: > > hello, > >> On 12/16/22 19:20, Eric Botcazou wrote: >>>> The libgcc parts look reasonable to me, but I can't approve them. >>>> Maybe Jonathan Yong can approve those parts as mingw-w64 target >>>> maintainer, or maybe a libgcc approver can do so. >>> >>> OK. >>> >>>> The libstdc++ parts are OK for trunk. IIUC they could go in >>>> separately, they just wouldn't be very much use without the libgcc >>>> changes. >>> >>> Sure thing. >>> >> >> Ping, need help to commit it? > > yes, it would be great if we can merge the path into gcc-13! > > I've tested it on gcc-12-branch and gcc-master for i686/x86_64 windows, > with msvcrt and ucrt runtime - works as it should! > > Eric ^^^ > > > > best! Done, pushed to master branch. Thanks Eric.
On Fri, Dec 23, 2022 at 7:00 PM Jonathan Yong via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > On 12/22/22 12:28, i.nixman@autistici.org wrote: > > On 2022-12-22 12:21, Jonathan Yong wrote: > > > > hello, > > > >> On 12/16/22 19:20, Eric Botcazou wrote: > >>>> The libgcc parts look reasonable to me, but I can't approve them. > >>>> Maybe Jonathan Yong can approve those parts as mingw-w64 target > >>>> maintainer, or maybe a libgcc approver can do so. > >>> > >>> OK. > >>> > >>>> The libstdc++ parts are OK for trunk. IIUC they could go in > >>>> separately, they just wouldn't be very much use without the libgcc > >>>> changes. > >>> > >>> Sure thing. > >>> > >> > >> Ping, need help to commit it? > > > > yes, it would be great if we can merge the path into gcc-13! > > > > I've tested it on gcc-12-branch and gcc-master for i686/x86_64 windows, > > with msvcrt and ucrt runtime - works as it should! > > > > Eric ^^^ > > > > > > > > best! > > Done, pushed to master branch. Thanks Eric. I think this might have broken fortran. I'm assuming because the backtrace includes gthr.h, and I just did a git pull: In file included from /tmp/rtmingw/mingw/include/windows.h:71, from ../libgcc/gthr-default.h:606, from ../../../libgfortran/../libgcc/gthr.h:148, from ../../../libgfortran/io/io.h:33, from ../../../libgfortran/runtime/error.c:27: ../../../libgfortran/io/io.h:298:24: error: expected identifier before numeric constant 298 | { CC_LIST, CC_FORTRAN, CC_NONE, | ^~~~~~~
On 2022-12-23 23:59, Jonathan Yong wrote:
> Done, pushed to master branch. Thanks Eric.
thank you Jonathan!
On 2022-12-24 05:58, NightStrike wrote: > > I think this might have broken fortran. I'm assuming because the > backtrace includes gthr.h, and I just did a git pull: > > In file included from /tmp/rtmingw/mingw/include/windows.h:71, > from ../libgcc/gthr-default.h:606, > from ../../../libgfortran/../libgcc/gthr.h:148, > from ../../../libgfortran/io/io.h:33, > from ../../../libgfortran/runtime/error.c:27: > ../../../libgfortran/io/io.h:298:24: error: expected identifier before > numeric constant > 298 | { CC_LIST, CC_FORTRAN, CC_NONE, > | ^~~~~~~ hmm... I don't remember if I specified `fortran` in `--enable-language` in my test builds... will try to build again now...
On 2022-12-24 05:58, NightStrike wrote: > > I think this might have broken fortran. I'm assuming because the > backtrace includes gthr.h, and I just did a git pull: > > In file included from /tmp/rtmingw/mingw/include/windows.h:71, > from ../libgcc/gthr-default.h:606, > from ../../../libgfortran/../libgcc/gthr.h:148, > from ../../../libgfortran/io/io.h:33, > from ../../../libgfortran/runtime/error.c:27: > ../../../libgfortran/io/io.h:298:24: error: expected identifier before > numeric constant > 298 | { CC_LIST, CC_FORTRAN, CC_NONE, > | ^~~~~~~ yes, you are right! this is because the `CC_NONE` was previously defined in `wingdi.h` as `#define CC_NONE 0` thinking...
On 2022-12-24 13:50, i.nixman@autistici.org wrote: > On 2022-12-24 05:58, NightStrike wrote: >> >> I think this might have broken fortran. I'm assuming because the >> backtrace includes gthr.h, and I just did a git pull: >> >> In file included from /tmp/rtmingw/mingw/include/windows.h:71, >> from ../libgcc/gthr-default.h:606, >> from ../../../libgfortran/../libgcc/gthr.h:148, >> from ../../../libgfortran/io/io.h:33, >> from ../../../libgfortran/runtime/error.c:27: >> ../../../libgfortran/io/io.h:298:24: error: expected identifier before >> numeric constant >> 298 | { CC_LIST, CC_FORTRAN, CC_NONE, >> | ^~~~~~~ > > > yes, you are right! > this is because the `CC_NONE` was previously defined in `wingdi.h` as > `#define CC_NONE 0` > > thinking... fixed and tested. Jonathan Yong, could you please apply the attached patch too? kings regards!
On 2022-12-24 15:42, i.nixman@autistici.org wrote: > fixed and tested. > > Jonathan Yong, could you please apply the attached patch too? > > > > kings regards! oh no... please wait.
On 2022-12-24 15:57, i.nixman@autistici.org wrote: > On 2022-12-24 15:42, i.nixman@autistici.org wrote: > >> fixed and tested. >> >> Jonathan Yong, could you please apply the attached patch too? >> >> >> >> kings regards! > > oh no... > > please wait. fixed now. bootstrapped successfully! Jonathan Yong, could you please apply the attached patch too? best!
On 12/24/22 21:22, i.nixman@autistici.org wrote: > On 2022-12-24 15:57, i.nixman@autistici.org wrote: >> On 2022-12-24 15:42, i.nixman@autistici.org wrote: >> >>> fixed and tested. >>> >>> Jonathan Yong, could you please apply the attached patch too? >>> >>> >>> >>> kings regards! >> >> oh no... >> >> please wait. > > fixed now. > bootstrapped successfully! > > > Jonathan Yong, could you please apply the attached patch too? > > > > best! Done, pushed to master, thanks.
> fixed now. > bootstrapped successfully! Thanks for fixing it. Another way out is to hide the Win32 API by defining __GTHREAD_HIDE_WIN32API like libstdc++ does in its header files.
diff --git a/libgfortran/io/async.h b/libgfortran/io/async.h index efd542a45e82..d57722a95e44 100644 --- a/libgfortran/io/async.h +++ b/libgfortran/io/async.h @@ -351,7 +351,7 @@ typedef struct async_unit struct adv_cond work; struct adv_cond emptysignal; struct st_parameter_dt *pdt; - pthread_t thread; + __gthread_t thread; struct transfer_queue *head; struct transfer_queue *tail;