From 41b63e23cced89abfe174acc07a743630cb4af78 Mon Sep 17 00:00:00 2001 From: Alexander Polyakov Date: Mon, 18 May 2026 21:07:19 +0300 Subject: [PATCH 1/2] [k2] use initial-exec TLS model for performance critical thread locals --- runtime-light/k2-platform/k2-api.h | 18 ++++++++++++------ runtime-light/runtime-light.cpp | 27 ++++++++++++++++----------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/runtime-light/k2-platform/k2-api.h b/runtime-light/k2-platform/k2-api.h index 9eb8f2b445..a354de1a36 100644 --- a/runtime-light/k2-platform/k2-api.h +++ b/runtime-light/k2-platform/k2-api.h @@ -29,11 +29,17 @@ namespace k2 { -namespace k2_impl_ { +namespace details { inline constexpr size_t DEFAULT_MEMORY_ALIGN = 16; -} // namespace k2_impl_ +#define TLS_INITIAL_EXEC __attribute__((tls_model("initial-exec"))) + +TLS_INITIAL_EXEC inline thread_local const ImageState* image_state_ptr{}; // NOLINT +TLS_INITIAL_EXEC inline thread_local const ComponentState* component_state_ptr{}; // NOLINT +TLS_INITIAL_EXEC inline thread_local InstanceState* instance_state_ptr{}; // NOLINT + +} // namespace details inline constexpr int32_t errno_ok = 0; inline constexpr int32_t errno_e2big = E2BIG; @@ -82,15 +88,15 @@ inline const ControlFlags* control_flags() noexcept { } inline const ImageState* image_state() noexcept { - return k2_image_state(); + return details::image_state_ptr; } inline const ComponentState* component_state() noexcept { - return k2_component_state(); + return details::component_state_ptr; } inline InstanceState* instance_state() noexcept { - return k2_instance_state(); + return details::instance_state_ptr; } inline void* alloc_align(size_t size, size_t align) noexcept { @@ -98,7 +104,7 @@ inline void* alloc_align(size_t size, size_t align) noexcept { } inline void* alloc(size_t size) noexcept { - return k2::alloc_align(size, k2_impl_::DEFAULT_MEMORY_ALIGN); + return k2::alloc_align(size, details::DEFAULT_MEMORY_ALIGN); } inline void* realloc(void* ptr, size_t new_size) noexcept { diff --git a/runtime-light/runtime-light.cpp b/runtime-light/runtime-light.cpp index 7e6bbd7c38..dfe61b379c 100644 --- a/runtime-light/runtime-light.cpp +++ b/runtime-light/runtime-light.cpp @@ -7,6 +7,7 @@ #include "runtime-light/core/globals/php-init-scripts.h" #include "runtime-light/coroutine/io-scheduler.h" #include "runtime-light/k2-platform/k2-api.h" +#include "runtime-light/k2-platform/k2-header.h" #include "runtime-light/state/component-state.h" #include "runtime-light/state/image-state.h" #include "runtime-light/state/instance-state.h" @@ -15,43 +16,44 @@ #define VISIBILITY_DEFAULT __attribute__((visibility("default"))) VISIBILITY_DEFAULT ImageState* k2_create_image() { - kphp::log::debug("start image state creation, requested {} bytes", sizeof(ImageState)); - auto* image_state_ptr{static_cast(k2::alloc(sizeof(ImageState)))}; - kphp::log::assertion(image_state_ptr != nullptr); // Not enough memory for image state - kphp::log::debug("finish image state creation"); - return image_state_ptr; + return static_cast(k2::alloc_align(sizeof(ImageState), alignof(ImageState))); } VISIBILITY_DEFAULT void k2_init_image() { - kphp::log::debug("start image state init"); + k2::details::image_state_ptr = k2_image_state(); new (const_cast(k2::image_state())) ImageState{}; init_php_scripts_once_in_master(); - kphp::log::debug("finish image state init"); } VISIBILITY_DEFAULT ComponentState* k2_create_component() { + k2::details::image_state_ptr = k2_image_state(); kphp::log::debug("start component state creation, requested {} bytes", sizeof(ComponentState)); - auto* component_state_ptr{static_cast(k2::alloc(sizeof(ComponentState)))}; - kphp::log::assertion(component_state_ptr != nullptr); // Not enough memory for component state + auto* component_state_ptr{static_cast(k2::alloc_align(sizeof(ComponentState), alignof(ComponentState)))}; kphp::log::debug("finish component state creation"); return component_state_ptr; } VISIBILITY_DEFAULT void k2_init_component() { + k2::details::image_state_ptr = k2_image_state(); + k2::details::component_state_ptr = k2_component_state(); kphp::log::debug("start component state init"); new (const_cast(k2::component_state())) ComponentState{}; kphp::log::debug("finish component state init"); } VISIBILITY_DEFAULT InstanceState* k2_create_instance() { + k2::details::image_state_ptr = k2_image_state(); + k2::details::component_state_ptr = k2_component_state(); kphp::log::debug("start instance state creation, requested {} bytes", sizeof(InstanceState)); - auto* instance_state_ptr{static_cast(k2::alloc(sizeof(InstanceState)))}; - kphp::log::assertion(instance_state_ptr != nullptr); // Not enough memory for instance state + auto* instance_state_ptr{static_cast(k2::alloc_align(sizeof(InstanceState), alignof(InstanceState)))}; kphp::log::debug("finish instance state creation"); return instance_state_ptr; } VISIBILITY_DEFAULT void k2_init_instance() { + k2::details::image_state_ptr = k2_image_state(); + k2::details::component_state_ptr = k2_component_state(); + k2::details::instance_state_ptr = k2_instance_state(); kphp::log::debug("start instance state init"); new (k2::instance_state()) InstanceState{}; k2::instance_state()->init_script_execution(); @@ -59,6 +61,9 @@ VISIBILITY_DEFAULT void k2_init_instance() { } VISIBILITY_DEFAULT k2::PollStatus k2_poll() { + k2::details::image_state_ptr = k2_image_state(); + k2::details::component_state_ptr = k2_component_state(); + k2::details::instance_state_ptr = k2_instance_state(); kphp::log::debug("k2_poll started"); const auto poll_status{kphp::coro::io_scheduler::get().process_events()}; kphp::log::debug("k2_poll finished: {}", std::to_underlying(poll_status)); From 5d733f67f45f562ad0791f224727f6902b4de5ea Mon Sep 17 00:00:00 2001 From: Alexander Polyakov Date: Thu, 21 May 2026 18:54:11 +0300 Subject: [PATCH 2/2] address review notes --- runtime-light/k2-platform/k2-api.h | 2 ++ runtime-light/runtime-light.cpp | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/runtime-light/k2-platform/k2-api.h b/runtime-light/k2-platform/k2-api.h index a354de1a36..26b3e5e775 100644 --- a/runtime-light/k2-platform/k2-api.h +++ b/runtime-light/k2-platform/k2-api.h @@ -39,6 +39,8 @@ TLS_INITIAL_EXEC inline thread_local const ImageState* image_state_ptr{}; TLS_INITIAL_EXEC inline thread_local const ComponentState* component_state_ptr{}; // NOLINT TLS_INITIAL_EXEC inline thread_local InstanceState* instance_state_ptr{}; // NOLINT +#undef TLS_INITIAL_EXEC + } // namespace details inline constexpr int32_t errno_ok = 0; diff --git a/runtime-light/runtime-light.cpp b/runtime-light/runtime-light.cpp index dfe61b379c..e65f3a0966 100644 --- a/runtime-light/runtime-light.cpp +++ b/runtime-light/runtime-light.cpp @@ -16,17 +16,24 @@ #define VISIBILITY_DEFAULT __attribute__((visibility("default"))) VISIBILITY_DEFAULT ImageState* k2_create_image() { + k2::details::image_state_ptr = nullptr; + k2::details::component_state_ptr = nullptr; + k2::details::instance_state_ptr = nullptr; return static_cast(k2::alloc_align(sizeof(ImageState), alignof(ImageState))); } VISIBILITY_DEFAULT void k2_init_image() { k2::details::image_state_ptr = k2_image_state(); + k2::details::component_state_ptr = nullptr; + k2::details::instance_state_ptr = nullptr; new (const_cast(k2::image_state())) ImageState{}; init_php_scripts_once_in_master(); } VISIBILITY_DEFAULT ComponentState* k2_create_component() { k2::details::image_state_ptr = k2_image_state(); + k2::details::component_state_ptr = nullptr; + k2::details::instance_state_ptr = nullptr; kphp::log::debug("start component state creation, requested {} bytes", sizeof(ComponentState)); auto* component_state_ptr{static_cast(k2::alloc_align(sizeof(ComponentState), alignof(ComponentState)))}; kphp::log::debug("finish component state creation"); @@ -36,6 +43,7 @@ VISIBILITY_DEFAULT ComponentState* k2_create_component() { VISIBILITY_DEFAULT void k2_init_component() { k2::details::image_state_ptr = k2_image_state(); k2::details::component_state_ptr = k2_component_state(); + k2::details::instance_state_ptr = nullptr; kphp::log::debug("start component state init"); new (const_cast(k2::component_state())) ComponentState{}; kphp::log::debug("finish component state init"); @@ -44,6 +52,7 @@ VISIBILITY_DEFAULT void k2_init_component() { VISIBILITY_DEFAULT InstanceState* k2_create_instance() { k2::details::image_state_ptr = k2_image_state(); k2::details::component_state_ptr = k2_component_state(); + k2::details::instance_state_ptr = nullptr; kphp::log::debug("start instance state creation, requested {} bytes", sizeof(InstanceState)); auto* instance_state_ptr{static_cast(k2::alloc_align(sizeof(InstanceState), alignof(InstanceState)))}; kphp::log::debug("finish instance state creation");