Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve support for c++ threading and synchronization #735

Merged

Conversation

cfriedt
Copy link
Member

@cfriedt cfriedt commented Feb 11, 2024

Overview

This change allows Zephyr developers to use most or all of the C++ facilities in gcc that depend on gthread support.

Those facilities include (but are likely not limited to)

  • std::thread
  • std::this_thread
  • std::mutex
  • std::recursive_mutex
  • std::shared_mutex
  • std::condition_variable
  • std::binary_semaphore
  • std::counting_semaphore
  • std::lock_guard
  • std::unique_lock
  • std::scoped_lock
  • std::shared_lock
  • std::syncstream
  • std::future
  • std::async

Associated Zephyr SDK PRs

Associated Zephyr PRs

Zephyr SDK Toolchain Snapshots

* The riscv64-zephyr-elf toolchain stack unwinding support is not used in Zephyr. This should be fixed by zephyrproject/zephyr#69912.

Testing branch

Test are in review at zephyrproject-rtos/zephyr#43729 .

The test suites can be run with e.g.

west build -p auto -b qemu_riscv64 -t run tests/lib/cpp/std/thread \
  -- \
  -DCONFIG_PICOLIBC=n \
  -DCONFIG_NEWLIB_LIBC=y

They should run via picolibc eventually as well, but IIRC, there is an error about a missing .spec file.

Help Wanted

Updating Picolibc

The few changes required to newlib might also need to be applied to picolibc in order to expose similar functionality.

Additional Testsuites

It would be helpful to add test suites for the following

Additional testsuites can be added in parallel. They should not be considered blockers by any means, since they do not specifically depend on anything specific to Zephyr.

Technically, not dependent on threading, coroutine support in Zephyr might Just Work (TM). However, coroutines have the potential to be extremely impactful in Zephyr as they are far more memory efficient than threads (important for resource-constrained devices).

Building, Testing, and Uploading Additional SDK Toolchains

"Zephyr SDK Toolchain Snapshots" lists a number of unchecked boxes and unlinked toolchains without links. To check the box and populate the link, the following steps should be taken:

  1. Build the toolchain
sh ./sdk-ng/contrib/linux_build_toolchain.sh -o /tmp/sdk-build -c arc64-zephyr-elf
  1. Back up the existing toolchain (adjust your Zephyr SDK prefix as necessary)
rsync -avr /opt/zephyr/zephyr-sdk-0.16.5/arc64-zephyr-elf{,_orig}/
  1. Overwrite the old toolchain with the new
rsync -avr --delete {/tmp/sdk-build/output,/opt/zephyr/zephyr-sdk-0.16.5}/arc64-zephyr-elf/
  1. Ensure the following testsuites build, run, and pass
west build -p auto -b qemu_arc/qemu_arc_hs6x -t run tests/lib/cpp/std/condition_variable/ -- -DCONFIG_NEWLIB_LIBC=y -DCONFIG_PICOLIBC=n
west build -p auto -b qemu_arc/qemu_arc_hs6x -t run tests/lib/cpp/std/mutex/ -- -DCONFIG_NEWLIB_LIBC=y -DCONFIG_PICOLIBC=n
west build -p auto -b qemu_arc/qemu_arc_hs6x -t run tests/lib/cpp/std/thread/ -- -DCONFIG_NEWLIB_LIBC=y -DCONFIG_PICOLIBC=n
  1. Compress the toolchain
cd /opt/zephyr/zephyr-sdk-0.16.5
tar cpJf ~/arc64-zephyr-elf.tar.xz arc64-zephyr-elf
  1. Upload file to Google Drive
  2. Update Link

LLVM Toolchain Integration

Currently, all of this work is being done against Zephyr's GCC-based SDK toolchains. It's possible that LLVM toolchain integration will be much easier.

Our testsuites should run successfully with both GCC-based toolchains as well as with LLVM.

@cfriedt cfriedt force-pushed the enable-std-thread-iso-only branch 2 times, most recently from 194035e to 11c3edb Compare February 11, 2024 12:53
@cfriedt
Copy link
Member Author

cfriedt commented Feb 11, 2024

This was considerably easier with the contrib/linux_build_toolchain.sh script 👍

@cfriedt cfriedt force-pushed the enable-std-thread-iso-only branch 2 times, most recently from c53bdb4 to cb6f07e Compare February 11, 2024 19:16
@cfriedt cfriedt changed the title support c11 and c++11 threads, mutexes, condition variables, etc improve support for c++ threading and synchronization Feb 11, 2024
@cfriedt cfriedt force-pushed the enable-std-thread-iso-only branch 2 times, most recently from 694e91d to 0706d26 Compare February 12, 2024 14:17
Copy link

@dkalowsk dkalowsk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat!

@cfriedt

This comment has been minimized.

@cfriedt cfriedt force-pushed the enable-std-thread-iso-only branch from 0706d26 to b32e55d Compare February 19, 2024 11:05
@cfriedt
Copy link
Member Author

cfriedt commented Feb 19, 2024

  • added support for thrd_sleep() (which is ISO C11) instead of nanosleep() (which is POSIX) in gcc/libstdc++-v3

