Skip to content

Commit 126ea20

Browse files
feat core: add gdb coroutines unwinder
Benchmark results: ``` Benchmarking utask cmd for tasks_cnt=100 threads_cnt=8 memory_per_task=1000: `utask list` (first call) time: 0.343 s `utask list` (second call) time: 0.001 s `utask apply all bt` (first call) time: 1.126 s `utask apply all bt` (second call) time: 0.915 s Benchmarking utask cmd for tasks_cnt=100 threads_cnt=8 memory_per_task=10000000: `utask list` (first call) time: 0.321 s `utask list` (second call) time: 0.001 s `utask apply all bt` (first call) time: 1.098 s `utask apply all bt` (second call) time: 0.873 s Benchmarking utask cmd for tasks_cnt=500 threads_cnt=32 memory_per_task=1000000: `utask list` (first call) time: 1.531 s `utask list` (second call) time: 0.004 s `utask apply all bt` (first call) time: 5.381 s `utask apply all bt` (second call) time: 4.405 s Benchmarking utask cmd for tasks_cnt=1000 threads_cnt=32 memory_per_task=100000: `utask list` (first call) time: 3.161 s `utask list` (second call) time: 0.007 s `utask apply all bt` (first call) time: 11.124 s `utask apply all bt` (second call) time: 9.036 s Benchmarking utask cmd for tasks_cnt=2000 threads_cnt=32 memory_per_task=100000: `utask list` (first call) time: 6.319 s `utask list` (second call) time: 0.013 s `utask apply all bt` (first call) time: 21.829 s `utask apply all bt` (second call) time: 17.738 s ``` Tests: протестировано в CI commit_hash:1d9a6e55c91a86540b2c19f35d36288abb645791
1 parent d8f7bf6 commit 126ea20

File tree

32 files changed

+1325
-58
lines changed

32 files changed

+1325
-58
lines changed

