diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-09-10 16:38:41 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-09-10 16:38:41 +0200 |
| commit | c63a0f8e7ed7a2d88cb24a46a6fd8e409f35756b (patch) | |
| tree | a39f38114423bd6068be6812c7e8322dda834499 /kapi | |
| parent | 3ce0197e99ecea7be66decc2c3c6f785497ef862 (diff) | |
| download | kernel-c63a0f8e7ed7a2d88cb24a46a6fd8e409f35756b.tar.xz kernel-c63a0f8e7ed7a2d88cb24a46a6fd8e409f35756b.zip | |
kapi/system: reduce panic buffer size
Previously, we allocated a 512-byte buffer for every call of the
formatted panic function. This was heavily increasing the stack size for
a number of functions.
We now don't print to a statically allocated buffer, but rather use the
iterator-based formatting facility and a proxy iterator with a small,
self-flushing buffer. This reduces that static overhead of the formatted
panic function to by almost 500 bytes, while increasing possible message
fidelity, since we are not longer arbitrarily limited by the buffer.
Diffstat (limited to 'kapi')
| -rw-r--r-- | kapi/kapi/system.hpp | 102 |
1 files changed, 78 insertions, 24 deletions
diff --git a/kapi/kapi/system.hpp b/kapi/kapi/system.hpp index 80233507..d8a306d3 100644 --- a/kapi/kapi/system.hpp +++ b/kapi/kapi/system.hpp @@ -6,8 +6,8 @@ #include <array> #include <cstddef> +#include <iterator> #include <source_location> -#include <span> #include <string_view> #include <type_traits> @@ -17,25 +17,76 @@ namespace kapi::system //! @addtogroup kapi-system-kernel-defined //! @{ - template<typename... FormatArguments> - struct panic_format_string + namespace detail { - kstd::format_string<FormatArguments...> format; - std::source_location location; - - template<std::size_t Size> - consteval panic_format_string(char const (&format)[Size], // NOLINT - std::source_location location = std::source_location::current()) - : format{format} - , location{location} - {} - - consteval panic_format_string(std::string_view format, - std::source_location location = std::source_location::current()) - : format{format} - , location{location} - {} - }; + template<typename... FormatArguments> + struct panic_format_string + { + kstd::format_string<FormatArguments...> format; + std::source_location location; + + template<std::size_t Size> + consteval panic_format_string(char const (&format)[Size], // NOLINT + std::source_location location = std::source_location::current()) + : format{format} + , location{location} + {} + + consteval panic_format_string(std::string_view format, + std::source_location location = std::source_location::current()) + : format{format} + , location{location} + {} + }; + + struct panic_buffer + { + ~panic_buffer(); + + void append(char character); + void flush(); + + private: + std::array<char, 16> m_buffer{}; + std::size_t m_written{}; + }; + + struct panic_iterator + { + using iterator_category = std::output_iterator_tag; + using iterator_concept = std::output_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = void; + using pointer = void; + using reference = void; + + explicit panic_iterator(panic_buffer & buffer); + + auto operator*() noexcept -> panic_iterator &; + auto operator=(char character) -> panic_iterator &; + auto operator++() -> panic_iterator &; + auto operator++(int) -> panic_iterator; + + private: + panic_buffer * m_buffer; + }; + + } // namespace detail + + //! Initiate panic processing. + //! + //! @param location The location where the panic occurred. + auto panic_start(std::source_location location) -> void; + + //! Write panic output. + //! + //! @param message The message to write. + auto panic_write(std::string_view message) -> void; + + //! Finish panic processing + //! + //! @param location The location where the panic occurred. + [[noreturn]] auto panic_finish(std::source_location location) -> void; //! Terminate kernel execution with the given error message. //! @@ -61,14 +112,17 @@ namespace kapi::system auto memory_initialized() -> void; //! @} // end group platform-defined - // + template<typename... FormatArguments> - [[noreturn]] auto panic(panic_format_string<std::type_identity_t<FormatArguments>...> format, + [[noreturn]] auto panic(detail::panic_format_string<std::type_identity_t<FormatArguments>...> format, FormatArguments &&... arguments) { - auto buffer = std::array<char, 512uz>{}; - auto [_, length] = kstd::format_to(std::span{buffer}, format.format, std::forward<FormatArguments>(arguments)...); - panic(std::string_view{buffer.data(), length}, format.location); + panic_start(format.location); + { + auto buffer = detail::panic_buffer{}; + kstd::format_to(detail::panic_iterator{buffer}, format.format, std::forward<FormatArguments>(arguments)...); + } + panic_finish(format.location); } } // namespace kapi::system |
