Re: [PATCH] libstdc++: Allow emergency EH alloc pool size to be tuned [PR68606]
On Tue, 11 Oct 2022 at 19:58, Jonathan Wakely wrote: > > > > On Tue, 11 Oct 2022, 19:38 David Edelsohn via Libstdc++, > wrote: >> >> This patch seems to have broken bootstrap on AIX. It seems to assume >> methods that aren't guaranteed to be defined. > > > > It doesn't use anything that wasn't already used by that file. > > I have no idea how it ever compiled if it doesn't now, but I'll take a look. The problem was inconsistent namespace qualification. The __scoped_lock type is always present on AIX even for the single-threaded multilib, but the code wasn't referring to the correct __scoped_lock type consistently. Fixed like so. Bootstrapped on x86_64-linux with --disable-threads (I'm still waiting for the AIX build, but the symptom and cure are the same as for --disable-threads on other targets). Pushed to trunk. commit 23c3cbaed36f6d2f3a7a64f6ebda69329723514b Author: Jonathan Wakely Date: Tue Oct 11 20:19:08 2022 libstdc++: Fix bootstrap for --disable-threads build [PR107221] The __scoped_lock type should be used unqualified so that we always refer to pool::__scoped_lock, which might be the dummy fallback implementation. The __mutex and __scoped_lock types in already work fine without __GTHREADS being defined, but that header isn't included at all unless _GLIBCXX_HOSTED != 0. The fallback implementation should be used for ! _GLIBCXX_HOSTED instead of for !defined __GTHREADS. libstdc++-v3/ChangeLog: PR bootstrap/107221 * libsupc++/eh_alloc.cc (pool): Change preprocessor condition for using __mutex from __GTHREADS to _GLIBCXX_HOSTED. (pool::allocate): Remove namespace qualification to use pool::__scoped_lock instead of __gnu_cxx::__scoped_lock. diff --git a/libstdc++-v3/libsupc++/eh_alloc.cc b/libstdc++-v3/libsupc++/eh_alloc.cc index 50dc37c0d9c..81b8a1548c6 100644 --- a/libstdc++-v3/libsupc++/eh_alloc.cc +++ b/libstdc++-v3/libsupc++/eh_alloc.cc @@ -145,7 +145,7 @@ namespace char data[] __attribute__((aligned)); }; -#ifdef __GTHREADS +#if _GLIBCXX_HOSTED // A single mutex controlling emergency allocations. __gnu_cxx::__mutex emergency_mutex; using __scoped_lock = __gnu_cxx::__scoped_lock; @@ -236,7 +236,7 @@ namespace void *pool::allocate (std::size_t size) noexcept { - __gnu_cxx::__scoped_lock sentry(emergency_mutex); + __scoped_lock sentry(emergency_mutex); // We need an additional size_t member plus the padding to // ensure proper alignment of data. size += offsetof (allocated_entry, data);
Re: [PATCH] libstdc++: Allow emergency EH alloc pool size to be tuned [PR68606]
On Tue, 11 Oct 2022, 19:38 David Edelsohn via Libstdc++, < libstd...@gcc.gnu.org> wrote: > This patch seems to have broken bootstrap on AIX. It seems to assume > methods that aren't guaranteed to be defined. > It doesn't use anything that wasn't already used by that file. I have no idea how it ever compiled if it doesn't now, but I'll take a look. > Thanks, David > > libtool: compile: /tmp/GCC/./gcc/xgcc -B/tmp/GCC/./gcc/ > -B/nasfarm/edelsohn/ins > tall/GCC/powerpc-ibm-aix7.2.5.0/bin/ > -B/nasfarm/edelsohn/install/GCC/powerpc-ibm > -aix7.2.5.0/lib/ -isystem > /nasfarm/edelsohn/install/GCC/powerpc-ibm-aix7.2.5.0/i > nclude -isystem > /nasfarm/edelsohn/install/GCC/powerpc-ibm-aix7.2.5.0/sys-include > -fno-checking -DHAVE_CONFIG_H -I.. > -I/nasfarm/edelsohn/src/src/libstdc++-v3/../ > libiberty -I/nasfarm/edelsohn/src/src/libstdc++-v3/../include > -D_GLIBCXX_SHARED > > -I/tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include/powerpc-ibm-aix7.2.5.0 > -I > /tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include > -I/nasfarm/edelsohn/src/src > /libstdc++-v3/libsupc++ -I/nasfarm/edelsohn/install/include > -I/nasfarm/edelsohn/ > install/include -g -O2 -DIN_GLIBCPP_V3 -Wno-error -c cp-demangle.c -fPIC > -DPIC -o cp-demangle.o > /nasfarm/edelsohn/src/src/libstdc++-v3/libsupc++/eh_alloc.cc: In member > function 'void* {anonymous}::pool::allocate(std::size_t)': > /nasfarm/edelsohn/src/src/libstdc++-v3/libsupc++/eh_alloc.cc:239:54: error: > no matching function for call to > '__gnu_cxx::__scoped_lock::__scoped_lock(int&)' > 239 | __gnu_cxx::__scoped_lock sentry(emergency_mutex); > | ^ > In file included from > /nasfarm/edelsohn/src/src/libstdc++-v3/libsupc++/eh_alloc.cc:37: > > /tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include/ext/concurrence.h:240:14: > note: candidate: '__gnu_cxx::__scoped_lock::__scoped_lock(__mutex_type&)' > 240 | explicit __scoped_lock(__mutex_type& __name) : > _M_device(__name) > | ^ > > /tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include/ext/concurrence.h:240:42: > note: no known conversion for argument 1 from 'int' to > '__gnu_cxx::__scoped_lock::__mutex_type&' > 240 | explicit __scoped_lock(__mutex_type& __name) : > _M_device(__name) > |~~^~ > > /tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include/ext/concurrence.h:236:5: > note: candidate: '__gnu_cxx::__scoped_lock::__scoped_lock(const > __gnu_cxx::__scoped_lock&)' > 236 | __scoped_lock(const __scoped_lock&); > | ^ > > /tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include/ext/concurrence.h:236:19: > note: no known conversion for argument 1 from 'int' to 'const > __gnu_cxx::__scoped_lock&' > 236 | __scoped_lock(const __scoped_lock&); > | ^~~~ > make[5]: *** [Makefile:778: eh_alloc.lo] Error 1 >
Re: [PATCH] libstdc++: Allow emergency EH alloc pool size to be tuned [PR68606]
This patch seems to have broken bootstrap on AIX. It seems to assume methods that aren't guaranteed to be defined. Thanks, David libtool: compile: /tmp/GCC/./gcc/xgcc -B/tmp/GCC/./gcc/ -B/nasfarm/edelsohn/ins tall/GCC/powerpc-ibm-aix7.2.5.0/bin/ -B/nasfarm/edelsohn/install/GCC/powerpc-ibm -aix7.2.5.0/lib/ -isystem /nasfarm/edelsohn/install/GCC/powerpc-ibm-aix7.2.5.0/i nclude -isystem /nasfarm/edelsohn/install/GCC/powerpc-ibm-aix7.2.5.0/sys-include -fno-checking -DHAVE_CONFIG_H -I.. -I/nasfarm/edelsohn/src/src/libstdc++-v3/../ libiberty -I/nasfarm/edelsohn/src/src/libstdc++-v3/../include -D_GLIBCXX_SHARED -I/tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include/powerpc-ibm-aix7.2.5.0 -I /tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include -I/nasfarm/edelsohn/src/src /libstdc++-v3/libsupc++ -I/nasfarm/edelsohn/install/include -I/nasfarm/edelsohn/ install/include -g -O2 -DIN_GLIBCPP_V3 -Wno-error -c cp-demangle.c -fPIC -DPIC -o cp-demangle.o /nasfarm/edelsohn/src/src/libstdc++-v3/libsupc++/eh_alloc.cc: In member function 'void* {anonymous}::pool::allocate(std::size_t)': /nasfarm/edelsohn/src/src/libstdc++-v3/libsupc++/eh_alloc.cc:239:54: error: no matching function for call to '__gnu_cxx::__scoped_lock::__scoped_lock(int&)' 239 | __gnu_cxx::__scoped_lock sentry(emergency_mutex); | ^ In file included from /nasfarm/edelsohn/src/src/libstdc++-v3/libsupc++/eh_alloc.cc:37: /tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include/ext/concurrence.h:240:14: note: candidate: '__gnu_cxx::__scoped_lock::__scoped_lock(__mutex_type&)' 240 | explicit __scoped_lock(__mutex_type& __name) : _M_device(__name) | ^ /tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include/ext/concurrence.h:240:42: note: no known conversion for argument 1 from 'int' to '__gnu_cxx::__scoped_lock::__mutex_type&' 240 | explicit __scoped_lock(__mutex_type& __name) : _M_device(__name) |~~^~ /tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include/ext/concurrence.h:236:5: note: candidate: '__gnu_cxx::__scoped_lock::__scoped_lock(const __gnu_cxx::__scoped_lock&)' 236 | __scoped_lock(const __scoped_lock&); | ^ /tmp/GCC/powerpc-ibm-aix7.2.5.0/libstdc++-v3/include/ext/concurrence.h:236:19: note: no known conversion for argument 1 from 'int' to 'const __gnu_cxx::__scoped_lock&' 236 | __scoped_lock(const __scoped_lock&); | ^~~~ make[5]: *** [Makefile:778: eh_alloc.lo] Error 1
Re: [PATCH] libstdc++: Allow emergency EH alloc pool size to be tuned [PR68606]
On Tue, Oct 11, 2022 at 1:06 PM Jonathan Wakely wrote: > > On Tue, 11 Oct 2022 at 07:41, Richard Biener > wrote: > > > > On Mon, Oct 10, 2022 at 5:10 PM Jonathan Wakely wrote: > > > > > > On Mon, 10 Oct 2022 at 12:17, Jonathan Wakely wrote: > > > > > > > > On Mon, 10 Oct 2022 at 07:18, Richard Biener > > > > wrote: > > > > > > > > > > On Fri, Oct 7, 2022 at 5:55 PM Jonathan Wakely via Gcc-patches > > > > > wrote: > > > > > > > > > > > > This needs a little more documentation (see the TODO in the manual), > > > > > > rather than just the comments in the source. This isn't final, but I > > > > > > think it's the direction I want to take. > > > > > > > > > > > > -- >8 -- > > > > > > > > > > > > Implement a long-standing request to support tuning the size of the > > > > > > emergency buffer for allocating exceptions after malloc fails, or to > > > > > > disable that buffer entirely. > > > > > > > > > > > > It's now possible to disable the dynamic allocation of the buffer > > > > > > and > > > > > > use a fixed-size static buffer, via > > > > > > --enable-libstdcxx-static-eh-pool. > > > > > > This is a built-time choice that is baked into libstdc++ and so > > > > > > affects > > > > > > all code linked against that build of libstdc++. > > > > > > > > > > > > The size of the pool can be set by > > > > > > --with-libstdcxx-eh-pool-obj-count=N > > > > > > which is measured in units of sizeof(void*) not bytes. A given > > > > > > exception > > > > > > type such as std::system_error depends on the target, so giving a > > > > > > size > > > > > > in bytes wouldn't be portable across 16/32/64-bit targets. > > > > > > > > > > > > When libstdc++ is configured to use a dynamic buffer, the size of > > > > > > that > > > > > > buffer can now be tuned at runtime by setting the GLIBCXX_TUNABLES > > > > > > environment variable (c.f. PR libstdc++/88264). The number of > > > > > > exceptions > > > > > > to reserve space for is controlled by the > > > > > > "glibcxx.eh_pool.obj_count" > > > > > > and "glibcxx.eh_pool.obj_size" tunables. The pool will be sized to > > > > > > be > > > > > > able to allocate obj_count exceptions of size > > > > > > obj_size*sizeof(void*) and > > > > > > obj_count "dependent" exceptions rethrown by std::rethrow_exception. > > > > > > > > > > > > With the ability to tune the buffer size, we can reduce the default > > > > > > pool > > > > > > size. Most users never need to throw 1kB exceptions in parallel from > > > > > > hundreds of threads after malloc is OOM. > > > > > > > > > > But does it hurt? Back in time when I reworked the allocator to be > > > > > less > > > > > wasteful the whole point was to allow more exceptions to be in-flight > > > > > during OOM shutdown of a process with many threads. > > > > > > > > It certainly hurts for small systems, but maybe we can keep the large > > > > allocation for 64-bit targets (currently 73kB) and only reduce it for > > > > 32-bit (19kB) and 16-bit (3kB IIRC) targets. > > > > > > Maybe this incremental diff would be an improvement: > > > > > > @@ -90,7 +90,7 @@ using namespace __cxxabiv1; > > > // Assume that the number of concurrent exception objects scales with the > > > // processor word size, i.e., 16-bit systems are not likely to have > > > hundreds > > > // of threads all simultaneously throwing on OOM conditions. > > > -# define EMERGENCY_OBJ_COUNT (8 * __SIZEOF_POINTER__) > > > +# define EMERGENCY_OBJ_COUNT (4 * __SIZEOF_POINTER__ * > > > __SIZEOF_POINTER__) > > > # define MAX_OBJ_COUNT (16 << __SIZEOF_POINTER__) > > > #else > > > # define EMERGENCY_OBJ_COUNT 4 > > > > > > This makes it quadratic in the word size, so on 64-bit targets we'd > > > have space for 256 "reasonable size" exceptions (and twice as many > > > single word exceptions like std::bad_alloc), but only 64 on 32-bit > > > targets, and only 16 on 16-bit ones. > > > > So can we then commonize some of the #defines by using sizeof(void *) > > (taking pointer size as word size?) > > What did you have in mind? Do you mean use sizeof(void*) instead of > the SIZEOF macro? I was just confused and didn't see you commonized EMERGENCY_OBJ_SIZE already, so ignore my comment. > > MAX_OBJ_COUNT uses the SIZEOF macro so it can be used in a > preprocessor condition: > > #ifdef _GLIBCXX_EH_POOL_NOBJS > # if _GLIBCXX_EH_POOL_NOBJS > MAX_OBJ_COUNT >
Re: [PATCH] libstdc++: Allow emergency EH alloc pool size to be tuned [PR68606]
On Tue, 11 Oct 2022 at 07:41, Richard Biener wrote: > > On Mon, Oct 10, 2022 at 5:10 PM Jonathan Wakely wrote: > > > > On Mon, 10 Oct 2022 at 12:17, Jonathan Wakely wrote: > > > > > > On Mon, 10 Oct 2022 at 07:18, Richard Biener > > > wrote: > > > > > > > > On Fri, Oct 7, 2022 at 5:55 PM Jonathan Wakely via Gcc-patches > > > > wrote: > > > > > > > > > > This needs a little more documentation (see the TODO in the manual), > > > > > rather than just the comments in the source. This isn't final, but I > > > > > think it's the direction I want to take. > > > > > > > > > > -- >8 -- > > > > > > > > > > Implement a long-standing request to support tuning the size of the > > > > > emergency buffer for allocating exceptions after malloc fails, or to > > > > > disable that buffer entirely. > > > > > > > > > > It's now possible to disable the dynamic allocation of the buffer and > > > > > use a fixed-size static buffer, via --enable-libstdcxx-static-eh-pool. > > > > > This is a built-time choice that is baked into libstdc++ and so > > > > > affects > > > > > all code linked against that build of libstdc++. > > > > > > > > > > The size of the pool can be set by > > > > > --with-libstdcxx-eh-pool-obj-count=N > > > > > which is measured in units of sizeof(void*) not bytes. A given > > > > > exception > > > > > type such as std::system_error depends on the target, so giving a size > > > > > in bytes wouldn't be portable across 16/32/64-bit targets. > > > > > > > > > > When libstdc++ is configured to use a dynamic buffer, the size of that > > > > > buffer can now be tuned at runtime by setting the GLIBCXX_TUNABLES > > > > > environment variable (c.f. PR libstdc++/88264). The number of > > > > > exceptions > > > > > to reserve space for is controlled by the "glibcxx.eh_pool.obj_count" > > > > > and "glibcxx.eh_pool.obj_size" tunables. The pool will be sized to be > > > > > able to allocate obj_count exceptions of size obj_size*sizeof(void*) > > > > > and > > > > > obj_count "dependent" exceptions rethrown by std::rethrow_exception. > > > > > > > > > > With the ability to tune the buffer size, we can reduce the default > > > > > pool > > > > > size. Most users never need to throw 1kB exceptions in parallel from > > > > > hundreds of threads after malloc is OOM. > > > > > > > > But does it hurt? Back in time when I reworked the allocator to be less > > > > wasteful the whole point was to allow more exceptions to be in-flight > > > > during OOM shutdown of a process with many threads. > > > > > > It certainly hurts for small systems, but maybe we can keep the large > > > allocation for 64-bit targets (currently 73kB) and only reduce it for > > > 32-bit (19kB) and 16-bit (3kB IIRC) targets. > > > > Maybe this incremental diff would be an improvement: > > > > @@ -90,7 +90,7 @@ using namespace __cxxabiv1; > > // Assume that the number of concurrent exception objects scales with the > > // processor word size, i.e., 16-bit systems are not likely to have hundreds > > // of threads all simultaneously throwing on OOM conditions. > > -# define EMERGENCY_OBJ_COUNT (8 * __SIZEOF_POINTER__) > > +# define EMERGENCY_OBJ_COUNT (4 * __SIZEOF_POINTER__ * > > __SIZEOF_POINTER__) > > # define MAX_OBJ_COUNT (16 << __SIZEOF_POINTER__) > > #else > > # define EMERGENCY_OBJ_COUNT 4 > > > > This makes it quadratic in the word size, so on 64-bit targets we'd > > have space for 256 "reasonable size" exceptions (and twice as many > > single word exceptions like std::bad_alloc), but only 64 on 32-bit > > targets, and only 16 on 16-bit ones. > > So can we then commonize some of the #defines by using sizeof(void *) > (taking pointer size as word size?) What did you have in mind? Do you mean use sizeof(void*) instead of the SIZEOF macro? MAX_OBJ_COUNT uses the SIZEOF macro so it can be used in a preprocessor condition: #ifdef _GLIBCXX_EH_POOL_NOBJS # if _GLIBCXX_EH_POOL_NOBJS > MAX_OBJ_COUNT
Re: [PATCH] libstdc++: Allow emergency EH alloc pool size to be tuned [PR68606]
On Mon, Oct 10, 2022 at 5:10 PM Jonathan Wakely wrote: > > On Mon, 10 Oct 2022 at 12:17, Jonathan Wakely wrote: > > > > On Mon, 10 Oct 2022 at 07:18, Richard Biener > > wrote: > > > > > > On Fri, Oct 7, 2022 at 5:55 PM Jonathan Wakely via Gcc-patches > > > wrote: > > > > > > > > This needs a little more documentation (see the TODO in the manual), > > > > rather than just the comments in the source. This isn't final, but I > > > > think it's the direction I want to take. > > > > > > > > -- >8 -- > > > > > > > > Implement a long-standing request to support tuning the size of the > > > > emergency buffer for allocating exceptions after malloc fails, or to > > > > disable that buffer entirely. > > > > > > > > It's now possible to disable the dynamic allocation of the buffer and > > > > use a fixed-size static buffer, via --enable-libstdcxx-static-eh-pool. > > > > This is a built-time choice that is baked into libstdc++ and so affects > > > > all code linked against that build of libstdc++. > > > > > > > > The size of the pool can be set by --with-libstdcxx-eh-pool-obj-count=N > > > > which is measured in units of sizeof(void*) not bytes. A given exception > > > > type such as std::system_error depends on the target, so giving a size > > > > in bytes wouldn't be portable across 16/32/64-bit targets. > > > > > > > > When libstdc++ is configured to use a dynamic buffer, the size of that > > > > buffer can now be tuned at runtime by setting the GLIBCXX_TUNABLES > > > > environment variable (c.f. PR libstdc++/88264). The number of exceptions > > > > to reserve space for is controlled by the "glibcxx.eh_pool.obj_count" > > > > and "glibcxx.eh_pool.obj_size" tunables. The pool will be sized to be > > > > able to allocate obj_count exceptions of size obj_size*sizeof(void*) and > > > > obj_count "dependent" exceptions rethrown by std::rethrow_exception. > > > > > > > > With the ability to tune the buffer size, we can reduce the default pool > > > > size. Most users never need to throw 1kB exceptions in parallel from > > > > hundreds of threads after malloc is OOM. > > > > > > But does it hurt? Back in time when I reworked the allocator to be less > > > wasteful the whole point was to allow more exceptions to be in-flight > > > during OOM shutdown of a process with many threads. > > > > It certainly hurts for small systems, but maybe we can keep the large > > allocation for 64-bit targets (currently 73kB) and only reduce it for > > 32-bit (19kB) and 16-bit (3kB IIRC) targets. > > Maybe this incremental diff would be an improvement: > > @@ -90,7 +90,7 @@ using namespace __cxxabiv1; > // Assume that the number of concurrent exception objects scales with the > // processor word size, i.e., 16-bit systems are not likely to have hundreds > // of threads all simultaneously throwing on OOM conditions. > -# define EMERGENCY_OBJ_COUNT (8 * __SIZEOF_POINTER__) > +# define EMERGENCY_OBJ_COUNT (4 * __SIZEOF_POINTER__ * __SIZEOF_POINTER__) > # define MAX_OBJ_COUNT (16 << __SIZEOF_POINTER__) > #else > # define EMERGENCY_OBJ_COUNT 4 > > This makes it quadratic in the word size, so on 64-bit targets we'd > have space for 256 "reasonable size" exceptions (and twice as many > single word exceptions like std::bad_alloc), but only 64 on 32-bit > targets, and only 16 on 16-bit ones. So can we then commonize some of the #defines by using sizeof(void *) (taking pointer size as word size?) > > This slightly increases the initial allocation on x86_64 from 72,704 > bytes to 73,728 bytes, but reduces 32-bit from 18,944 bytes to 12,800. > If more is needed, it can be chosen via configure or the environment. >
Re: [PATCH] libstdc++: Allow emergency EH alloc pool size to be tuned [PR68606]
On Mon, 10 Oct 2022 at 12:17, Jonathan Wakely wrote: > > On Mon, 10 Oct 2022 at 07:18, Richard Biener > wrote: > > > > On Fri, Oct 7, 2022 at 5:55 PM Jonathan Wakely via Gcc-patches > > wrote: > > > > > > This needs a little more documentation (see the TODO in the manual), > > > rather than just the comments in the source. This isn't final, but I > > > think it's the direction I want to take. > > > > > > -- >8 -- > > > > > > Implement a long-standing request to support tuning the size of the > > > emergency buffer for allocating exceptions after malloc fails, or to > > > disable that buffer entirely. > > > > > > It's now possible to disable the dynamic allocation of the buffer and > > > use a fixed-size static buffer, via --enable-libstdcxx-static-eh-pool. > > > This is a built-time choice that is baked into libstdc++ and so affects > > > all code linked against that build of libstdc++. > > > > > > The size of the pool can be set by --with-libstdcxx-eh-pool-obj-count=N > > > which is measured in units of sizeof(void*) not bytes. A given exception > > > type such as std::system_error depends on the target, so giving a size > > > in bytes wouldn't be portable across 16/32/64-bit targets. > > > > > > When libstdc++ is configured to use a dynamic buffer, the size of that > > > buffer can now be tuned at runtime by setting the GLIBCXX_TUNABLES > > > environment variable (c.f. PR libstdc++/88264). The number of exceptions > > > to reserve space for is controlled by the "glibcxx.eh_pool.obj_count" > > > and "glibcxx.eh_pool.obj_size" tunables. The pool will be sized to be > > > able to allocate obj_count exceptions of size obj_size*sizeof(void*) and > > > obj_count "dependent" exceptions rethrown by std::rethrow_exception. > > > > > > With the ability to tune the buffer size, we can reduce the default pool > > > size. Most users never need to throw 1kB exceptions in parallel from > > > hundreds of threads after malloc is OOM. > > > > But does it hurt? Back in time when I reworked the allocator to be less > > wasteful the whole point was to allow more exceptions to be in-flight > > during OOM shutdown of a process with many threads. > > It certainly hurts for small systems, but maybe we can keep the large > allocation for 64-bit targets (currently 73kB) and only reduce it for > 32-bit (19kB) and 16-bit (3kB IIRC) targets. Maybe this incremental diff would be an improvement: @@ -90,7 +90,7 @@ using namespace __cxxabiv1; // Assume that the number of concurrent exception objects scales with the // processor word size, i.e., 16-bit systems are not likely to have hundreds // of threads all simultaneously throwing on OOM conditions. -# define EMERGENCY_OBJ_COUNT (8 * __SIZEOF_POINTER__) +# define EMERGENCY_OBJ_COUNT (4 * __SIZEOF_POINTER__ * __SIZEOF_POINTER__) # define MAX_OBJ_COUNT (16 << __SIZEOF_POINTER__) #else # define EMERGENCY_OBJ_COUNT 4 This makes it quadratic in the word size, so on 64-bit targets we'd have space for 256 "reasonable size" exceptions (and twice as many single word exceptions like std::bad_alloc), but only 64 on 32-bit targets, and only 16 on 16-bit ones. This slightly increases the initial allocation on x86_64 from 72,704 bytes to 73,728 bytes, but reduces 32-bit from 18,944 bytes to 12,800. If more is needed, it can be chosen via configure or the environment.
Re: [PATCH] libstdc++: Allow emergency EH alloc pool size to be tuned [PR68606]
On Mon, 10 Oct 2022 at 07:18, Richard Biener wrote: > > On Fri, Oct 7, 2022 at 5:55 PM Jonathan Wakely via Gcc-patches > wrote: > > > > This needs a little more documentation (see the TODO in the manual), > > rather than just the comments in the source. This isn't final, but I > > think it's the direction I want to take. > > > > -- >8 -- > > > > Implement a long-standing request to support tuning the size of the > > emergency buffer for allocating exceptions after malloc fails, or to > > disable that buffer entirely. > > > > It's now possible to disable the dynamic allocation of the buffer and > > use a fixed-size static buffer, via --enable-libstdcxx-static-eh-pool. > > This is a built-time choice that is baked into libstdc++ and so affects > > all code linked against that build of libstdc++. > > > > The size of the pool can be set by --with-libstdcxx-eh-pool-obj-count=N > > which is measured in units of sizeof(void*) not bytes. A given exception > > type such as std::system_error depends on the target, so giving a size > > in bytes wouldn't be portable across 16/32/64-bit targets. > > > > When libstdc++ is configured to use a dynamic buffer, the size of that > > buffer can now be tuned at runtime by setting the GLIBCXX_TUNABLES > > environment variable (c.f. PR libstdc++/88264). The number of exceptions > > to reserve space for is controlled by the "glibcxx.eh_pool.obj_count" > > and "glibcxx.eh_pool.obj_size" tunables. The pool will be sized to be > > able to allocate obj_count exceptions of size obj_size*sizeof(void*) and > > obj_count "dependent" exceptions rethrown by std::rethrow_exception. > > > > With the ability to tune the buffer size, we can reduce the default pool > > size. Most users never need to throw 1kB exceptions in parallel from > > hundreds of threads after malloc is OOM. > > But does it hurt? Back in time when I reworked the allocator to be less > wasteful the whole point was to allow more exceptions to be in-flight > during OOM shutdown of a process with many threads. It certainly hurts for small systems, but maybe we can keep the large allocation for 64-bit targets (currently 73kB) and only reduce it for 32-bit (19kB) and 16-bit (3kB IIRC) targets. And obviously if the new code to check an env var is backported, the defaults shouldn't be changed in the release branch. Just enable the new feature, but leave defaults the same. N.B. the C++ ABI actually requires that the emergency pool should block if too many threads try to access it at once. That would mean the program slows down drastically, but doesn't empty the pool and terminate if there are many threads all trying to throw on OOM. I'm not convinced blocking is the right default, but making it an option seems reasonable (I created PR107180 to track that). > So if we reduce the default buffer size that should be documented > in changes.html, maybe with a hint how to restore the old buffer size > (configury flags required or runtime ENV setting)? The git commit message gives the env setting to do that, and acinclude.m4 gives the configure option to do that. I can certainly add the info to changes.html where it's more likely to be noticed. > > Otherwise looks OK to me. Great, thanks for taking a look.
Re: [PATCH] libstdc++: Allow emergency EH alloc pool size to be tuned [PR68606]
On Fri, Oct 7, 2022 at 5:55 PM Jonathan Wakely via Gcc-patches wrote: > > This needs a little more documentation (see the TODO in the manual), > rather than just the comments in the source. This isn't final, but I > think it's the direction I want to take. > > -- >8 -- > > Implement a long-standing request to support tuning the size of the > emergency buffer for allocating exceptions after malloc fails, or to > disable that buffer entirely. > > It's now possible to disable the dynamic allocation of the buffer and > use a fixed-size static buffer, via --enable-libstdcxx-static-eh-pool. > This is a built-time choice that is baked into libstdc++ and so affects > all code linked against that build of libstdc++. > > The size of the pool can be set by --with-libstdcxx-eh-pool-obj-count=N > which is measured in units of sizeof(void*) not bytes. A given exception > type such as std::system_error depends on the target, so giving a size > in bytes wouldn't be portable across 16/32/64-bit targets. > > When libstdc++ is configured to use a dynamic buffer, the size of that > buffer can now be tuned at runtime by setting the GLIBCXX_TUNABLES > environment variable (c.f. PR libstdc++/88264). The number of exceptions > to reserve space for is controlled by the "glibcxx.eh_pool.obj_count" > and "glibcxx.eh_pool.obj_size" tunables. The pool will be sized to be > able to allocate obj_count exceptions of size obj_size*sizeof(void*) and > obj_count "dependent" exceptions rethrown by std::rethrow_exception. > > With the ability to tune the buffer size, we can reduce the default pool > size. Most users never need to throw 1kB exceptions in parallel from > hundreds of threads after malloc is OOM. But does it hurt? Back in time when I reworked the allocator to be less wasteful the whole point was to allow more exceptions to be in-flight during OOM shutdown of a process with many threads. So if we reduce the default buffer size that should be documented in changes.html, maybe with a hint how to restore the old buffer size (configury flags required or runtime ENV setting)? Otherwise looks OK to me. Thanks, Richard. > The users who do need that can > use the tunables to select larger sizes. The old default can be chosen > with: > > For 64-bit: > GLIBCXX_TUNABLES="glibcxx.eh_pool.obj_count=64:glibcxx.eh_pool.obj_size=112" > For 32-bit: > GLIBCXX_TUNABLES="glibcxx.eh_pool.obj_count=32:glibcxx.eh_pool.obj_size=112" > > libstdc++-v3/ChangeLog: > > PR libstdc++/68606 > * Makefile.in: Regenerate. > * acinclude.m4 (GLIBCXX_EMERGENCY_EH_ALLOC): New macro. > * configure: Regenerate. > * configure.ac: Use GLIBCXX_EMERGENCY_EH_ALLOC. > * crossconfig.m4: Check for secure_getenv. > * doc/Makefile.in: Regenerate. > * doc/xml/manual/configure.xml: Document new configure options. > * doc/xml/manual/using_exceptions.xml: Document emergency > buffer. > * doc/html/*: Regenerate. > * include/Makefile.in: Regenerate. > * libsupc++/Makefile.am: Use EH_POOL_FLAGS. > * libsupc++/Makefile.in: Regenerate. > * libsupc++/eh_alloc.cc (EMERGENCY_OBJ_SIZE): Define in units > of sizeof(void*) not including the ABI's exception header. > (EMERGENCY_OBJ_COUNT): Define as target-independent calculation > based on word size. > (MAX_OBJ_COUNT): Define macro for upper limit on pool size. > (pool) [_GLIBCXX_EH_POOL_STATIC]: Use fixed-size buffer. > (pool::buffer_size_in_bytes): New static member function. > (pool::pool): Parse GLIBCXX_TUNABLES environment variable to set > pool size at runtime. > (pool::in_pool): Use std::less for total order. > (__freeres) [_GLIBCXX_EH_POOL_STATIC]: Do nothing. > (__cxa_allocate_exception, __cxa_free_exception) > (__cxa_allocate_dependent_exception) > (__cxa_free_dependent_exception): Add [[unlikely]] attributes. > * po/Makefile.in: Regenerate. > * python/Makefile.in: Regenerate. > * src/Makefile.in: Regenerate. > * src/c++11/Makefile.in: Regenerate. > * src/c++17/Makefile.in: Regenerate. > * src/c++20/Makefile.in: Regenerate. > * src/c++98/Makefile.in: Regenerate. > * src/filesystem/Makefile.in: Regenerate. > * src/libbacktrace/Makefile.in: Regenerate. > * testsuite/Makefile.in: Regenerate. > --- > libstdc++-v3/Makefile.in | 1 + > libstdc++-v3/acinclude.m4 | 45 > libstdc++-v3/configure| 67 +- > libstdc++-v3/configure.ac | 3 + > libstdc++-v3/crossconfig.m4 | 1 + > libstdc++-v3/doc/Makefile.in | 1 + > libstdc++-v3/doc/html/index.html | 2 +- > libstdc++-v3/doc/html/manual/configure.html | 10 +- > libstdc++-v3/doc/html/manual/index.html | 2 +- >
[PATCH] libstdc++: Allow emergency EH alloc pool size to be tuned [PR68606]
This needs a little more documentation (see the TODO in the manual), rather than just the comments in the source. This isn't final, but I think it's the direction I want to take. -- >8 -- Implement a long-standing request to support tuning the size of the emergency buffer for allocating exceptions after malloc fails, or to disable that buffer entirely. It's now possible to disable the dynamic allocation of the buffer and use a fixed-size static buffer, via --enable-libstdcxx-static-eh-pool. This is a built-time choice that is baked into libstdc++ and so affects all code linked against that build of libstdc++. The size of the pool can be set by --with-libstdcxx-eh-pool-obj-count=N which is measured in units of sizeof(void*) not bytes. A given exception type such as std::system_error depends on the target, so giving a size in bytes wouldn't be portable across 16/32/64-bit targets. When libstdc++ is configured to use a dynamic buffer, the size of that buffer can now be tuned at runtime by setting the GLIBCXX_TUNABLES environment variable (c.f. PR libstdc++/88264). The number of exceptions to reserve space for is controlled by the "glibcxx.eh_pool.obj_count" and "glibcxx.eh_pool.obj_size" tunables. The pool will be sized to be able to allocate obj_count exceptions of size obj_size*sizeof(void*) and obj_count "dependent" exceptions rethrown by std::rethrow_exception. With the ability to tune the buffer size, we can reduce the default pool size. Most users never need to throw 1kB exceptions in parallel from hundreds of threads after malloc is OOM. The users who do need that can use the tunables to select larger sizes. The old default can be chosen with: For 64-bit: GLIBCXX_TUNABLES="glibcxx.eh_pool.obj_count=64:glibcxx.eh_pool.obj_size=112" For 32-bit: GLIBCXX_TUNABLES="glibcxx.eh_pool.obj_count=32:glibcxx.eh_pool.obj_size=112" libstdc++-v3/ChangeLog: PR libstdc++/68606 * Makefile.in: Regenerate. * acinclude.m4 (GLIBCXX_EMERGENCY_EH_ALLOC): New macro. * configure: Regenerate. * configure.ac: Use GLIBCXX_EMERGENCY_EH_ALLOC. * crossconfig.m4: Check for secure_getenv. * doc/Makefile.in: Regenerate. * doc/xml/manual/configure.xml: Document new configure options. * doc/xml/manual/using_exceptions.xml: Document emergency buffer. * doc/html/*: Regenerate. * include/Makefile.in: Regenerate. * libsupc++/Makefile.am: Use EH_POOL_FLAGS. * libsupc++/Makefile.in: Regenerate. * libsupc++/eh_alloc.cc (EMERGENCY_OBJ_SIZE): Define in units of sizeof(void*) not including the ABI's exception header. (EMERGENCY_OBJ_COUNT): Define as target-independent calculation based on word size. (MAX_OBJ_COUNT): Define macro for upper limit on pool size. (pool) [_GLIBCXX_EH_POOL_STATIC]: Use fixed-size buffer. (pool::buffer_size_in_bytes): New static member function. (pool::pool): Parse GLIBCXX_TUNABLES environment variable to set pool size at runtime. (pool::in_pool): Use std::less for total order. (__freeres) [_GLIBCXX_EH_POOL_STATIC]: Do nothing. (__cxa_allocate_exception, __cxa_free_exception) (__cxa_allocate_dependent_exception) (__cxa_free_dependent_exception): Add [[unlikely]] attributes. * po/Makefile.in: Regenerate. * python/Makefile.in: Regenerate. * src/Makefile.in: Regenerate. * src/c++11/Makefile.in: Regenerate. * src/c++17/Makefile.in: Regenerate. * src/c++20/Makefile.in: Regenerate. * src/c++98/Makefile.in: Regenerate. * src/filesystem/Makefile.in: Regenerate. * src/libbacktrace/Makefile.in: Regenerate. * testsuite/Makefile.in: Regenerate. --- libstdc++-v3/Makefile.in | 1 + libstdc++-v3/acinclude.m4 | 45 libstdc++-v3/configure| 67 +- libstdc++-v3/configure.ac | 3 + libstdc++-v3/crossconfig.m4 | 1 + libstdc++-v3/doc/Makefile.in | 1 + libstdc++-v3/doc/html/index.html | 2 +- libstdc++-v3/doc/html/manual/configure.html | 10 +- libstdc++-v3/doc/html/manual/index.html | 2 +- libstdc++-v3/doc/html/manual/intro.html | 2 +- libstdc++-v3/doc/html/manual/using.html | 2 +- .../doc/html/manual/using_exceptions.html | 53 +++- libstdc++-v3/doc/xml/manual/configure.xml | 23 ++ .../doc/xml/manual/using_exceptions.xml | 48 libstdc++-v3/include/Makefile.in | 1 + libstdc++-v3/libsupc++/Makefile.am| 2 +- libstdc++-v3/libsupc++/Makefile.in| 3 +- libstdc++-v3/libsupc++/eh_alloc.cc| 226 +- libstdc++-v3/po/Makefile.in | 1 + libstdc++-v3/python/Makefile.in | 1 + libstdc++-v3/src/Makefile.in | 1 +