diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b4bb346f91269a28e3b05facb6e058971776c85..268017c84b894e1d2a6726f8e15f78be04b55ccf 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 0000000000000000000000000000000000000000..d1804530cb49715c5467791fd841a5d39d710915 --- /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 0000000000000000000000000000000000000000..78404af023a6b69d3a352740dfa743ee80272496 --- /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 5595c88f0da59e0ed686daebeecf86ce50b5c821..ed6ec0dada0c23ff127e6ac6f00d656e33890f4b 100644 --- a/src/lib/core/fiber.c +++ b/src/lib/core/fiber.c @@ -251,11 +251,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 5ab1f335804835014adb5d44d03c07947657448a..9874aa19cd0c92d5ad98ae9c9bffd937d44d7d74 100644 --- a/test/unit/fiber_stack.c +++ b/test/unit/fiber_stack.c @@ -29,15 +29,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); /*