Files
gcc/libstdc++-v3/include/bits/std_thread.h

390 lines
10 KiB
C
Raw Normal View History

libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
// std::thread declarations -*- C++ -*-
2026-01-02 09:53:48 +01:00
// Copyright (C) 2008-2026 Free Software Foundation, Inc.
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/std_thread.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{thread}
*/
#ifndef _GLIBCXX_THREAD_H
#define _GLIBCXX_THREAD_H 1
libstdc++: #ifdef out #pragma GCC system_header In r15-3714-gd3a7302ec5985a I added -Wsystem-headers to the libstdc++ build flags to help catch problems in the library. This patch takes a different approach, of disabling the #pragma system_header unless _GLIBCXX_SYSHDR is defined. As a result, the testsuites will treat them as non-system-headers to get better warning coverage during regression testing of both gcc and libstdc++, not just when building the library. My rationale for the #ifdef instead of just removing the #pragma is the three G++ tests that want to test libstdc++ system header behavior, so we need a way to select it. This doesn't affect installed libraries, as they get their system-header status from the lookup path. But testsuite_flags --build-includes gives -I directives rather than -isystem. This patch doesn't change the headers in config/ because I'm not compiling with most of them, so won't see any warnings that need fixing. Adjusting them could happen later, or we can not bother. libstdc++-v3/ChangeLog: * acinclude.m4 (WARN_FLAGS): Remove -Wsystem-headers. * configure: Regenerate. * include/bits/algorithmfwd.h: #ifdef out #pragma GCC system_header. * include/bits/atomic_base.h * include/bits/atomic_futex.h * include/bits/atomic_timed_wait.h * include/bits/atomic_wait.h * include/bits/basic_ios.h * include/bits/basic_string.h * include/bits/boost_concept_check.h * include/bits/char_traits.h * include/bits/charconv.h * include/bits/chrono.h * include/bits/chrono_io.h * include/bits/codecvt.h * include/bits/concept_check.h * include/bits/cpp_type_traits.h * include/bits/elements_of.h * include/bits/enable_special_members.h * include/bits/erase_if.h * include/bits/forward_list.h * include/bits/functional_hash.h * include/bits/gslice.h * include/bits/gslice_array.h * include/bits/hashtable.h * include/bits/indirect_array.h * include/bits/invoke.h * include/bits/ios_base.h * include/bits/iterator_concepts.h * include/bits/locale_classes.h * include/bits/locale_facets.h * include/bits/locale_facets_nonio.h * include/bits/localefwd.h * include/bits/mask_array.h * include/bits/max_size_type.h * include/bits/memory_resource.h * include/bits/memoryfwd.h * include/bits/move_only_function.h * include/bits/node_handle.h * include/bits/ostream_insert.h * include/bits/out_ptr.h * include/bits/parse_numbers.h * include/bits/postypes.h * include/bits/quoted_string.h * include/bits/range_access.h * include/bits/ranges_base.h * include/bits/refwrap.h * include/bits/sat_arith.h * include/bits/semaphore_base.h * include/bits/slice_array.h * include/bits/std_abs.h * include/bits/std_function.h * include/bits/std_mutex.h * include/bits/std_thread.h * include/bits/stl_iterator_base_funcs.h * include/bits/stl_iterator_base_types.h * include/bits/stl_tree.h * include/bits/stream_iterator.h * include/bits/streambuf_iterator.h * include/bits/stringfwd.h * include/bits/this_thread_sleep.h * include/bits/unique_lock.h * include/bits/uses_allocator_args.h * include/bits/utility.h * include/bits/valarray_after.h * include/bits/valarray_array.h * include/bits/valarray_before.h * include/bits/version.h * include/c_compatibility/fenv.h * include/c_compatibility/inttypes.h * include/c_compatibility/stdint.h * include/decimal/decimal.h * include/experimental/bits/net.h * include/experimental/bits/shared_ptr.h * include/ext/aligned_buffer.h * include/ext/alloc_traits.h * include/ext/atomicity.h * include/ext/concurrence.h * include/ext/numeric_traits.h * include/ext/pod_char_traits.h * include/ext/pointer.h * include/ext/stdio_filebuf.h * include/ext/stdio_sync_filebuf.h * include/ext/string_conversions.h * include/ext/type_traits.h * include/ext/vstring.h * include/ext/vstring_fwd.h * include/ext/vstring_util.h * include/parallel/algorithmfwd.h * include/parallel/numericfwd.h * include/tr1/functional_hash.h * include/tr1/hashtable.h * include/tr1/random.h * libsupc++/exception.h * libsupc++/hash_bytes.h * include/bits/basic_ios.tcc * include/bits/basic_string.tcc * include/bits/fstream.tcc * include/bits/istream.tcc * include/bits/locale_classes.tcc * include/bits/locale_facets.tcc * include/bits/locale_facets_nonio.tcc * include/bits/ostream.tcc * include/bits/sstream.tcc * include/bits/streambuf.tcc * include/bits/string_view.tcc * include/bits/version.tpl * include/experimental/bits/string_view.tcc * include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp * include/ext/random.tcc * include/ext/vstring.tcc * include/tr2/bool_set.tcc * include/tr2/dynamic_bitset.tcc * include/bits/c++config * include/c/cassert * include/c/cctype * include/c/cerrno * include/c/cfloat * include/c/ciso646 * include/c/climits * include/c/clocale * include/c/cmath * include/c/csetjmp * include/c/csignal * include/c/cstdarg * include/c/cstddef * include/c/cstdio * include/c/cstdlib * include/c/cstring * include/c/ctime * include/c/cuchar * include/c/cwchar * include/c/cwctype * include/c_global/cassert * include/c_global/ccomplex * include/c_global/cctype * include/c_global/cerrno * include/c_global/cfenv * include/c_global/cfloat * include/c_global/cinttypes * include/c_global/ciso646 * include/c_global/climits * include/c_global/clocale * include/c_global/cmath * include/c_global/csetjmp * include/c_global/csignal * include/c_global/cstdalign * include/c_global/cstdarg * include/c_global/cstdbool * include/c_global/cstddef * include/c_global/cstdint * include/c_global/cstdio * include/c_global/cstdlib * include/c_global/cstring * include/c_global/ctgmath * include/c_global/ctime * include/c_global/cuchar * include/c_global/cwchar * include/c_global/cwctype * include/c_std/cassert * include/c_std/cctype * include/c_std/cerrno * include/c_std/cfloat * include/c_std/ciso646 * include/c_std/climits * include/c_std/clocale * include/c_std/cmath * include/c_std/csetjmp * include/c_std/csignal * include/c_std/cstdarg * include/c_std/cstddef * include/c_std/cstdio * include/c_std/cstdlib * include/c_std/cstring * include/c_std/ctime * include/c_std/cuchar * include/c_std/cwchar * include/c_std/cwctype * include/debug/array * include/debug/bitset * include/debug/deque * include/debug/forward_list * include/debug/list * include/debug/map * include/debug/set * include/debug/string * include/debug/unordered_map * include/debug/unordered_set * include/debug/vector * include/decimal/decimal * include/experimental/algorithm * include/experimental/any * include/experimental/array * include/experimental/buffer * include/experimental/chrono * include/experimental/contract * include/experimental/deque * include/experimental/executor * include/experimental/filesystem * include/experimental/forward_list * include/experimental/functional * include/experimental/internet * include/experimental/io_context * include/experimental/iterator * include/experimental/list * include/experimental/map * include/experimental/memory * include/experimental/memory_resource * include/experimental/net * include/experimental/netfwd * include/experimental/numeric * include/experimental/propagate_const * include/experimental/ratio * include/experimental/regex * include/experimental/scope * include/experimental/set * include/experimental/socket * include/experimental/string * include/experimental/string_view * include/experimental/synchronized_value * include/experimental/system_error * include/experimental/timer * include/experimental/tuple * include/experimental/type_traits * include/experimental/unordered_map * include/experimental/unordered_set * include/experimental/vector * include/ext/algorithm * include/ext/cmath * include/ext/functional * include/ext/iterator * include/ext/memory * include/ext/numeric * include/ext/random * include/ext/rb_tree * include/ext/rope * include/parallel/algorithm * include/std/algorithm * include/std/any * include/std/array * include/std/atomic * include/std/barrier * include/std/bit * include/std/bitset * include/std/charconv * include/std/chrono * include/std/codecvt * include/std/complex * include/std/concepts * include/std/condition_variable * include/std/coroutine * include/std/deque * include/std/execution * include/std/expected * include/std/filesystem * include/std/format * include/std/forward_list * include/std/fstream * include/std/functional * include/std/future * include/std/generator * include/std/iomanip * include/std/ios * include/std/iosfwd * include/std/iostream * include/std/istream * include/std/iterator * include/std/latch * include/std/limits * include/std/list * include/std/locale * include/std/map * include/std/memory * include/std/memory_resource * include/std/mutex * include/std/numbers * include/std/numeric * include/std/optional * include/std/ostream * include/std/print * include/std/queue * include/std/random * include/std/ranges * include/std/ratio * include/std/regex * include/std/scoped_allocator * include/std/semaphore * include/std/set * include/std/shared_mutex * include/std/span * include/std/spanstream * include/std/sstream * include/std/stack * include/std/stacktrace * include/std/stdexcept * include/std/streambuf * include/std/string * include/std/string_view * include/std/syncstream * include/std/system_error * include/std/text_encoding * include/std/thread * include/std/tuple * include/std/type_traits * include/std/typeindex * include/std/unordered_map * include/std/unordered_set * include/std/utility * include/std/valarray * include/std/variant * include/std/vector * include/std/version * include/tr1/array * include/tr1/cfenv * include/tr1/cinttypes * include/tr1/cmath * include/tr1/complex * include/tr1/cstdbool * include/tr1/cstdint * include/tr1/cstdio * include/tr1/cstdlib * include/tr1/cwchar * include/tr1/cwctype * include/tr1/functional * include/tr1/memory * include/tr1/random * include/tr1/regex * include/tr1/tuple * include/tr1/type_traits * include/tr1/unordered_map * include/tr1/unordered_set * include/tr1/utility * include/tr2/bool_set * include/tr2/dynamic_bitset * include/tr2/type_traits * libsupc++/atomic_lockfree_defines.h * libsupc++/compare * libsupc++/cxxabi.h * libsupc++/cxxabi_forced.h * libsupc++/cxxabi_init_exception.h * libsupc++/exception * libsupc++/initializer_list * libsupc++/new * libsupc++/typeinfo: Likewise. * testsuite/20_util/ratio/operations/ops_overflow_neg.cc * testsuite/23_containers/array/tuple_interface/get_neg.cc * testsuite/23_containers/vector/cons/destructible_debug_neg.cc * testsuite/24_iterators/operations/prev_neg.cc * testsuite/ext/type_traits/add_unsigned_floating_neg.cc * testsuite/ext/type_traits/add_unsigned_integer_neg.cc * testsuite/ext/type_traits/remove_unsigned_floating_neg.cc * testsuite/ext/type_traits/remove_unsigned_integer_neg.cc: Adjust line numbers. gcc/testsuite/ChangeLog * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C * g++.dg/diagnostic/disable.C: #define _GLIBCXX_SYSHDR.
2024-09-12 12:15:51 -04:00
#ifdef _GLIBCXX_SYSHDR
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
#pragma GCC system_header
libstdc++: #ifdef out #pragma GCC system_header In r15-3714-gd3a7302ec5985a I added -Wsystem-headers to the libstdc++ build flags to help catch problems in the library. This patch takes a different approach, of disabling the #pragma system_header unless _GLIBCXX_SYSHDR is defined. As a result, the testsuites will treat them as non-system-headers to get better warning coverage during regression testing of both gcc and libstdc++, not just when building the library. My rationale for the #ifdef instead of just removing the #pragma is the three G++ tests that want to test libstdc++ system header behavior, so we need a way to select it. This doesn't affect installed libraries, as they get their system-header status from the lookup path. But testsuite_flags --build-includes gives -I directives rather than -isystem. This patch doesn't change the headers in config/ because I'm not compiling with most of them, so won't see any warnings that need fixing. Adjusting them could happen later, or we can not bother. libstdc++-v3/ChangeLog: * acinclude.m4 (WARN_FLAGS): Remove -Wsystem-headers. * configure: Regenerate. * include/bits/algorithmfwd.h: #ifdef out #pragma GCC system_header. * include/bits/atomic_base.h * include/bits/atomic_futex.h * include/bits/atomic_timed_wait.h * include/bits/atomic_wait.h * include/bits/basic_ios.h * include/bits/basic_string.h * include/bits/boost_concept_check.h * include/bits/char_traits.h * include/bits/charconv.h * include/bits/chrono.h * include/bits/chrono_io.h * include/bits/codecvt.h * include/bits/concept_check.h * include/bits/cpp_type_traits.h * include/bits/elements_of.h * include/bits/enable_special_members.h * include/bits/erase_if.h * include/bits/forward_list.h * include/bits/functional_hash.h * include/bits/gslice.h * include/bits/gslice_array.h * include/bits/hashtable.h * include/bits/indirect_array.h * include/bits/invoke.h * include/bits/ios_base.h * include/bits/iterator_concepts.h * include/bits/locale_classes.h * include/bits/locale_facets.h * include/bits/locale_facets_nonio.h * include/bits/localefwd.h * include/bits/mask_array.h * include/bits/max_size_type.h * include/bits/memory_resource.h * include/bits/memoryfwd.h * include/bits/move_only_function.h * include/bits/node_handle.h * include/bits/ostream_insert.h * include/bits/out_ptr.h * include/bits/parse_numbers.h * include/bits/postypes.h * include/bits/quoted_string.h * include/bits/range_access.h * include/bits/ranges_base.h * include/bits/refwrap.h * include/bits/sat_arith.h * include/bits/semaphore_base.h * include/bits/slice_array.h * include/bits/std_abs.h * include/bits/std_function.h * include/bits/std_mutex.h * include/bits/std_thread.h * include/bits/stl_iterator_base_funcs.h * include/bits/stl_iterator_base_types.h * include/bits/stl_tree.h * include/bits/stream_iterator.h * include/bits/streambuf_iterator.h * include/bits/stringfwd.h * include/bits/this_thread_sleep.h * include/bits/unique_lock.h * include/bits/uses_allocator_args.h * include/bits/utility.h * include/bits/valarray_after.h * include/bits/valarray_array.h * include/bits/valarray_before.h * include/bits/version.h * include/c_compatibility/fenv.h * include/c_compatibility/inttypes.h * include/c_compatibility/stdint.h * include/decimal/decimal.h * include/experimental/bits/net.h * include/experimental/bits/shared_ptr.h * include/ext/aligned_buffer.h * include/ext/alloc_traits.h * include/ext/atomicity.h * include/ext/concurrence.h * include/ext/numeric_traits.h * include/ext/pod_char_traits.h * include/ext/pointer.h * include/ext/stdio_filebuf.h * include/ext/stdio_sync_filebuf.h * include/ext/string_conversions.h * include/ext/type_traits.h * include/ext/vstring.h * include/ext/vstring_fwd.h * include/ext/vstring_util.h * include/parallel/algorithmfwd.h * include/parallel/numericfwd.h * include/tr1/functional_hash.h * include/tr1/hashtable.h * include/tr1/random.h * libsupc++/exception.h * libsupc++/hash_bytes.h * include/bits/basic_ios.tcc * include/bits/basic_string.tcc * include/bits/fstream.tcc * include/bits/istream.tcc * include/bits/locale_classes.tcc * include/bits/locale_facets.tcc * include/bits/locale_facets_nonio.tcc * include/bits/ostream.tcc * include/bits/sstream.tcc * include/bits/streambuf.tcc * include/bits/string_view.tcc * include/bits/version.tpl * include/experimental/bits/string_view.tcc * include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp * include/ext/random.tcc * include/ext/vstring.tcc * include/tr2/bool_set.tcc * include/tr2/dynamic_bitset.tcc * include/bits/c++config * include/c/cassert * include/c/cctype * include/c/cerrno * include/c/cfloat * include/c/ciso646 * include/c/climits * include/c/clocale * include/c/cmath * include/c/csetjmp * include/c/csignal * include/c/cstdarg * include/c/cstddef * include/c/cstdio * include/c/cstdlib * include/c/cstring * include/c/ctime * include/c/cuchar * include/c/cwchar * include/c/cwctype * include/c_global/cassert * include/c_global/ccomplex * include/c_global/cctype * include/c_global/cerrno * include/c_global/cfenv * include/c_global/cfloat * include/c_global/cinttypes * include/c_global/ciso646 * include/c_global/climits * include/c_global/clocale * include/c_global/cmath * include/c_global/csetjmp * include/c_global/csignal * include/c_global/cstdalign * include/c_global/cstdarg * include/c_global/cstdbool * include/c_global/cstddef * include/c_global/cstdint * include/c_global/cstdio * include/c_global/cstdlib * include/c_global/cstring * include/c_global/ctgmath * include/c_global/ctime * include/c_global/cuchar * include/c_global/cwchar * include/c_global/cwctype * include/c_std/cassert * include/c_std/cctype * include/c_std/cerrno * include/c_std/cfloat * include/c_std/ciso646 * include/c_std/climits * include/c_std/clocale * include/c_std/cmath * include/c_std/csetjmp * include/c_std/csignal * include/c_std/cstdarg * include/c_std/cstddef * include/c_std/cstdio * include/c_std/cstdlib * include/c_std/cstring * include/c_std/ctime * include/c_std/cuchar * include/c_std/cwchar * include/c_std/cwctype * include/debug/array * include/debug/bitset * include/debug/deque * include/debug/forward_list * include/debug/list * include/debug/map * include/debug/set * include/debug/string * include/debug/unordered_map * include/debug/unordered_set * include/debug/vector * include/decimal/decimal * include/experimental/algorithm * include/experimental/any * include/experimental/array * include/experimental/buffer * include/experimental/chrono * include/experimental/contract * include/experimental/deque * include/experimental/executor * include/experimental/filesystem * include/experimental/forward_list * include/experimental/functional * include/experimental/internet * include/experimental/io_context * include/experimental/iterator * include/experimental/list * include/experimental/map * include/experimental/memory * include/experimental/memory_resource * include/experimental/net * include/experimental/netfwd * include/experimental/numeric * include/experimental/propagate_const * include/experimental/ratio * include/experimental/regex * include/experimental/scope * include/experimental/set * include/experimental/socket * include/experimental/string * include/experimental/string_view * include/experimental/synchronized_value * include/experimental/system_error * include/experimental/timer * include/experimental/tuple * include/experimental/type_traits * include/experimental/unordered_map * include/experimental/unordered_set * include/experimental/vector * include/ext/algorithm * include/ext/cmath * include/ext/functional * include/ext/iterator * include/ext/memory * include/ext/numeric * include/ext/random * include/ext/rb_tree * include/ext/rope * include/parallel/algorithm * include/std/algorithm * include/std/any * include/std/array * include/std/atomic * include/std/barrier * include/std/bit * include/std/bitset * include/std/charconv * include/std/chrono * include/std/codecvt * include/std/complex * include/std/concepts * include/std/condition_variable * include/std/coroutine * include/std/deque * include/std/execution * include/std/expected * include/std/filesystem * include/std/format * include/std/forward_list * include/std/fstream * include/std/functional * include/std/future * include/std/generator * include/std/iomanip * include/std/ios * include/std/iosfwd * include/std/iostream * include/std/istream * include/std/iterator * include/std/latch * include/std/limits * include/std/list * include/std/locale * include/std/map * include/std/memory * include/std/memory_resource * include/std/mutex * include/std/numbers * include/std/numeric * include/std/optional * include/std/ostream * include/std/print * include/std/queue * include/std/random * include/std/ranges * include/std/ratio * include/std/regex * include/std/scoped_allocator * include/std/semaphore * include/std/set * include/std/shared_mutex * include/std/span * include/std/spanstream * include/std/sstream * include/std/stack * include/std/stacktrace * include/std/stdexcept * include/std/streambuf * include/std/string * include/std/string_view * include/std/syncstream * include/std/system_error * include/std/text_encoding * include/std/thread * include/std/tuple * include/std/type_traits * include/std/typeindex * include/std/unordered_map * include/std/unordered_set * include/std/utility * include/std/valarray * include/std/variant * include/std/vector * include/std/version * include/tr1/array * include/tr1/cfenv * include/tr1/cinttypes * include/tr1/cmath * include/tr1/complex * include/tr1/cstdbool * include/tr1/cstdint * include/tr1/cstdio * include/tr1/cstdlib * include/tr1/cwchar * include/tr1/cwctype * include/tr1/functional * include/tr1/memory * include/tr1/random * include/tr1/regex * include/tr1/tuple * include/tr1/type_traits * include/tr1/unordered_map * include/tr1/unordered_set * include/tr1/utility * include/tr2/bool_set * include/tr2/dynamic_bitset * include/tr2/type_traits * libsupc++/atomic_lockfree_defines.h * libsupc++/compare * libsupc++/cxxabi.h * libsupc++/cxxabi_forced.h * libsupc++/cxxabi_init_exception.h * libsupc++/exception * libsupc++/initializer_list * libsupc++/new * libsupc++/typeinfo: Likewise. * testsuite/20_util/ratio/operations/ops_overflow_neg.cc * testsuite/23_containers/array/tuple_interface/get_neg.cc * testsuite/23_containers/vector/cons/destructible_debug_neg.cc * testsuite/24_iterators/operations/prev_neg.cc * testsuite/ext/type_traits/add_unsigned_floating_neg.cc * testsuite/ext/type_traits/add_unsigned_integer_neg.cc * testsuite/ext/type_traits/remove_unsigned_floating_neg.cc * testsuite/ext/type_traits/remove_unsigned_integer_neg.cc: Adjust line numbers. gcc/testsuite/ChangeLog * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C * g++.dg/diagnostic/disable.C: #define _GLIBCXX_SYSHDR.
2024-09-12 12:15:51 -04:00
#endif
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
#if __cplusplus >= 201103L
#include <bits/c++config.h>
#include <iosfwd> // std::basic_ostream
#include <tuple> // std::tuple
#include <bits/functional_hash.h> // std::hash
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
#include <bits/invoke.h> // std::__invoke
#include <bits/refwrap.h> // not required, but helpful to users
#include <bits/unique_ptr.h> // std::unique_ptr
#ifdef _GLIBCXX_HAS_GTHREADS
# include <bits/gthr.h>
#else
# include <errno.h>
# include <bits/functexcept.h>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __glibcxx_formatters
template<typename, typename> class formatter;
#endif
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
/** @addtogroup threads
* @{
*/
/** A std::thread represents a new thread of execution.
*
* The default constructor creates an object that does not own a thread.
* The `thread(F&&, Args&&...)` constructor invokes a callable in a new
* thread, and owns that new thread. A `std::thread` that owns a thread
* is *joinable*. Joining a thread waits for it to finish executing,
* which happens when the callable running in that thread returns.
*
* A `std::thread` cannot be copied, but can be moved. Moving a joinable
* object transfers ownership of its thread to another object.
*
* A joinable `std::thread` must be explicitly joined (or detached) before
* it is destroyed or assigned to. Attempting to destroy a joinable thread
* will terminate the whole process.
*
* @headerfile thread
* @since C++11
*/
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
class thread
{
public:
#ifdef _GLIBCXX_HAS_GTHREADS
using native_handle_type = __gthread_t;
#else
using native_handle_type = int;
#endif
/** A std::thread::id is a unique identifier for a thread.
*
* @headerfile thread
* @since C++11
*/
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
class id
{
native_handle_type _M_thread;
public:
id() noexcept : _M_thread() { }
explicit
id(native_handle_type __id) : _M_thread(__id) { }
private:
friend class thread;
friend struct hash<id>;
friend bool
operator==(id __x, id __y) noexcept;
#if __cpp_lib_three_way_comparison
friend strong_ordering
operator<=>(id __x, id __y) noexcept;
#else
friend bool
operator<(id __x, id __y) noexcept;
#endif
template<class _CharT, class _Traits>
friend basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __out, id __id);
#if __glibcxx_formatters
friend formatter<id, char>;
friend formatter<id, wchar_t>;
#endif
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
};
private:
id _M_id;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2097. packaged_task constructors should be constrained
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
// 3039. Unnecessary decay in thread and packaged_task
template<typename _Tp>
using __not_same = __not_<is_same<__remove_cvref_t<_Tp>, thread>>;
public:
thread() noexcept = default;
#ifdef _GLIBCXX_HAS_GTHREADS
private:
// This adds to user code that creates std:thread objects (because
// it is called by the template ctor below) strong references to
// pthread_create and pthread_join, which ensures they are both
// linked in even during static linking. We can't depend on
// gthread calls to bring them in, because those may use weak
// references.
static void
_M_thread_deps_never_run() {
#ifdef GTHR_ACTIVE_PROXY
reinterpret_cast<void (*)(void)>(&pthread_create)();
reinterpret_cast<void (*)(void)>(&pthread_join)();
#endif
}
public:
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
template<typename _Callable, typename... _Args,
typename = _Require<__not_same<_Callable>>>
explicit
thread(_Callable&& __f, _Args&&... __args)
{
static_assert( __is_invocable<typename decay<_Callable>::type,
typename decay<_Args>::type...>::value,
"std::thread arguments must be invocable after conversion to rvalues"
);
using _Wrapper = _Call_wrapper<_Callable, _Args...>;
// Create a call wrapper with DECAY_COPY(__f) as its target object
// and DECAY_COPY(__args)... as its bound argument entities.
_M_start_thread(_State_ptr(new _State_impl<_Wrapper>(
std::forward<_Callable>(__f), std::forward<_Args>(__args)...)),
_M_thread_deps_never_run);
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
}
#endif // _GLIBCXX_HAS_GTHREADS
~thread()
{
if (joinable())
std::__terminate();
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
}
thread(const thread&) = delete;
thread(thread&& __t) noexcept
{ swap(__t); }
thread& operator=(const thread&) = delete;
thread& operator=(thread&& __t) noexcept
{
if (joinable())
std::__terminate();
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
swap(__t);
return *this;
}
void
swap(thread& __t) noexcept
{ std::swap(_M_id, __t._M_id); }
bool
joinable() const noexcept
{ return !(_M_id == id()); }
void
join();
void
detach();
id
get_id() const noexcept
{ return _M_id; }
/** @pre thread is joinable
*/
native_handle_type
native_handle()
{ return _M_id._M_thread; }
// Returns a value that hints at the number of hardware thread contexts.
static unsigned int
hardware_concurrency() noexcept;
#ifdef _GLIBCXX_HAS_GTHREADS
#ifndef _GLIBCXX_THREAD_IMPL
private:
#endif
// Abstract base class for types that wrap arbitrary functors to be
// invoked in the new thread of execution.
struct _State
{
virtual ~_State();
virtual void _M_run() = 0;
};
using _State_ptr = unique_ptr<_State>;
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
private:
template<typename _Callable>
struct _State_impl : public _State
{
_Callable _M_func;
template<typename... _Args>
_State_impl(_Args&&... __args)
: _M_func(std::forward<_Args>(__args)...)
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
{ }
void
_M_run() { _M_func(); }
};
void
_M_start_thread(_State_ptr, void (*)());
#if _GLIBCXX_THREAD_ABI_COMPAT
public:
struct _Impl_base;
typedef shared_ptr<_Impl_base> __shared_base_type;
struct _Impl_base
{
__shared_base_type _M_this_ptr;
virtual ~_Impl_base() = default;
virtual void _M_run() = 0;
};
private:
void
_M_start_thread(__shared_base_type, void (*)());
void
_M_start_thread(__shared_base_type);
#endif
private:
// A call wrapper that does INVOKE(forwarded tuple elements...)
template<typename _Tuple>
struct _Invoker
{
template<typename... _Args>
explicit
_Invoker(_Args&&... __args)
: _M_t(std::forward<_Args>(__args)...)
{ }
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
_Tuple _M_t;
template<typename>
struct __result;
template<typename _Fn, typename... _Args>
struct __result<tuple<_Fn, _Args...>>
: __invoke_result<_Fn, _Args...>
{ };
template<size_t... _Ind>
typename __result<_Tuple>::type
_M_invoke(_Index_tuple<_Ind...>)
{ return std::__invoke(std::get<_Ind>(std::move(_M_t))...); }
typename __result<_Tuple>::type
operator()()
{
using _Indices
= typename _Build_index_tuple<tuple_size<_Tuple>::value>::__type;
return _M_invoke(_Indices());
}
};
public:
/// @cond undocumented
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
template<typename... _Tp>
using _Call_wrapper = _Invoker<tuple<typename decay<_Tp>::type...>>;
/// @endcond
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
#endif // _GLIBCXX_HAS_GTHREADS
};
#ifndef _GLIBCXX_HAS_GTHREADS
inline void thread::join() { std::__throw_system_error(EINVAL); }
inline void thread::detach() { std::__throw_system_error(EINVAL); }
inline unsigned int thread::hardware_concurrency() noexcept { return 0; }
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
#endif
/// @relates std::thread
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
inline void
swap(thread& __x, thread& __y) noexcept
{ __x.swap(__y); }
/// @relates std::thread::id
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
inline bool
operator==(thread::id __x, thread::id __y) noexcept
{
// pthread_equal is undefined if either thread ID is not valid, so we
// can't safely use __gthread_equal on default-constructed values (nor
// the non-zero value returned by this_thread::get_id() for
// single-threaded programs using GNU libc). Assume EqualityComparable.
return __x._M_thread == __y._M_thread;
}
// N.B. other comparison operators are defined in <thread>
// DR 889.
/// std::hash specialization for thread::id.
template<>
struct hash<thread::id>
: public __hash_base<size_t, thread::id>
{
size_t
operator()(const thread::id& __id) const noexcept
{ return std::_Hash_impl::hash(__id._M_thread); }
};
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
namespace this_thread
{
/// The unique identifier of the current thread.
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
inline thread::id
get_id() noexcept
{
libstdc++: Avoid calling undefined __gthread_self weak symbol [PR 95989] Since glibc 2.27 the pthread_self symbol has been defined in libc rather than libpthread. Because we only call pthread_self through a weak alias it's possible for statically linked executables to end up without a definition of pthread_self. This crashes when trying to call an undefined weak symbol. We can use the __GLIBC_PREREQ version check to detect the version of glibc where pthread_self is no longer in libpthread, and call it directly rather than through the weak reference. It would be better to check for pthread_self in libc during configure instead of hardcoding the __GLIBC_PREREQ check. That would be complicated by the fact that prior to glibc 2.27 libc.a didn't have the pthread_self symbol, but libc.so.6 did. The configure checks would need to try to link both statically and dynamically, and the result would depend on whether the static libc.a happens to be installed during configure (which could vary between different systems using the same version of glibc). Doing it properly is left for a future date, as that will be needed anyway after glibc moves all pthread symbols from libpthread to libc. When that happens we should revisit the whole approach of using weak symbols for pthread symbols. For the purposes of std::this_thread::get_id() we call pthread_self() directly when using glibc 2.27 or later. Otherwise, if __gthread_active_p() is true then we know the libpthread symbol is available so we call that. Otherwise, we are single-threaded and just use ((__gthread_t)1) as the thread ID. An undesirable consequence of this change is that code compiled prior to the change might inline the old definition of this_thread::get_id() which always returns (__gthread_t)1 in a program that isn't linked to libpthread. Code compiled after the change will use pthread_self() and so get a real TID. That could result in the main thread having different thread::id values in different translation units. This seems acceptable, as there are not expected to be many uses of thread::id in programs that aren't linked to libpthread. An earlier version of this patch also changed __gthread_self() to use __GLIBC_PREREQ(2, 27) and only use the weak symbol for older glibc. Tha might still make sense to do, but isn't needed by libstdc++ now. libstdc++-v3/ChangeLog: PR libstdc++/95989 * config/os/gnu-linux/os_defines.h (_GLIBCXX_NATIVE_THREAD_ID): Define new macro to get reliable thread ID. * include/bits/std_thread.h: (this_thread::get_id): Use new macro if it's defined. * testsuite/30_threads/jthread/95989.cc: New test. * testsuite/30_threads/this_thread/95989.cc: New test.
2020-11-19 21:07:06 +00:00
#ifndef _GLIBCXX_HAS_GTHREADS
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
return thread::id(1);
libstdc++: Avoid calling undefined __gthread_self weak symbol [PR 95989] Since glibc 2.27 the pthread_self symbol has been defined in libc rather than libpthread. Because we only call pthread_self through a weak alias it's possible for statically linked executables to end up without a definition of pthread_self. This crashes when trying to call an undefined weak symbol. We can use the __GLIBC_PREREQ version check to detect the version of glibc where pthread_self is no longer in libpthread, and call it directly rather than through the weak reference. It would be better to check for pthread_self in libc during configure instead of hardcoding the __GLIBC_PREREQ check. That would be complicated by the fact that prior to glibc 2.27 libc.a didn't have the pthread_self symbol, but libc.so.6 did. The configure checks would need to try to link both statically and dynamically, and the result would depend on whether the static libc.a happens to be installed during configure (which could vary between different systems using the same version of glibc). Doing it properly is left for a future date, as that will be needed anyway after glibc moves all pthread symbols from libpthread to libc. When that happens we should revisit the whole approach of using weak symbols for pthread symbols. For the purposes of std::this_thread::get_id() we call pthread_self() directly when using glibc 2.27 or later. Otherwise, if __gthread_active_p() is true then we know the libpthread symbol is available so we call that. Otherwise, we are single-threaded and just use ((__gthread_t)1) as the thread ID. An undesirable consequence of this change is that code compiled prior to the change might inline the old definition of this_thread::get_id() which always returns (__gthread_t)1 in a program that isn't linked to libpthread. Code compiled after the change will use pthread_self() and so get a real TID. That could result in the main thread having different thread::id values in different translation units. This seems acceptable, as there are not expected to be many uses of thread::id in programs that aren't linked to libpthread. An earlier version of this patch also changed __gthread_self() to use __GLIBC_PREREQ(2, 27) and only use the weak symbol for older glibc. Tha might still make sense to do, but isn't needed by libstdc++ now. libstdc++-v3/ChangeLog: PR libstdc++/95989 * config/os/gnu-linux/os_defines.h (_GLIBCXX_NATIVE_THREAD_ID): Define new macro to get reliable thread ID. * include/bits/std_thread.h: (this_thread::get_id): Use new macro if it's defined. * testsuite/30_threads/jthread/95989.cc: New test. * testsuite/30_threads/this_thread/95989.cc: New test.
2020-11-19 21:07:06 +00:00
#elif defined _GLIBCXX_NATIVE_THREAD_ID
return thread::id(_GLIBCXX_NATIVE_THREAD_ID);
#else
return thread::id(__gthread_self());
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
#endif
}
/// Allow the implementation to schedule a different thread.
libstdc++: Move std::thread to a new header This makes it possible to use std::thread without including the whole of <thread>. It also makes this_thread::get_id() and this_thread::yield() available even when there is no gthreads support (e.g. when GCC is built with --disable-threads or --enable-threads=single). In order for the std::thread::id return type of this_thread::get_id() to be defined, std:thread itself is defined unconditionally. However the constructor that creates new threads is not defined for single-threaded builds. The thread::join() and thread::detach() member functions are defined inline for single-threaded builds and just throw an exception (because we know the thread cannot be joinable if the constructor that creates joinable threads doesn't exit). The thread::hardware_concurrency() member function is also defined inline and returns 0 (as suggested by the standard when the value "is not computable or well-defined"). The main benefit for most targets is that other headers such as <future> do not need to include the whole of <thread> just to be able to create a std::thread. That avoids including <stop_token> and std::jthread where not required. This is another partial fix for PR 92546. This also means we can use this_thread::get_id() and this_thread::yield() in <stop_token> instead of using the gthread functions directly. This removes some preprocessor conditionals, simplifying the code. libstdc++-v3/ChangeLog: PR libstdc++/92546 * include/Makefile.am: Add new <bits/std_thread.h> header. * include/Makefile.in: Regenerate. * include/std/future: Include new header instead of <thread>. * include/std/stop_token: Include new header instead of <bits/gthr.h>. (stop_token::_S_yield()): Use this_thread::yield(). (_Stop_state_t::_M_requester): Change type to std::thread::id. (_Stop_state_t::_M_request_stop()): Use this_thread::get_id(). (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise. Use __is_single_threaded() to decide whether to synchronize. * include/std/thread (thread, operator==, this_thread::get_id) (this_thread::yield): Move to new header. (operator<=>, operator!=, operator<, operator<=, operator>) (operator>=, hash<thread::id>, operator<<): Define even when gthreads not available. * src/c++11/thread.cc: Include <memory>. * include/bits/std_thread.h: New file. (thread, operator==, this_thread::get_id, this_thread::yield): Define even when gthreads not available. [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach) (thread::hardware_concurrency): Define inline.
2020-11-19 13:36:15 +00:00
inline void
yield() noexcept
{
#if defined _GLIBCXX_HAS_GTHREADS && defined _GLIBCXX_USE_SCHED_YIELD
__gthread_yield();
#endif
}
} // namespace this_thread
/// @}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // C++11
#endif // _GLIBCXX_THREAD_H