public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: LIU Hao <lh_mouse@126.com>
To: gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org
Subject: Adding a new thread model to GCC
Date: Sun, 2 Oct 2022 02:34:45 +0800	[thread overview]
Message-ID: <0f1f223a-3756-1da3-bd1d-b87edd34e1f9@126.com> (raw)


[-- Attachment #1.1.1: Type: text/plain, Size: 1462 bytes --]

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

[-- Attachment #1.1.2: 0001-libgfortran-Use-__gthread_t-instead-of-pthread_t.patch --]
[-- Type: text/plain, Size: 969 bytes --]

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(-)

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;
 
-- 
2.37.3


[-- Attachment #1.1.3: 0002-libstdc-thread-Implement-_GLIBCXX_NPROCS-for-Windows.patch --]
[-- Type: text/plain, Size: 1166 bytes --]

From fcae3b25b859a207152927797c5ebc520ef3d61a 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 2/3] 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..b39d9f4a9e29 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
-- 
2.37.3


[-- Attachment #1.1.4: 0003-gcc-Add-mcf-thread-model-support-from-mcfgthread.patch --]
[-- Type: text/plain, Size: 9383 bytes --]

From d0f78f3f83d134d91b59e553b115521f8d67ef52 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 3/3] 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

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: Make CRT depend on threading
	library, not vice versa

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
---
 config/gthr.m4                          |  1 +
 gcc/config.gcc                          |  3 +++
 gcc/config/i386/mingw-mcfgthread.h      |  1 +
 gcc/config/i386/mingw32.h               | 11 ++++++++-
 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   |  2 ++
 libgcc/config/i386/t-slibgcc-cygming    |  2 +-
 libstdc++-v3/libsupc++/atexit_thread.cc | 20 ++++++++++++++++
 libstdc++-v3/libsupc++/guard.cc         | 31 +++++++++++++++++++++++++
 12 files changed, 78 insertions(+), 4 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 555f257c2e7a..4cb31bd41561 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2088,6 +2088,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..ec381a7798f1
--- /dev/null
+++ b/gcc/config/i386/mingw-mcfgthread.h
@@ -0,0 +1 @@
+#define TARGET_USE_MCFGTHREAD 1
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
index d3ca0cd0279d..307a803b92c2 100644
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -32,6 +32,14 @@ along with GCC; see the file COPYING3.  If not see
 	 | MASK_STACK_PROBE | MASK_ALIGN_DOUBLE \
 	 | MASK_MS_BITFIELD_LAYOUT)
 
+#ifndef TARGET_USE_MCFGTHREAD
+#define CPP_MCFGTHREAD()  ((void)0)
+#define LIB_MCFGTHREAD     ""
+#else
+#define CPP_MCFGTHREAD()  (builtin_define("__USING_MCFGTHREAD__"))
+#define LIB_MCFGTHREAD     " -lmcfgthread "
+#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 +58,7 @@ along with GCC; see the file COPYING3.  If not see
 	  builtin_define_std ("WIN64");				\
 	  builtin_define ("_WIN64");				\
 	}							\
+	CPP_MCFGTHREAD();	\
     }								\
   while (0)
 
@@ -185,7 +194,7 @@ along with GCC; see the file COPYING3.  If not see
 #define REAL_LIBGCC_SPEC \
   "%{mthreads:-lmingwthrd} -lmingw32 \
    " SHARED_LIBGCC_SPEC " \
-   -lmoldname -lmingwex -lmsvcrt -lkernel32"
+   -lmoldname -lmingwex -lmsvcrt " LIB_MCFGTHREAD " -lkernel32 -lntdll"
 
 #undef STARTFILE_SPEC
 #define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
diff --git a/gcc/configure.ac b/gcc/configure.ac
index b6bafa8b7d69..0641b8a61dae 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..4b9b10e32d61
--- /dev/null
+++ b/libgcc/config/i386/t-mingw-mcfgthread
@@ -0,0 +1,2 @@
+SHLIB_PTHREAD_CFLAG =
+SHLIB_PTHREAD_LDFLAG = -lmcfgthread
diff --git a/libgcc/config/i386/t-slibgcc-cygming b/libgcc/config/i386/t-slibgcc-cygming
index 6236c78e4668..3ab1312053d7 100644
--- a/libgcc/config/i386/t-slibgcc-cygming
+++ b/libgcc/config/i386/t-slibgcc-cygming
@@ -37,7 +37,7 @@ 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_LC) ${SHLIB_PTHREAD_LDFLAG} && \
 	if [ -f $(SHLIB_DIR)/$(SHLIB_SONAME) ]; then \
 	  mv -f $(SHLIB_DIR)/$(SHLIB_SONAME) \
 		$(SHLIB_DIR)/$(SHLIB_SONAME).backup; \
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__
-- 
2.37.3


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

             reply	other threads:[~2022-10-01 18:34 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-01 18:34 LIU Hao [this message]
2022-10-01 20:02 ` Bernhard Reutner-Fischer
2022-10-21  9:58 ` Jonathan Wakely
2022-10-21 10:09   ` i.nixman
2022-10-21 10:48     ` Jonathan Wakely
2022-10-21 10:55       ` i.nixman
2022-10-21 11:36     ` LIU Hao
2022-10-21 11:54       ` i.nixman
2022-10-21 12:19         ` LIU Hao
2022-10-21 12:34           ` i.nixman
2022-10-24  3:40             ` LIU Hao
2022-10-24 20:50               ` Jacek Caban
2022-10-21 11:44   ` Eric Botcazou
2022-10-21 11:55     ` i.nixman
2022-10-24  6:53     ` i.nixman
2022-10-24  8:15       ` Eric Botcazou
2022-10-24  8:20         ` i.nixman
2022-10-31  9:18       ` Eric Botcazou
2022-10-31 15:22         ` i.nixman
2022-11-01  5:22         ` i.nixman
2022-11-01  9:09           ` Eric Botcazou
2022-11-02 12:05             ` i.nixman
2022-11-02 21:27               ` Eric Botcazou
2022-11-02 21:40                 ` i.nixman
2022-12-16 17:18         ` Jonathan Wakely
2022-12-16 19:20           ` Eric Botcazou
2022-12-22 12:21             ` Jonathan Yong
2022-12-22 12:28               ` i.nixman
2022-12-23 23:59                 ` Jonathan Yong
2022-12-24  5:58                   ` NightStrike
2022-12-24  6:27                     ` i.nixman
2022-12-24 13:50                     ` i.nixman
2022-12-24 15:42                       ` i.nixman
2022-12-24 15:57                         ` i.nixman
2022-12-24 21:22                           ` i.nixman
2022-12-25  1:10                             ` Jonathan Yong
2023-01-09 21:56                             ` Eric Botcazou
2022-12-24  6:22                   ` i.nixman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0f1f223a-3756-1da3-bd1d-b87edd34e1f9@126.com \
    --to=lh_mouse@126.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=libstdc++@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).