@cfriedt cfriedt force-pushed the enable-std-thread-iso-only branch 4 times, most recently from 1800fde to f167e82 Compare February 19, 2024 16:51
@cfriedt cfriedt marked this pull request as ready for review March 2, 2024 11:35
@cfriedt
Copy link
Member Author

cfriedt commented Mar 2, 2024

This can probably be opened for review at this point. Likely I should make PRs for submodules too.

@cfriedt cfriedt force-pushed the enable-std-thread-iso-only branch from f167e82 to 775f79d Compare March 6, 2024 22:56
@cfriedt
Copy link
Member Author

cfriedt commented Mar 6, 2024

Two additional patches needed
Defines to get the required visibility and library behaviour.

diff --git a/libgcc/gthr-c11.h b/libgcc/gthr-c11.h
index 3cadb110d96..db2cc7a46f7 100644
--- a/libgcc/gthr-c11.h
+++ b/libgcc/gthr-c11.h
@@ -45,6 +45,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define _GTHREAD_USE_COND_INIT_FUNC 1
 #define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function
 
+#define _GLIBCXX_THREAD_ABI_COMPAT 1
+#define _GLIBCXX_HAS_GTHREADS 1
+#define _GLIBCXX_USE_THRD_SLEEP 1
+
 #include <threads.h>
 #include <time.h>
 

Include the header for shared_ptr, which is used in one area in this file (if the header is not included there is a compile error)

diff --git a/libstdc++-v3/include/bits/std_thread.h b/libstdc++-v3/include/bits/std_thread.h
index dd625de3bc3..413ad4c9e09 100644
--- a/libstdc++-v3/include/bits/std_thread.h
+++ b/libstdc++-v3/include/bits/std_thread.h
@@ -41,6 +41,7 @@
 #include <bits/invoke.h>       // std::__invoke
 #include <bits/refwrap.h>       // not required, but helpful to users
 #include <bits/unique_ptr.h>   // std::unique_ptr
+#include <bits/shared_ptr.h>   // std::shared_ptr
 
 #ifdef _GLIBCXX_HAS_GTHREADS
 # include <bits/gthr.h>

@cfriedt cfriedt force-pushed the enable-std-thread-iso-only branch from 775f79d to c2c9e86 Compare March 8, 2024 15:35
Copy link

@dkalowsk dkalowsk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haven't been able to review the submodule changes but the configs changes look good

@cfriedt
Copy link
Member Author

cfriedt commented Mar 8, 2024

haven't been able to review the submodule changes but the configs changes look good

@dkalowsk - I still need to make an aarch64-zephyr-elf toolchain for you.

@cfriedt
Copy link
Member Author

cfriedt commented Mar 9, 2024

Screenshot 2024-03-09 at 1 19 55 PM Screenshot 2024-03-09 at 1 20 31 PM Screenshot 2024-03-09 at 1 20 55 PM Screenshot 2024-03-09 at 1 21 23 PM

@cfriedt cfriedt added area: libstdc++ Issues related to libstdc++ (GNU C++ Library) area: Toolchain Issues related to Toolchain (Binutils+GCC+GDB+libs) labels Mar 9, 2024
@cfriedt cfriedt added area: GCC Issues related to GCC (GNU Compiler Collection) area: Newlib Issues related to Newlib (C Library) labels Mar 9, 2024
@cfriedt cfriedt requested a review from yperess March 10, 2024 13:12
@cfriedt
Copy link
Member Author

cfriedt commented Mar 10, 2024

cc @XenulsWatching

@cfriedt
Copy link
Member Author

cfriedt commented Mar 10, 2024

The one oddity I found with using the C11 threads API to provide the C++11 threads API was that there is no equivalent for hardware_concurrency() - i.e. how many hardware threads are available.

Copy link
Member

@stephanosio stephanosio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

DNM until the submodule refs are updated.

@stephanosio
Copy link
Member

@cfriedt Could you please rebase and update the submodule modules to point to the merged commits?

@cfriedt cfriedt force-pushed the enable-std-thread-iso-only branch from c2c9e86 to 947d2e9 Compare April 3, 2024 06:28
@cfriedt
Copy link
Member Author

cfriedt commented Apr 3, 2024

@stephanosio - should be updated now.

@cfriedt cfriedt requested a review from stephanosio April 3, 2024 06:31
Add support for ISO C++11 threads, mutexes, condition variables,
semaphores, locks, scoped locks, synchronized streams, and
futures (async programming) via ISO C11 threads.

Signed-off-by: Christopher Friedt <[email protected]>
@cfriedt cfriedt force-pushed the enable-std-thread-iso-only branch from 947d2e9 to 166747d Compare April 3, 2024 07:03
@stephanosio stephanosio removed the DNM DO NOT MERGE label Apr 4, 2024
@stephanosio stephanosio merged commit 8dee616 into zephyrproject-rtos:main Apr 4, 2024
30 checks passed
@cfriedt cfriedt deleted the enable-std-thread-iso-only branch April 4, 2024 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: GCC Issues related to GCC (GNU Compiler Collection) area: libstdc++ Issues related to libstdc++ (GNU C++ Library) area: Newlib Issues related to Newlib (C Library) area: Toolchain Issues related to Toolchain (Binutils+GCC+GDB+libs)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants