From 50eb5a93c5d64976a4ebbc3d1571531716036802 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Fri, 3 Apr 2026 18:25:45 +0300 Subject: [PATCH 01/11] [k2] support file_get_contents --- .../stdlib/file/file-system-functions.h | 32 ++++--------------- runtime-light/stdlib/file/resource.h | 27 +++++++++++++++- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/runtime-light/stdlib/file/file-system-functions.h b/runtime-light/stdlib/file/file-system-functions.h index bdc3ece9c7..5a84100fe2 100644 --- a/runtime-light/stdlib/file/file-system-functions.h +++ b/runtime-light/stdlib/file/file-system-functions.h @@ -16,9 +16,7 @@ #include #include -#include "runtime-common/core/allocator/script-allocator.h" #include "runtime-common/core/runtime-core.h" -#include "runtime-common/core/std/containers.h" #include "runtime-common/stdlib/array/array-functions.h" #include "runtime-common/stdlib/string/string-functions.h" #include "runtime-light/coroutine/task.h" @@ -204,40 +202,22 @@ inline Optional f$file_get_contents(const string& stream) noexcept { } inline Optional> f$file(const string& name) noexcept { - struct stat stat_buf {}; - auto expected_file{kphp::fs::file::open(name.c_str(), "r")}; if (!expected_file.has_value()) { return false; } - if (!k2::stat({name.c_str(), name.size()}, std::addressof(stat_buf)).has_value()) { - return false; - } - if (!S_ISREG(stat_buf.st_mode)) { - kphp::log::warning("regular file expected as first argument in function file, \"{}\" is given", name.c_str()); - return false; - } - const size_t size{static_cast(stat_buf.st_size)}; - if (size > string::max_size()) { - kphp::log::warning("file \"{}\" is too large", name.c_str()); + auto expected_file_content{std::move(*expected_file).get_contents()}; + if (!expected_file_content.has_value()) { return false; } - - kphp::stl::vector file_content; - file_content.resize(size); - { - auto file{std::move(*expected_file)}; - if (auto expected_read_result{file.read(file_content)}; !expected_read_result.has_value() || *expected_read_result < size) { - return false; - } - } + auto file_content{std::move(*expected_file_content)}; array result; int32_t prev{-1}; - for (size_t i{0}; i < size; i++) { - if (static_cast(file_content[i]) == '\n' || i + 1 == size) { - result.push_back(string{reinterpret_cast(file_content.data()) + prev + 1, static_cast(i - prev)}); + for (size_t i{0}; i < file_content.size(); i++) { + if (static_cast(file_content[i]) == '\n' || i + 1 == file_content.size()) { + result.push_back(string{file_content.buffer() + prev + 1, static_cast(i - prev)}); prev = i; } } diff --git a/runtime-light/stdlib/file/resource.h b/runtime-light/stdlib/file/resource.h index 5300ce96e0..0db50450a0 100644 --- a/runtime-light/stdlib/file/resource.h +++ b/runtime-light/stdlib/file/resource.h @@ -17,6 +17,8 @@ #include #include +#include + #include "runtime-common/core/allocator/script-allocator.h" #include "runtime-common/core/class-instance/refcountable-php-classes.h" #include "runtime-common/core/runtime-core.h" @@ -25,6 +27,7 @@ #include "runtime-light/coroutine/task.h" #include "runtime-light/k2-platform/k2-api.h" #include "runtime-light/server/http/http-server-state.h" +#include "runtime-light/stdlib/diagnostics/logs.h" #include "runtime-light/stdlib/output/output-state.h" #include "runtime-light/streams/stream.h" @@ -146,7 +149,29 @@ inline auto file::pread(std::span buf, uint64_t offset) noexcept -> s } inline auto file::get_contents() noexcept -> std::expected { - return std::unexpected{m_descriptor != k2::INVALID_PLATFORM_DESCRIPTOR ? k2::errno_efault : k2::errno_enodev}; + struct stat stat_buf {}; + + return k2::fstat(m_descriptor, std::addressof(stat_buf)).and_then([&stat_buf, this] noexcept -> std::expected { + if (!S_ISREG(stat_buf.st_mode)) { + kphp::log::warning("regular file expected"); + return std::unexpected{k2::errno_efault}; + } + + const size_t size{static_cast(stat_buf.st_size)}; + if (size > string::max_size()) { + kphp::log::warning("file is too large"); + return std::unexpected{k2::errno_efault}; + } + + string file_content{static_cast(size), false}; + return read({reinterpret_cast(file_content.buffer()), file_content.size()}) + .and_then([size, &file_content](size_t read_result) noexcept -> std::expected { + if (read_result < size) { + return std::unexpected{k2::errno_efault}; + } + return file_content; + }); + }); } inline auto file::flush() noexcept -> std::expected { From 2583acad52e1e6aea995c094a3b1022fed9da2b5 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Mon, 6 Apr 2026 11:36:50 +0300 Subject: [PATCH 02/11] pass std::string_view into file::open --- runtime-light/stdlib/file/file-system-functions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-light/stdlib/file/file-system-functions.h b/runtime-light/stdlib/file/file-system-functions.h index 5a84100fe2..08142ef14a 100644 --- a/runtime-light/stdlib/file/file-system-functions.h +++ b/runtime-light/stdlib/file/file-system-functions.h @@ -202,7 +202,7 @@ inline Optional f$file_get_contents(const string& stream) noexcept { } inline Optional> f$file(const string& name) noexcept { - auto expected_file{kphp::fs::file::open(name.c_str(), "r")}; + auto expected_file{kphp::fs::file::open({name.c_str(), name.size()}, "r")}; if (!expected_file.has_value()) { return false; } From 3c5f4c7487370d9d92b07604b4d30be96a290f11 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Mon, 6 Apr 2026 11:48:43 +0300 Subject: [PATCH 03/11] do not use lambdas --- runtime-light/stdlib/file/resource.h | 40 +++++++++++++++------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/runtime-light/stdlib/file/resource.h b/runtime-light/stdlib/file/resource.h index 0db50450a0..f45a863446 100644 --- a/runtime-light/stdlib/file/resource.h +++ b/runtime-light/stdlib/file/resource.h @@ -151,27 +151,29 @@ inline auto file::pread(std::span buf, uint64_t offset) noexcept -> s inline auto file::get_contents() noexcept -> std::expected { struct stat stat_buf {}; - return k2::fstat(m_descriptor, std::addressof(stat_buf)).and_then([&stat_buf, this] noexcept -> std::expected { - if (!S_ISREG(stat_buf.st_mode)) { - kphp::log::warning("regular file expected"); - return std::unexpected{k2::errno_efault}; - } + if (auto expected{k2::fstat(m_descriptor, std::addressof(stat_buf))}; !expected.has_value()) { + return std::unexpected{expected.error()}; + } + if (!S_ISREG(stat_buf.st_mode)) { + kphp::log::warning("regular file expected"); + return std::unexpected{k2::errno_efault}; + } - const size_t size{static_cast(stat_buf.st_size)}; - if (size > string::max_size()) { - kphp::log::warning("file is too large"); - return std::unexpected{k2::errno_efault}; - } + const size_t size{static_cast(stat_buf.st_size)}; + if (size > string::max_size()) { + kphp::log::warning("file is too large"); + return std::unexpected{k2::errno_efault}; + } - string file_content{static_cast(size), false}; - return read({reinterpret_cast(file_content.buffer()), file_content.size()}) - .and_then([size, &file_content](size_t read_result) noexcept -> std::expected { - if (read_result < size) { - return std::unexpected{k2::errno_efault}; - } - return file_content; - }); - }); + string file_content{static_cast(size), false}; + auto expected_read_result{read({reinterpret_cast(file_content.buffer()), file_content.size()})}; + if (!expected_read_result.has_value()) { + return std::unexpected{expected_read_result.error()}; + } + if (*expected_read_result < size) { + return std::unexpected{k2::errno_efault}; + } + return file_content; } inline auto file::flush() noexcept -> std::expected { From 9f97cbbd5752c1644bd2375bd3b325004b13d2b1 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Mon, 6 Apr 2026 11:55:46 +0300 Subject: [PATCH 04/11] error handling --- runtime-light/stdlib/file/file-system-functions.h | 1 + runtime-light/stdlib/file/resource.h | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/runtime-light/stdlib/file/file-system-functions.h b/runtime-light/stdlib/file/file-system-functions.h index 08142ef14a..21faef6e99 100644 --- a/runtime-light/stdlib/file/file-system-functions.h +++ b/runtime-light/stdlib/file/file-system-functions.h @@ -209,6 +209,7 @@ inline Optional> f$file(const string& name) noexcept { auto expected_file_content{std::move(*expected_file).get_contents()}; if (!expected_file_content.has_value()) { + kphp::log::warning("file::get_contents returned code {}", expected_file_content.error()); return false; } auto file_content{std::move(*expected_file_content)}; diff --git a/runtime-light/stdlib/file/resource.h b/runtime-light/stdlib/file/resource.h index f45a863446..2237fba2e3 100644 --- a/runtime-light/stdlib/file/resource.h +++ b/runtime-light/stdlib/file/resource.h @@ -27,7 +27,6 @@ #include "runtime-light/coroutine/task.h" #include "runtime-light/k2-platform/k2-api.h" #include "runtime-light/server/http/http-server-state.h" -#include "runtime-light/stdlib/diagnostics/logs.h" #include "runtime-light/stdlib/output/output-state.h" #include "runtime-light/streams/stream.h" @@ -155,13 +154,11 @@ inline auto file::get_contents() noexcept -> std::expected { return std::unexpected{expected.error()}; } if (!S_ISREG(stat_buf.st_mode)) { - kphp::log::warning("regular file expected"); return std::unexpected{k2::errno_efault}; } const size_t size{static_cast(stat_buf.st_size)}; if (size > string::max_size()) { - kphp::log::warning("file is too large"); return std::unexpected{k2::errno_efault}; } From 2e13a292f7e4abf763042ab58173bd573af2c187 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Mon, 6 Apr 2026 11:59:59 +0300 Subject: [PATCH 05/11] use `std::as_writable_bytes` --- runtime-light/stdlib/file/resource.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-light/stdlib/file/resource.h b/runtime-light/stdlib/file/resource.h index 2237fba2e3..78b1141e28 100644 --- a/runtime-light/stdlib/file/resource.h +++ b/runtime-light/stdlib/file/resource.h @@ -163,7 +163,7 @@ inline auto file::get_contents() noexcept -> std::expected { } string file_content{static_cast(size), false}; - auto expected_read_result{read({reinterpret_cast(file_content.buffer()), file_content.size()})}; + auto expected_read_result{read(std::as_writable_bytes(std::span{file_content.buffer(), file_content.size()}))}; if (!expected_read_result.has_value()) { return std::unexpected{expected_read_result.error()}; } From b009a1c3b930dcab7745247f09ede7a3130554c6 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Mon, 6 Apr 2026 12:08:19 +0300 Subject: [PATCH 06/11] enable gzip test --- tests/phpt/dl/464_gzip.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpt/dl/464_gzip.php b/tests/phpt/dl/464_gzip.php index 3e540200b8..0de0bce821 100644 --- a/tests/phpt/dl/464_gzip.php +++ b/tests/phpt/dl/464_gzip.php @@ -1,4 +1,4 @@ -@ok k2_skip +@ok Date: Tue, 7 Apr 2026 18:48:51 +0300 Subject: [PATCH 07/11] use mmap --- runtime-light/stdlib/file/resource.h | 81 ++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 11 deletions(-) diff --git a/runtime-light/stdlib/file/resource.h b/runtime-light/stdlib/file/resource.h index 78b1141e28..2ededcbff7 100644 --- a/runtime-light/stdlib/file/resource.h +++ b/runtime-light/stdlib/file/resource.h @@ -17,6 +17,7 @@ #include #include +#include #include #include "runtime-common/core/allocator/script-allocator.h" @@ -27,6 +28,7 @@ #include "runtime-light/coroutine/task.h" #include "runtime-light/k2-platform/k2-api.h" #include "runtime-light/server/http/http-server-state.h" +#include "runtime-light/stdlib/diagnostics/logs.h" #include "runtime-light/stdlib/output/output-state.h" #include "runtime-light/streams/stream.h" @@ -47,6 +49,71 @@ inline constexpr std::string_view UDP_SCHEME_PREFIX = "udp://"; // ================================================================================================ +class mmap { + k2::descriptor m_descriptor{k2::INVALID_PLATFORM_DESCRIPTOR}; + void* m_addr{nullptr}; + size_t m_length{}; + + mmap(k2::descriptor descriptor, void* addr, size_t length) noexcept + : m_descriptor{descriptor}, + m_addr{addr}, + m_length{length} {} + +public: + mmap(mmap&& other) noexcept + : m_descriptor{std::exchange(other.m_descriptor, k2::INVALID_PLATFORM_DESCRIPTOR)}, + m_addr{std::exchange(other.m_addr, nullptr)}, + m_length{std::exchange(other.m_length, {})} {} + + mmap& operator=(mmap&& other) noexcept { + if (this != std::addressof(other)) { + std::ignore = close(); + m_descriptor = std::exchange(other.m_descriptor, k2::INVALID_PLATFORM_DESCRIPTOR); + m_addr = std::exchange(other.m_addr, nullptr); + m_length = std::exchange(other.m_length, {}); + } + return *this; + } + + ~mmap() { + std::ignore = close(); + } + + mmap(const mmap&) = delete; + mmap& operator=(const mmap&) = delete; + + static auto create(size_t length, int32_t prot, int32_t flags, k2::descriptor fd, uint64_t offset) noexcept -> std::expected; + + auto get_contents() noexcept -> string; + auto close() noexcept -> std::expected; +}; + +inline auto mmap::create(size_t length, int32_t prot, int32_t flags, k2::descriptor fd, uint64_t offset) noexcept -> std::expected { + k2::descriptor descriptor{k2::INVALID_PLATFORM_DESCRIPTOR}; + auto* addr{k2::mmap(std::addressof(descriptor), nullptr, length, prot, flags, fd, offset)}; + if (addr == MAP_FAILED) [[unlikely]] { + return std::unexpected{k2::errno_efault}; + } + return mmap{descriptor, addr, length}; +} + +inline auto mmap::get_contents() noexcept -> string { + std::ignore = k2::madvise(m_addr, m_length, MADV_SEQUENTIAL); + string content{static_cast(m_length), false}; + std::memcpy(content.buffer(), m_addr, m_length); + return content; +} + +inline auto mmap::close() noexcept -> std::expected { + if (m_descriptor == k2::INVALID_PLATFORM_DESCRIPTOR) [[unlikely]] { + return std::unexpected{k2::errno_enodev}; + } + k2::free_descriptor(std::exchange(m_descriptor, k2::INVALID_PLATFORM_DESCRIPTOR)); + return {}; +} + +// ================================================================================================ + struct resource : public refcountable_polymorphic_php_classes { const char* get_class() const noexcept final { return "resource"; @@ -154,23 +221,15 @@ inline auto file::get_contents() noexcept -> std::expected { return std::unexpected{expected.error()}; } if (!S_ISREG(stat_buf.st_mode)) { - return std::unexpected{k2::errno_efault}; + return std::unexpected{k2::errno_einval}; } const size_t size{static_cast(stat_buf.st_size)}; if (size > string::max_size()) { - return std::unexpected{k2::errno_efault}; + return std::unexpected{k2::errno_enomem}; } - string file_content{static_cast(size), false}; - auto expected_read_result{read(std::as_writable_bytes(std::span{file_content.buffer(), file_content.size()}))}; - if (!expected_read_result.has_value()) { - return std::unexpected{expected_read_result.error()}; - } - if (*expected_read_result < size) { - return std::unexpected{k2::errno_efault}; - } - return file_content; + return kphp::fs::mmap::create(size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, m_descriptor, 0).transform(&kphp::fs::mmap::get_contents); } inline auto file::flush() noexcept -> std::expected { From c63a9c14bfac52f986421d9550e355d2e54051ff Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Wed, 8 Apr 2026 14:46:26 +0300 Subject: [PATCH 08/11] simplify mmap warpper --- runtime-light/stdlib/file/resource.h | 30 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/runtime-light/stdlib/file/resource.h b/runtime-light/stdlib/file/resource.h index 2ededcbff7..f19a9e3d4c 100644 --- a/runtime-light/stdlib/file/resource.h +++ b/runtime-light/stdlib/file/resource.h @@ -51,26 +51,22 @@ inline constexpr std::string_view UDP_SCHEME_PREFIX = "udp://"; class mmap { k2::descriptor m_descriptor{k2::INVALID_PLATFORM_DESCRIPTOR}; - void* m_addr{nullptr}; - size_t m_length{}; + std::span m_data; mmap(k2::descriptor descriptor, void* addr, size_t length) noexcept : m_descriptor{descriptor}, - m_addr{addr}, - m_length{length} {} + m_data{reinterpret_cast(addr), length} {} public: mmap(mmap&& other) noexcept : m_descriptor{std::exchange(other.m_descriptor, k2::INVALID_PLATFORM_DESCRIPTOR)}, - m_addr{std::exchange(other.m_addr, nullptr)}, - m_length{std::exchange(other.m_length, {})} {} + m_data{std::exchange(other.m_data, {})} {} mmap& operator=(mmap&& other) noexcept { if (this != std::addressof(other)) { std::ignore = close(); m_descriptor = std::exchange(other.m_descriptor, k2::INVALID_PLATFORM_DESCRIPTOR); - m_addr = std::exchange(other.m_addr, nullptr); - m_length = std::exchange(other.m_length, {}); + m_data = std::exchange(other.m_data, {}); } return *this; } @@ -84,7 +80,7 @@ class mmap { static auto create(size_t length, int32_t prot, int32_t flags, k2::descriptor fd, uint64_t offset) noexcept -> std::expected; - auto get_contents() noexcept -> string; + auto data() noexcept -> std::span; auto close() noexcept -> std::expected; }; @@ -97,11 +93,8 @@ inline auto mmap::create(size_t length, int32_t prot, int32_t flags, k2::descrip return mmap{descriptor, addr, length}; } -inline auto mmap::get_contents() noexcept -> string { - std::ignore = k2::madvise(m_addr, m_length, MADV_SEQUENTIAL); - string content{static_cast(m_length), false}; - std::memcpy(content.buffer(), m_addr, m_length); - return content; +inline auto mmap::data() noexcept -> std::span { + return m_data; } inline auto mmap::close() noexcept -> std::expected { @@ -229,7 +222,14 @@ inline auto file::get_contents() noexcept -> std::expected { return std::unexpected{k2::errno_enomem}; } - return kphp::fs::mmap::create(size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, m_descriptor, 0).transform(&kphp::fs::mmap::get_contents); + auto expected_mmap{kphp::fs::mmap::create(size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, m_descriptor, 0)}; + if (!expected_mmap.has_value()) { + return std::unexpected{expected_mmap.error()}; + } + + auto data{expected_mmap->data()}; + std::ignore = k2::madvise(reinterpret_cast(const_cast(data.data())), data.size(), MADV_SEQUENTIAL); + return string{reinterpret_cast(data.data()), static_cast(data.size())}; } inline auto file::flush() noexcept -> std::expected { From 995f2784c6dd06adc04cb28556cdf6dde2bb37d7 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Thu, 9 Apr 2026 17:10:34 +0300 Subject: [PATCH 09/11] fixes --- runtime-light/stdlib/file/file-system-functions.h | 7 ++++--- runtime-light/stdlib/file/resource.h | 9 ++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/runtime-light/stdlib/file/file-system-functions.h b/runtime-light/stdlib/file/file-system-functions.h index 21faef6e99..6fdef0c134 100644 --- a/runtime-light/stdlib/file/file-system-functions.h +++ b/runtime-light/stdlib/file/file-system-functions.h @@ -213,12 +213,13 @@ inline Optional> f$file(const string& name) noexcept { return false; } auto file_content{std::move(*expected_file_content)}; + const size_t size{file_content.size()}; array result; int32_t prev{-1}; - for (size_t i{0}; i < file_content.size(); i++) { - if (static_cast(file_content[i]) == '\n' || i + 1 == file_content.size()) { - result.push_back(string{file_content.buffer() + prev + 1, static_cast(i - prev)}); + for (size_t i{0}; i < size; i++) { + if (file_content[i] == '\n' || i + 1 == size) { + result.push_back(file_content.substr(prev + 1, static_cast(i - prev))); prev = i; } } diff --git a/runtime-light/stdlib/file/resource.h b/runtime-light/stdlib/file/resource.h index f19a9e3d4c..bd3b06cba3 100644 --- a/runtime-light/stdlib/file/resource.h +++ b/runtime-light/stdlib/file/resource.h @@ -28,7 +28,6 @@ #include "runtime-light/coroutine/task.h" #include "runtime-light/k2-platform/k2-api.h" #include "runtime-light/server/http/http-server-state.h" -#include "runtime-light/stdlib/diagnostics/logs.h" #include "runtime-light/stdlib/output/output-state.h" #include "runtime-light/streams/stream.h" @@ -80,7 +79,7 @@ class mmap { static auto create(size_t length, int32_t prot, int32_t flags, k2::descriptor fd, uint64_t offset) noexcept -> std::expected; - auto data() noexcept -> std::span; + auto data() const noexcept -> std::span; auto close() noexcept -> std::expected; }; @@ -90,10 +89,11 @@ inline auto mmap::create(size_t length, int32_t prot, int32_t flags, k2::descrip if (addr == MAP_FAILED) [[unlikely]] { return std::unexpected{k2::errno_efault}; } + std::ignore = k2::madvise(addr, length, MADV_SEQUENTIAL); return mmap{descriptor, addr, length}; } -inline auto mmap::data() noexcept -> std::span { +inline auto mmap::data() const noexcept -> std::span { return m_data; } @@ -219,7 +219,7 @@ inline auto file::get_contents() noexcept -> std::expected { const size_t size{static_cast(stat_buf.st_size)}; if (size > string::max_size()) { - return std::unexpected{k2::errno_enomem}; + return std::unexpected{k2::errno_erange}; } auto expected_mmap{kphp::fs::mmap::create(size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, m_descriptor, 0)}; @@ -228,7 +228,6 @@ inline auto file::get_contents() noexcept -> std::expected { } auto data{expected_mmap->data()}; - std::ignore = k2::madvise(reinterpret_cast(const_cast(data.data())), data.size(), MADV_SEQUENTIAL); return string{reinterpret_cast(data.data()), static_cast(data.size())}; } From 520d1b137467c71bde843fcb9832d8f0448733ac Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Fri, 10 Apr 2026 00:53:23 +0300 Subject: [PATCH 10/11] madvise method --- runtime-light/stdlib/file/resource.h | 29 ++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/runtime-light/stdlib/file/resource.h b/runtime-light/stdlib/file/resource.h index bd3b06cba3..d7023be5e6 100644 --- a/runtime-light/stdlib/file/resource.h +++ b/runtime-light/stdlib/file/resource.h @@ -13,13 +13,12 @@ #include #include #include +#include +#include #include #include #include -#include -#include - #include "runtime-common/core/allocator/script-allocator.h" #include "runtime-common/core/class-instance/refcountable-php-classes.h" #include "runtime-common/core/runtime-core.h" @@ -50,22 +49,26 @@ inline constexpr std::string_view UDP_SCHEME_PREFIX = "udp://"; class mmap { k2::descriptor m_descriptor{k2::INVALID_PLATFORM_DESCRIPTOR}; - std::span m_data; + void* m_addr{nullptr}; + size_t m_length{}; mmap(k2::descriptor descriptor, void* addr, size_t length) noexcept : m_descriptor{descriptor}, - m_data{reinterpret_cast(addr), length} {} + m_addr{addr}, + m_length{length} {} public: mmap(mmap&& other) noexcept : m_descriptor{std::exchange(other.m_descriptor, k2::INVALID_PLATFORM_DESCRIPTOR)}, - m_data{std::exchange(other.m_data, {})} {} + m_addr{std::exchange(other.m_addr, nullptr)}, + m_length{std::exchange(other.m_length, {})} {} mmap& operator=(mmap&& other) noexcept { if (this != std::addressof(other)) { std::ignore = close(); m_descriptor = std::exchange(other.m_descriptor, k2::INVALID_PLATFORM_DESCRIPTOR); - m_data = std::exchange(other.m_data, {}); + m_addr = std::exchange(other.m_addr, nullptr); + m_length = std::exchange(other.m_length, {}); } return *this; } @@ -79,6 +82,7 @@ class mmap { static auto create(size_t length, int32_t prot, int32_t flags, k2::descriptor fd, uint64_t offset) noexcept -> std::expected; + auto madvise(int32_t advise) const noexcept -> std::expected; auto data() const noexcept -> std::span; auto close() noexcept -> std::expected; }; @@ -89,12 +93,15 @@ inline auto mmap::create(size_t length, int32_t prot, int32_t flags, k2::descrip if (addr == MAP_FAILED) [[unlikely]] { return std::unexpected{k2::errno_efault}; } - std::ignore = k2::madvise(addr, length, MADV_SEQUENTIAL); return mmap{descriptor, addr, length}; } +inline auto mmap::madvise(int32_t advise) const noexcept -> std::expected { + return k2::madvise(m_addr, m_length, advise); +} + inline auto mmap::data() const noexcept -> std::span { - return m_data; + return {reinterpret_cast(m_addr), m_length}; } inline auto mmap::close() noexcept -> std::expected { @@ -227,7 +234,9 @@ inline auto file::get_contents() noexcept -> std::expected { return std::unexpected{expected_mmap.error()}; } - auto data{expected_mmap->data()}; + auto& mmap{*expected_mmap}; + std::ignore = mmap.madvise(MADV_SEQUENTIAL); + auto data{mmap.data()}; return string{reinterpret_cast(data.data()), static_cast(data.size())}; } From e704ad3fe25e587170aa145648ae0641c87bf905 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Fri, 10 Apr 2026 12:20:58 +0300 Subject: [PATCH 11/11] remove const --- runtime-light/stdlib/file/resource.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime-light/stdlib/file/resource.h b/runtime-light/stdlib/file/resource.h index d7023be5e6..f3eb83e2ea 100644 --- a/runtime-light/stdlib/file/resource.h +++ b/runtime-light/stdlib/file/resource.h @@ -82,7 +82,7 @@ class mmap { static auto create(size_t length, int32_t prot, int32_t flags, k2::descriptor fd, uint64_t offset) noexcept -> std::expected; - auto madvise(int32_t advise) const noexcept -> std::expected; + auto madvise(int32_t advise) noexcept -> std::expected; auto data() const noexcept -> std::span; auto close() noexcept -> std::expected; }; @@ -96,7 +96,7 @@ inline auto mmap::create(size_t length, int32_t prot, int32_t flags, k2::descrip return mmap{descriptor, addr, length}; } -inline auto mmap::madvise(int32_t advise) const noexcept -> std::expected { +inline auto mmap::madvise(int32_t advise) noexcept -> std::expected { return k2::madvise(m_addr, m_length, advise); }