.mapping.json

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,8 @@
12881288
"core/src/dynamic_config/value_test.cpp":"taxi/uservices/userver/core/src/dynamic_config/value_test.cpp",
12891289
"core/src/engine/condition_variable.cpp":"taxi/uservices/userver/core/src/engine/condition_variable.cpp",
12901290
"core/src/engine/condition_variable_test.cpp":"taxi/uservices/userver/core/src/engine/condition_variable_test.cpp",
1291+
"core/src/engine/coro/marked_allocator.cpp":"taxi/uservices/userver/core/src/engine/coro/marked_allocator.cpp",
1292+
"core/src/engine/coro/marked_allocator.hpp":"taxi/uservices/userver/core/src/engine/coro/marked_allocator.hpp",
12911293
"core/src/engine/coro/pool.cpp":"taxi/uservices/userver/core/src/engine/coro/pool.cpp",
12921294
"core/src/engine/coro/pool.hpp":"taxi/uservices/userver/core/src/engine/coro/pool.hpp",
12931295
"core/src/engine/coro/pool_config.cpp":"taxi/uservices/userver/core/src/engine/coro/pool_config.cpp",
@@ -3841,20 +3843,27 @@
38413843
"scripts/docs/scripts/toc.js":"taxi/uservices/userver/scripts/docs/scripts/toc.js",
38423844
"scripts/docs/upload_docs.sh":"taxi/uservices/userver/scripts/docs/upload_docs.sh",
38433845
"scripts/gdb/gen_gdb_printers.py":"taxi/uservices/userver/scripts/gdb/gen_gdb_printers.py",
3846+
"scripts/gdb/include/pretty_printers/third_party/moodycamel/extractor.hpp":"taxi/uservices/userver/scripts/gdb/include/pretty_printers/third_party/moodycamel/extractor.hpp",
3847+
"scripts/gdb/pretty_printers/cmd/utask/cmd.py":"taxi/uservices/userver/scripts/gdb/pretty_printers/cmd/utask/cmd.py",
38443848
"scripts/gdb/pretty_printers/formats/__init__.py":"taxi/uservices/userver/scripts/gdb/pretty_printers/formats/__init__.py",
38453849
"scripts/gdb/pretty_printers/formats/json/__init__.py":"taxi/uservices/userver/scripts/gdb/pretty_printers/formats/json/__init__.py",
38463850
"scripts/gdb/pretty_printers/formats/json/printers.py":"taxi/uservices/userver/scripts/gdb/pretty_printers/formats/json/printers.py",
38473851
"scripts/gdb/pretty_printers/formats/yaml/__init__.py":"taxi/uservices/userver/scripts/gdb/pretty_printers/formats/yaml/__init__.py",
3852+
"scripts/gdb/pretty_printers/third_party/moodycamel/printers.py":"taxi/uservices/userver/scripts/gdb/pretty_printers/third_party/moodycamel/printers.py",
38483853
"scripts/gdb/tests/CMakeLists.txt":"taxi/uservices/userver/scripts/gdb/tests/CMakeLists.txt",
38493854
"scripts/gdb/tests/gen_gdb_printers_tests.py":"taxi/uservices/userver/scripts/gdb/tests/gen_gdb_printers_tests.py",
3855+
"scripts/gdb/tests/include/CMakeLists.txt":"taxi/uservices/userver/scripts/gdb/tests/include/CMakeLists.txt",
38503856
"scripts/gdb/tests/include/userver/gdb_tests/stub.hpp":"taxi/uservices/userver/scripts/gdb/tests/include/userver/gdb_tests/stub.hpp",
38513857
"scripts/gdb/tests/src/CMakeLists.txt":"taxi/uservices/userver/scripts/gdb/tests/src/CMakeLists.txt",
3858+
"scripts/gdb/tests/src/cmd/CMakeLists.txt":"taxi/uservices/userver/scripts/gdb/tests/src/cmd/CMakeLists.txt",
3859+
"scripts/gdb/tests/src/cmd/utask/CMakeLists.txt":"taxi/uservices/userver/scripts/gdb/tests/src/cmd/utask/CMakeLists.txt",
3860+
"scripts/gdb/tests/src/cmd/utask/gdb_test_utask.cpp":"taxi/uservices/userver/scripts/gdb/tests/src/cmd/utask/gdb_test_utask.cpp",
38523861
"scripts/gdb/tests/src/formats/CMakeLists.txt":"taxi/uservices/userver/scripts/gdb/tests/src/formats/CMakeLists.txt",
38533862
"scripts/gdb/tests/src/formats/json/CMakeLists.txt":"taxi/uservices/userver/scripts/gdb/tests/src/formats/json/CMakeLists.txt",
38543863
"scripts/gdb/tests/src/formats/json/gdb_test_json.cpp":"taxi/uservices/userver/scripts/gdb/tests/src/formats/json/gdb_test_json.cpp",
3855-
"scripts/gdb/tests/src/formats/json/ya.make":"taxi/uservices/userver/scripts/gdb/tests/src/formats/json/ya.make",
3856-
"scripts/gdb/tests/src/formats/ya.make":"taxi/uservices/userver/scripts/gdb/tests/src/formats/ya.make",
3857-
"scripts/gdb/tests/src/ya.make":"taxi/uservices/userver/scripts/gdb/tests/src/ya.make",
3864+
"scripts/gdb/tests/src/third_party/CMakeLists.txt":"taxi/uservices/userver/scripts/gdb/tests/src/third_party/CMakeLists.txt",
3865+
"scripts/gdb/tests/src/third_party/moodycamel/CMakeLists.txt":"taxi/uservices/userver/scripts/gdb/tests/src/third_party/moodycamel/CMakeLists.txt",
3866+
"scripts/gdb/tests/src/third_party/moodycamel/gdb_test_moodycamel.cpp":"taxi/uservices/userver/scripts/gdb/tests/src/third_party/moodycamel/gdb_test_moodycamel.cpp",
38583867
"scripts/gdb/tests/test_printers.py":"taxi/uservices/userver/scripts/gdb/tests/test_printers.py",
38593868
"scripts/gdb/update_gdbinit.py":"taxi/uservices/userver/scripts/gdb/update_gdbinit.py",
38603869
"scripts/grpc/__init__.py":"taxi/uservices/userver/scripts/grpc/__init__.py",

