From aae1daabc07592f216c340219bdf10db0645660b Mon Sep 17 00:00:00 2001 From: Igor Munkin <imun@tarantool.org> Date: Tue, 11 Jul 2023 15:13:38 +0000 Subject: [PATCH] cmake: introduce FIBER_STACK_SIZE option In scope of the commit 82f4b4a3b1fb ("lib/core/fiber: Increase default stack size") the default value of fiber stack size is increased up to 512 Kb (you can find the reasons in the aforementioned commit message and in https://github.com/tarantool/tarantool/issues/3418 description). Some of the tests in test/PUC-Rio-Lua-5.1-test suite in LuaJIT repo (e.g. some cases with deep recursion in errors.lua or pm.lua) have already been tweaked according to the limitations mentioned in https://github.com/tarantool/tarantool/issues/5782, but the crashes still occurs while running LuaJIT tests with ASan support enabled. To make the testing routine more convenient, FIBER_STACK_SIZE option is introduced to Tarantool CMake machinery. One can provide the size either by raw digits (i.e. in bytes) or using Kb/Mb suffixes for convenience. A couple of important nits: * If the given value is not a multiple of 4Kb, CMake machinery adjusts it up to the nearest one greater than this value. * If the adjusted value is less than 512Kb, configuration fails with the corresponding CMake fatal error. Follows up #3418 Relates to #5782 @TarantoolBot document Title: introduce FIBER_STACK_SIZE configuration option To make managing of the default fiber stack size more convenient, the corresponding CMake option is added. **NB**: The stack size can't be less than 512Kb and if the given value is not a multiple of 4Kb, CMake machinery adjusts it up to the nearest one greater than this value. (cherry picked from commit ff57f990f359f6d7866c1947174d8ba0e97b1ea6) --- CMakeLists.txt | 1 + .../add-fiber-stack-size-option-to-cmake.md | 3 ++ cmake/SetFiberStackSize.cmake | 45 +++++++++++++++++++ src/lib/core/fiber.c | 6 ++- test/unit/fiber_stack.c | 11 ++++- 5 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 changelogs/unreleased/add-fiber-stack-size-option-to-cmake.md create mode 100644 cmake/SetFiberStackSize.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 729c6c3222..18650e8259 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,7 @@ include(cmake/module.cmake) include(cmake/thread.cmake) include(cmake/hardening.cmake) include(cmake/prefix.cmake) +include(cmake/SetFiberStackSize.cmake) add_compile_flags("C;CXX" ${HARDENING_FLAGS}) set(DEPENDENCY_CFLAGS "${DEPENDENCY_CFLAGS} ${HARDENING_FLAGS}") diff --git a/changelogs/unreleased/add-fiber-stack-size-option-to-cmake.md b/changelogs/unreleased/add-fiber-stack-size-option-to-cmake.md new file mode 100644 index 0000000000..d1804530cb --- /dev/null +++ b/changelogs/unreleased/add-fiber-stack-size-option-to-cmake.md @@ -0,0 +1,3 @@ +## feature/build + +* Added the CMake option `FIBER_STACK_SIZE` to set the default fiber stack size. diff --git a/cmake/SetFiberStackSize.cmake b/cmake/SetFiberStackSize.cmake new file mode 100644 index 0000000000..78404af023 --- /dev/null +++ b/cmake/SetFiberStackSize.cmake @@ -0,0 +1,45 @@ +# This module provides a CMake configuration variable to set +# fiber stack size. If no value is given the default size equals +# to 512Kb (see https://github.com/tarantool/tarantool/issues/3418 +# for more info). Possible types of values are described below. +# The given size is converted to bytes and aligned up to be +# multiple of 4Kb. As a result the corresponding define value is +# propagated to the sources. + +set(FIBER_STACK_SIZE "524288" CACHE STRING "Fiber stack size") + +# Possible values of the stack size: +# * Just a bunch of digits: the size is given in bytes +# * Digits with "KB"|"Kb" suffix: the size is given in kilobytes +# * Digits with "MB"|"Mb" suffix: the size is given in megabytes +# All other values are considered as invalid. +if(FIBER_STACK_SIZE MATCHES "^([0-9]+)$") + set(FIBER_STACK_SIZE_IN_BYTES ${CMAKE_MATCH_1}) +elseif(FIBER_STACK_SIZE MATCHES "([0-9]+)K[bB]$") + math(EXPR FIBER_STACK_SIZE_IN_BYTES "${CMAKE_MATCH_1} << 10") +elseif(FIBER_STACK_SIZE MATCHES "([0-9]+)M[bB]$") + math(EXPR FIBER_STACK_SIZE_IN_BYTES "${CMAKE_MATCH_1} << 20") +else() + message(FATAL_ERROR "Invalid size of the fiber stack") +endif() + +# XXX: Align the stack size in bytes up to be multiple of 4Kb. +math(EXPR FIBER_STACK_SIZE_IN_BYTES + "((${FIBER_STACK_SIZE_IN_BYTES} >> 12) + 1) << 12") + +# See the rationale for the minimal fiber stack size in +# https://github.com/tarantool/tarantool/issues/3418. +if(FIBER_STACK_SIZE_IN_BYTES LESS 524288) + message(FATAL_ERROR "[SetFiberStackSize] Minimal fiber stack size is 512Kb," + " but ${FIBER_STACK_SIZE} is given as a default") +else() + message(STATUS "[SetFiberStackSize] Default fiber stack size: " + " ${FIBER_STACK_SIZE} (adjusted to ${FIBER_STACK_SIZE_IN_BYTES} bytes)") +endif() + +# Propagate the value to the sources. +add_definitions(-DFIBER_STACK_SIZE_DEFAULT=${FIBER_STACK_SIZE_IN_BYTES}) + +# XXX: Unset variables to avoid spoiliing CMake environment. +unset(FIBER_STACK_SIZE_IN_BYTES) +unset(FIBER_STACK_SIZE) diff --git a/src/lib/core/fiber.c b/src/lib/core/fiber.c index 652737713e..0e281b49b2 100644 --- a/src/lib/core/fiber.c +++ b/src/lib/core/fiber.c @@ -258,11 +258,13 @@ pthread_t main_thread_id; static size_t page_size; static int stack_direction; +#ifndef FIBER_STACK_SIZE_DEFAULT +#error "Default fiber stack size is not set" +#endif + enum { /* The minimum allowable fiber stack size in bytes */ FIBER_STACK_SIZE_MINIMAL = 16384, - /* Default fiber stack size in bytes */ - FIBER_STACK_SIZE_DEFAULT = 524288, /* Stack size watermark in bytes. */ FIBER_STACK_SIZE_WATERMARK = 65536, }; diff --git a/test/unit/fiber_stack.c b/test/unit/fiber_stack.c index 8a3740e39a..3c7cf881ce 100644 --- a/test/unit/fiber_stack.c +++ b/test/unit/fiber_stack.c @@ -31,15 +31,22 @@ main_f(va_list ap) struct errinj *inj; struct fiber *fiber; int fiber_count = fiber_count_total(); + struct fiber_attr *fiber_attr = fiber_attr_new(); header(); - plan(10); + plan(11); + + /* + * Check the default fiber stack size value. + */ + ok(default_attr.stack_size == FIBER_STACK_SIZE_DEFAULT, + "fiber_attr: the default stack size is %ld, but %d is set via CMake", + default_attr.stack_size, FIBER_STACK_SIZE_DEFAULT); /* * Set non-default stack size to prevent reusing of an * existing fiber. */ - struct fiber_attr *fiber_attr = fiber_attr_new(); fiber_attr_setstacksize(fiber_attr, default_attr.stack_size * 2); /* -- GitLab