From 208ab531bbb115219b4879394b744bcb4b379fbc Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Fri, 30 Oct 2026 18:51:50 +0900 Subject: [PATCH] 0.1.5 --- okrun maps an image or okb file rather than reading it whole; images bind openkal.map (openkal 0.18) read_all doubled a heap buffer until the file fitted and kept it for the life of the program: a 71.5 MB image held 128 MiB, every page resident. The file is now a private, writable region of itself (kal_map_file), resident only where it is touched; a file that cannot be mapped is read as before. The binding list, generated from SURFACE.txt, gains kal_map_file, kal_map_sync and kal_map_release. Pins: openkal 0.18.0, openkal-linux 0.19.0, openkal-macos 0.16.0, openkal-windows 0.14.0; ld, run, tools and bind are 0.1.5. Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com> --- bind/mcpp.toml | 2 +- docs/bind.md | 5 +++-- examples/host/mcpp.toml | 2 +- ld/mcpp.toml | 2 +- run/mcpp.toml | 10 +++++----- run/src/run.cpp | 36 ++++++++++++++++++++++++++++++++---- tools/mcpp.toml | 2 +- 7 files changed, 44 insertions(+), 15 deletions(-) diff --git a/bind/mcpp.toml b/bind/mcpp.toml index 4e5571e..37b4e06 100644 --- a/bind/mcpp.toml +++ b/bind/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "openkal-bind" -version = "0.1.4" +version = "0.1.5" # `mcpp::xpkg_request', `mcpp::decision' (protocol 15). mcpp = ">=2026.10.1.3" description = "A build plugin: a library published as an ok image (.okso) and a C header is called from a program of any system, through a binding generated from the header and libokrun." diff --git a/docs/bind.md b/docs/bind.md index 87531ff..a9d721d 100644 --- a/docs/bind.md +++ b/docs/bind.md @@ -24,10 +24,10 @@ sources = [] include_dirs = ["include"] [target.'cfg(not(os = "openkal"))'.dependencies] -openkal-run = "0.1.4" +openkal-run = "0.1.5" [build-dependencies] -openkal-bind = "0.1.4" +openkal-bind = "0.1.5" ``` ```cpp @@ -100,3 +100,4 @@ llvm toolchain's clang converts the call. | 0.1.2 | This document. Released with openkal-run 0.1.2, whose library interface it calls. | | 0.1.3 | No change of its own; released with the archive. | | 0.1.4 | No change of its own; released with the archive, whose runner starts programs in a directory it may search but not read (openkal-linux 0.18.3). | +| 0.1.5 | No change of its own; released with the archive, whose runner maps an image or okb file rather than reading it whole, and binds `openkal.map` for images (openkal 0.18). | diff --git a/examples/host/mcpp.toml b/examples/host/mcpp.toml index c45d933..ebab056 100644 --- a/examples/host/mcpp.toml +++ b/examples/host/mcpp.toml @@ -4,7 +4,7 @@ # system of each architecture with the images built once. [package] name = "okrun-host" -version = "0.1.4" +version = "0.1.5" [dependencies] openkal-run = { path = "../../run" } diff --git a/ld/mcpp.toml b/ld/mcpp.toml index 39cf7e3..b805e47 100644 --- a/ld/mcpp.toml +++ b/ld/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "openkal-ld" -version = "0.1.4" +version = "0.1.5" description = "libokld: the ok format (openkal image format) --- its definition, a reader of bytes, a checker, a signer, and a loader. Freestanding: no C library, no exceptions." license = "Apache-2.0" authors = ["mcpplibs"] diff --git a/run/mcpp.toml b/run/mcpp.toml index b6f01fa..8c57514 100644 --- a/run/mcpp.toml +++ b/run/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "openkal-run" -version = "0.1.4" +version = "0.1.5" description = "libokrun: the runner's core --- an ok image's names bound to this process's one openkal implementation, in the image's calling convention, and its entry entered." license = "Apache-2.0" authors = ["mcpplibs"] @@ -11,17 +11,17 @@ repo = "https://github.com/mcpplibs/openkal-image" kind = "lib" [dependencies] -openkal = "0.17.1" +openkal = "0.18.0" openkal-ld = { path = "../ld" } [target.linux.dependencies] -openkal-linux = "0.18.3" +openkal-linux = "0.19.0" [target.macos.dependencies] -openkal-macos = "0.15.1" +openkal-macos = "0.16.0" [target.windows.dependencies] -openkal-windows = "0.13.3" +openkal-windows = "0.14.0" # The interfaces each system's implementation provides decide one unit: where # openkal.space is provided its names are bound, and elsewhere an image that diff --git a/run/src/run.cpp b/run/src/run.cpp index 38c7480..55bd3fc 100644 --- a/run/src/run.cpp +++ b/run/src/run.cpp @@ -88,13 +88,39 @@ bool locate(const char* path, kal_dir& dir, const char*& rest) { return true; } +// A file's bytes: a region of the file (openkal.map), or a buffer it was read +// into where the file cannot be mapped. `cap' is zero for a region. struct file_bytes { unsigned char* data = nullptr; unsigned long long size = 0, cap = 0; }; +void release_bytes(unsigned char* data, unsigned long long size, unsigned long long cap) { + if (!data) return; + if (cap == 0) kal_map_release(data, static_cast(size)); + else kal_free(data, cap, 16); +} + void release_file(file_bytes& f) { - if (f.data) kal_free(f.data, f.cap, 16); + release_bytes(f.data, f.size, f.cap); f = {}; } +// THE FILE IS MAPPED, NOT READ (openkal 0.18). An image or an okb was read +// whole into a buffer that doubled as it grew and was kept for the life of the +// program: a 71.5 MB image held 128 MiB of the heap, every page of it resident. +// A region of the file is resident only where it is touched, and its pages are +// the file's. Private and writable, so a page the loader writes is copied +// rather than refused; the file never changes. +bool map_all(kal_file f, file_bytes& out) { + kal_node_info info{}; + info.self_size = sizeof info; + if (kal_fs_file_info(f, KAL_INFO_SIZE, &info) != kal_ok || info.size == 0) return false; + void* p = nullptr; + if (kal_map_file(f, 0, static_cast(info.size), KAL_MAP_WRITE, &p) != kal_ok) return false; + out.data = static_cast(p); + out.size = info.size; + out.cap = 0; + return true; +} + bool read_all(const char* path, file_bytes& out, char* why, unsigned long long cap) { kal_dir dir{}; const char* rest = nullptr; @@ -102,6 +128,7 @@ bool read_all(const char* path, file_bytes& out, char* why, unsigned long long c unsigned long n = length(rest); kal_file f{}; if (kal_fs_open(dir, rest, n, KAL_OPEN_READ, &f) != kal_ok) { text(why, cap) << path << " cannot be opened"; return false; } + if (map_all(f, out)) { kal_fs_close_file(f); return true; } const kal_stream s = kal_fs_stream(f); for (;;) { if (out.size == out.cap) { @@ -530,8 +557,8 @@ extern "C" int okrun_run_images(const okrun_image* images, unsigned long count, struct okrun_library { okld_module* module = nullptr; search s; - unsigned char* bytes = nullptr; // a file's, read here - unsigned long long cap = 0; + unsigned char* bytes = nullptr; // a file's, mapped or read here + unsigned long long size = 0, cap = 0; }; namespace { @@ -561,7 +588,7 @@ okrun_library* new_library(const okrun_options* options) { void free_library(okrun_library* lib) { if (!lib) return; - if (lib->bytes) kal_free(lib->bytes, lib->cap, 16); + release_bytes(lib->bytes, lib->size, lib->cap); kal_free(lib, sizeof(okrun_library), 16); } @@ -591,6 +618,7 @@ extern "C" okrun_library* okrun_open_library(const char* path, const okrun_optio } directory_of(found, lib->s.directory, sizeof lib->s.directory); lib->bytes = f.data; + lib->size = f.size; lib->cap = f.cap; if (!open_loaded(lib, f.data, f.size, found, why, cap)) { free_library(lib); return nullptr; } return lib; diff --git a/tools/mcpp.toml b/tools/mcpp.toml index 703dafe..e9dbdf2 100644 --- a/tools/mcpp.toml +++ b/tools/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "openkal-tools" -version = "0.1.4" +version = "0.1.5" description = "okrun, which runs an ok image on this system, and okld, the format's tool on a build machine (check, note, sign, inspect)." license = "Apache-2.0" authors = ["mcpplibs"]