cmake/GenGdbPrinters.cmake

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ include_guard(GLOBAL)
33
include("${CMAKE_CURRENT_LIST_DIR}/UserverCodegenTarget.cmake")
44
include("${CMAKE_CURRENT_LIST_DIR}/UserverVenv.cmake")
55

6-
function(gen_gdb_printers TARGET STRUCTURE)
6+
function(_gen_gdb_impl TARGET STRUCTURE FILENAME)
77
# Set the path to the Python script
8-
set(PRINTER_PYTHON_SCRIPT "${USERVER_ROOT_DIR}/scripts/gdb/pretty_printers/${STRUCTURE}/printers.py")
8+
set(PRINTER_PYTHON_SCRIPT "${USERVER_ROOT_DIR}/scripts/gdb/pretty_printers/${STRUCTURE}/${FILENAME}.py")
99
set(GDB_AUTOGEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/gdb_autogen")
1010

1111
# Set the output header file path in the build directory
12-
set(OUTPUT_HEADER "${GDB_AUTOGEN_DIR}/gdb_autogen/${STRUCTURE}/printers.hpp")
12+
set(OUTPUT_HEADER "${GDB_AUTOGEN_DIR}/gdb_autogen/${STRUCTURE}/${FILENAME}.hpp")
1313

1414
# Create the output directory if it doesn't exist
1515
get_filename_component(OUTPUT_HEADER_DIR "${OUTPUT_HEADER}" DIRECTORY)
@@ -32,5 +32,16 @@ function(gen_gdb_printers TARGET STRUCTURE)
3232
# Add the generated header to the target's sources
3333
target_sources(${TARGET} PRIVATE "${OUTPUT_HEADER}")
3434

35-
target_include_directories(${TARGET} PRIVATE "${GDB_AUTOGEN_DIR}")
35+
target_include_directories(${TARGET}
36+
PRIVATE "${GDB_AUTOGEN_DIR}"
37+
PRIVATE "${USERVER_ROOT_DIR}/scripts/gdb/include"
38+
)
39+
endfunction()
40+
41+
function(gen_gdb_printers TARGET STRUCTURE)
42+
_gen_gdb_impl(${TARGET} ${STRUCTURE} "printers")
43+
endfunction()
44+
45+
function(gen_gdb_cmd TARGET STRUCTURE)
46+
_gen_gdb_impl(${TARGET} ${STRUCTURE} "cmd")
3647
endfunction()

core/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ add_library(${PROJECT_NAME} STATIC ${SOURCES})
8080
# that migrates coroutines between threads.
8181
target_compile_definitions(${PROJECT_NAME} PUBLIC MOODYCAMEL_NO_THREAD_LOCAL)
8282

83+
include(GenGdbPrinters)
84+
gen_gdb_printers(${PROJECT_NAME} "third_party/moodycamel")
85+
gen_gdb_cmd(${PROJECT_NAME} "cmd/utask")
86+
8387
if (USERVER_DISABLE_PHDR_CACHE)
8488
target_compile_definitions(${PROJECT_NAME} PRIVATE USERVER_DISABLE_PHDR_CACHE)
8589
endif()

core/include/userver/tracing/span.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ class Span final {
221221
const std::string& GetSpanId() const;
222222
const std::string& GetParentId() const;
223223

224+
/// Get name the Span was created with
225+
const std::string& GetName() const;
226+
224227
/// @returns true if this span would be logged with the current local and
225228
/// global log levels to the default logger.
226229
bool ShouldLogDefault() const noexcept;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <engine/coro/marked_allocator.hpp>
2+
3+
USERVER_NAMESPACE_BEGIN
4+
5+
namespace engine::coro::debug {
6+
7+
static volatile const std::size_t page_size = MarkedAllocator::traits_type::page_size();
8+
static volatile std::size_t allocator_stack_size = MarkedAllocator::traits_type::default_size();
9+
10+
MarkedAllocator::MarkedAllocator(std::size_t size) : boost::coroutines2::protected_fixedsize_stack(size) {
11+
auto aligment = page_size;
12+
allocator_stack_size = (size + aligment - 1) / aligment * aligment;
13+
}
14+
15+
} // namespace engine::coro::debug
16+
17+
USERVER_NAMESPACE_END
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
#include <boost/coroutine2/protected_fixedsize_stack.hpp>
4+
5+
USERVER_NAMESPACE_BEGIN
6+
7+
namespace engine::coro::debug {
8+
9+
struct MarkedAllocator : boost::coroutines2::protected_fixedsize_stack {
10+
MarkedAllocator(std::size_t size = traits_type::default_size());
11+
12+
const char kCoroutineMark[16] = "ThisIsCoroAlloc";
13+
};
14+
15+
} // namespace engine::coro::debug
16+
17+
USERVER_NAMESPACE_END

core/src/engine/coro/pool.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <moodycamel/concurrentqueue.h>
77

8+
#include <engine/coro/marked_allocator.hpp>
89
#include <engine/coro/pool_config.hpp>
910
#include <engine/coro/pool_stats.hpp>
1011
#include <engine/coro/stack_usage_monitor.hpp>
@@ -60,10 +61,10 @@ class Pool final {
6061
// outside of any coroutine.
6162
static inline thread_local std::vector<Coroutine> local_coro_buffer_;
6263

63-
boost::coroutines2::protected_fixedsize_stack stack_allocator_;
64+
debug::MarkedAllocator stack_allocator_;
6465
// Some pointers arithmetic in StackUsageMonitor depends on this.
6566
// If you change the allocator, adjust the math there accordingly.
66-
static_assert(std::is_same_v<decltype(stack_allocator_), boost::coroutines2::protected_fixedsize_stack>);
67+
static_assert(std::is_base_of_v<boost::coroutines2::protected_fixedsize_stack, decltype(stack_allocator_)>);
6768
StackUsageMonitor stack_usage_monitor_;
6869

6970
// We aim to reuse coroutines as much as possible,

core/src/engine/coro/stack_usage_monitor.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ constexpr std::size_t kStackUsageMonitorLimit = 1000;
4646

4747
std::size_t GetCurrentTaskStackUsageBytes() noexcept;
4848

49+
const void* GetCoroCbPtr(const boost::coroutines2::coroutine<impl::TaskContext*>::push_type& coro) noexcept;
50+
4951
} // namespace engine::coro
5052

5153
USERVER_NAMESPACE_END

core/src/engine/task/task_context.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include <engine/task/cxxabi_eh_globals.hpp>
2828
#include <engine/task/task_processor.hpp>
2929

30+
#include <gdb_autogen/cmd/utask/cmd.hpp>
31+
3032
USERVER_NAMESPACE_BEGIN
3133

3234
namespace engine {

core/src/engine/task/task_queue.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
#include <engine/task/task_context.hpp>
44

5+
#include <gdb_autogen/third_party/moodycamel/printers.hpp>
6+
#include <pretty_printers/third_party/moodycamel/extractor.hpp>
7+
58
USERVER_NAMESPACE_BEGIN
69

710
namespace engine {
@@ -11,7 +14,9 @@ constexpr std::size_t kSemaphoreInitialCount = 0;
1114
}
1215

1316
TaskQueue::TaskQueue(const TaskProcessorConfig& config)
14-
: queue_semaphore_(kSemaphoreInitialCount, config.spinning_iterations) {}
17+
: queue_semaphore_(kSemaphoreInitialCount, config.spinning_iterations) {
18+
moodycamel_extractor::instantiate(queue_);
19+
}
1520

1621
void TaskQueue::Push(boost::intrusive_ptr<impl::TaskContext>&& context) {
1722
UASSERT(context);

0 commit comments

Comments
 (0)