From 186e91d15bf62156a552a24fe72fe5fea55b8047 Mon Sep 17 00:00:00 2001 From: Jia Lin Date: Fri, 19 Jun 2026 15:27:19 +0800 Subject: [PATCH] Add frailbox buddy allocator --- diagnostic/build-00000000.json | 81 ++++++++- diagnostic/build-00000000.logd | Bin 33 -> 52509 bytes frailbox/include/buddy.h | 38 ++++ frailbox/src/buddy.c | 317 +++++++++++++++++++++++++++++++++ frailbox/tests/test_buddy.c | 74 ++++++++ 5 files changed, 501 insertions(+), 9 deletions(-) create mode 100644 frailbox/include/buddy.h create mode 100644 frailbox/src/buddy.c create mode 100644 frailbox/tests/test_buddy.c diff --git a/diagnostic/build-00000000.json b/diagnostic/build-00000000.json index 33e2ca62f..d6e9ab7cd 100644 --- a/diagnostic/build-00000000.json +++ b/diagnostic/build-00000000.json @@ -1,23 +1,86 @@ { - "generated_at": "2026-06-16T15:23:47.496569+00:00", + "generated_at": "2026-06-19T07:24:08.908496+00:00", "commit": "00000000", "diagnostic_logd": "diagnostic/build-00000000.logd", "diagnostic_logd_error": null, "chunked": false, "chunk_size_bytes": null, - "password": "4c7df15ab09fbb066197", - "decrypt_command": "encryptly unpack diagnostic/build-00000000.logd --password 4c7df15ab09fbb066197", - "total_modules": 1, - "passed": 0, - "failed": 1, + "password": "041370d59f0a326a255a", + "decrypt_command": "encryptly unpack diagnostic/build-00000000.logd --password 041370d59f0a326a255a", + "total_modules": 10, + "passed": 8, + "failed": 2, "modules": [ + { + "name": "backend", + "status": "PASS", + "elapsed_seconds": 38.536, + "artifact": "/mnt/c/Users/jarlyn/Documents/make money/GautamKumarOffical-TentOfTrials-api/GautamKumarOffical-TentOfTrials-2b54872/backend/target", + "output": "\u001b[1m\u001b[92m Compiling\u001b[0m proc-macro2 v1.0.106\n\u001b[1m\u001b[92m Compiling\u001b[0m quote v1.0.45\n\u001b[1m\u001b[92m Compiling\u001b[0m unicode-ident v1.0.24\n\u001b[1m\u001b[92m Compiling\u001b[0m libc v0.2.186\n\u001b[1m\u001b[92m Compiling\u001b[0m cfg-if v1.0.4\n\u001b[1m\u001b[92m Compiling\u001b[0m smallvec v1.15.2\n\u001b[1m\u001b[92m Compiling\u001b[0m pin-project-lite v0.2.17\n\u001b[1m\u001b[92m Compiling\u001b[0m stable_deref_trait v1.2.1\n\u001b[1m\u001b[92m Compiling\u001b[0m parking_lot_core v0.9.12\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_core v1.0.228\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-core v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m memchr v2.8.2\n\u001b[1m\u001b[92m Compiling\u001b[0m scopeguard v1.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m bytes v1.11.1\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-sink v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m itoa v1.0.18\n\u001b[1m\u001b[92m Compiling\u001b[0m once_cell v1.21.4\n\u001b[1m\u001b[92m Compiling\u001b[0m find-msvc-tools v0.1.9\n\u001b[1m\u001b[92m Compiling\u001b[0m serde v1.0.228\n\u001b[1m\u001b[92m Compiling\u001b[0m shlex v2.0.1\n\u001b[1m\u001b[92m Compiling\u001b[0m slab v0.4.12\n\u001b[1m\u001b[92m Compiling\u001b[0m vcpkg v0.2.15\n\u001b[1m\u001b[92m Compiling\u001b[0m pkg-config v0.3.33\n\u001b[1m\u001b[92m Compiling\u001b[0m litemap v0.8.2\n\u001b[1m\u001b[92m Compiling\u001b[0m writeable v0.6.3\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_normalizer_data v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-io v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m equivalent v1.0.2\n\u001b[1m\u001b[92m Compiling\u001b[0m utf8_iter v1.0.4\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-task v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_properties_data v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m hashbrown v0.17.1\n\u001b[1m\u001b[92m Compiling\u001b[0m lock_api v0.4.14\n\u001b[1m\u001b[92m Compiling\u001b[0m cc v1.2.64\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-channel v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-core v0.1.36\n\u001b[1m\u001b[92m Compiling\u001b[0m version_check v0.9.5\n\u001b[1m\u001b[92m Compiling\u001b[0m percent-encoding v2.3.2\n\u001b[1m\u001b[92m Compiling\u001b[0m http v1.4.2\n\u001b[1m\u001b[92m Compiling\u001b[0m bitflags v2.13.0\n\u001b[1m\u001b[92m Compiling\u001b[0m log v0.4.32\n\u001b[1m\u001b[92m Compiling\u001b[0m openssl v0.10.81\n\u001b[1m\u001b[92m Compiling\u001b[0m indexmap v2.14.0\n\u001b[1m\u001b[92m Compiling\u001b[0m foreign-types-shared v0.1.1\n\u001b[1m\u001b[92m Compiling\u001b[0m httparse v1.10.1\n\u001b[1m\u001b[92m Compiling\u001b[0m native-tls v0.2.18\n\u001b[1m\u001b[92m Compiling\u001b[0m fnv v1.0.7\n\u001b[1m\u001b[92m Compiling\u001b[0m typenum v1.20.1\n\u001b[1m\u001b[92m Compiling\u001b[0m try-lock v0.2.5\n\u001b[1m\u001b[92m Compiling\u001b[0m atomic-waker v1.1.2\n\u001b[1m\u001b[92m Compiling\u001b[0m tower-service v0.3.3\n\u001b[1m\u001b[92m Compiling\u001b[0m foreign-types v0.3.2\n\u001b[1m\u001b[92m Compiling\u001b[0m zmij v1.0.21\n\u001b[1m\u001b[92m Compiling\u001b[0m want v0.3.1\n\u001b[1m\u001b[92m Compiling\u001b[0m form_urlencoded v1.2.2\n\u001b[1m\u001b[92m Compiling\u001b[0m aho-corasick v1.1.4\n\u001b[1m\u001b[92m Compiling\u001b[0m openssl-probe v0.2.1\n\u001b[1m\u001b[92m Compiling\u001b[0m utf8parse v0.2.2\n\u001b[1m\u001b[92m Compiling\u001b[0m regex-syntax v0.8.11\n\u001b[1m\u001b[92m Compiling\u001b[0m autocfg v1.5.1\n\u001b[1m\u001b[92m Compiling\u001b[0m http-body v1.0.1\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_json v1.0.150\n\u001b[1m\u001b[92m Compiling\u001b[0m sync_wrapper v1.0.2\n\u001b[1m\u001b[92m Compiling\u001b[0m colorchoice v1.0.5\n\u001b[1m\u001b[92m Compiling\u001b[0m generic-array v0.14.7\n\u001b[1m\u001b[92m Compiling\u001b[0m ipnet v2.12.0\n\u001b[1m\u001b[92m Compiling\u001b[0m anstyle-parse v1.0.0\n\u001b[1m\u001b[92m Compiling\u001b[0m tower-layer v0.3.3\n\u001b[1m\u001b[92m Compiling\u001b[0m is_terminal_polyfill v1.70.2\n\u001b[1m\u001b[92m Compiling\u001b[0m crossbeam-utils v0.8.21\n\u001b[1m\u001b[92m Compiling\u001b[0m getrandom v0.4.2\n\u001b[1m\u001b[92m Compiling\u001b[0m anstyle v1.0.14\n\u001b[1m\u001b[92m Compiling\u001b[0m base64 v0.22.1\n\u001b[1m\u001b[92m Compiling\u001b[0m anstyle-query v1.1.5\n\u001b[1m\u001b[92m Compiling\u001b[0m http-body-util v0.1.3\n\u001b[1m\u001b[92m Compiling\u001b[0m thiserror v2.0.18\n\u001b[1m\u001b[92m Compiling\u001b[0m zeroize v1.9.0\n\u001b[1m\u001b[92m Compiling\u001b[0m clap_lex v1.1.0\n\u001b[1m\u001b[92m Compiling\u001b[0m strsim v0.11.1\n\u001b[1m\u001b[92m Compiling\u001b[0m ryu v1.0.23\n\u001b[1m\u001b[92m Compiling\u001b[0m anyhow v1.0.102\n\u001b[1m\u001b[92m Compiling\u001b[0m anstream v1.0.0\n\u001b[1m\u001b[92m Compiling\u001b[0m heck v0.5.0\n\u001b[1m\u001b[92m Compiling\u001b[0m num-traits v0.2.19\n\u001b[1m\u001b[92m Compiling\u001b[0m toml_write v0.1.2\n\u001b[1m\u001b[92m Compiling\u001b[0m winnow v0.7.15\n\u001b[1m\u001b[92m Compiling\u001b[0m lazy_static v1.5.0\n\u001b[1m\u001b[92m Compiling\u001b[0m rustls-pki-types v1.14.1\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-log v0.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m thread_local v1.1.9\n\u001b[1m\u001b[92m Compiling\u001b[0m openssl-sys v0.9.117\n\u001b[1m\u001b[92m Compiling\u001b[0m encoding_rs v0.8.35\n\u001b[1m\u001b[92m Compiling\u001b[0m mime v0.3.17\n\u001b[1m\u001b[92m Compiling\u001b[0m regex-automata v0.4.14\n\u001b[1m\u001b[92m Compiling\u001b[0m sharded-slab v0.1.7\n\u001b[1m\u001b[92m Compiling\u001b[0m hashbrown v0.14.5\n\u001b[1m\u001b[92m Compiling\u001b[0m cpufeatures v0.2.17\n\u001b[1m\u001b[92m Compiling\u001b[0m nu-ansi-term v0.50.3\n\u001b[1m\u001b[92m Compiling\u001b[0m clap_builder v4.6.0\n\u001b[1m\u001b[92m Compiling\u001b[0m iana-time-zone v0.1.65\n\u001b[1m\u001b[92m Compiling\u001b[0m errno v0.3.14\n\u001b[1m\u001b[92m Compiling\u001b[0m socket2 v0.6.4\n\u001b[1m\u001b[92m Compiling\u001b[0m mio v1.2.1\n\u001b[1m\u001b[92m Compiling\u001b[0m signal-hook-registry v1.4.8\n\u001b[1m\u001b[92m Compiling\u001b[0m syn v2.0.117\n\u001b[1m\u001b[92m Compiling\u001b[0m parking_lot v0.12.5\n\u001b[1m\u001b[92m Compiling\u001b[0m block-buffer v0.10.4\n\u001b[1m\u001b[92m Compiling\u001b[0m crypto-common v0.1.7\n\u001b[1m\u001b[92m Compiling\u001b[0m uuid v1.23.3\n\u001b[1m\u001b[92m Compiling\u001b[0m dashmap v6.2.1\n\u001b[1m\u001b[92m Compiling\u001b[0m digest v0.10.7\n\u001b[1m\u001b[92m Compiling\u001b[0m sha2 v0.10.9\n\u001b[1m\u001b[92m Compiling\u001b[0m matchers v0.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m regex v1.12.4\n\u001b[1m\u001b[92m Compiling\u001b[0m synstructure v0.13.2\n\u001b[1m\u001b[92m Compiling\u001b[0m zerofrom-derive v0.1.7\n\u001b[1m\u001b[92m Compiling\u001b[0m yoke-derive v0.8.2\n\u001b[1m\u001b[92m Compiling\u001b[0m zerovec-derive v0.11.3\n\u001b[1m\u001b[92m Compiling\u001b[0m displaydoc v0.2.6\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_derive v1.0.228\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio-macros v2.7.0\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-macro v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-attributes v0.1.31\n\u001b[1m\u001b[92m Compiling\u001b[0m openssl-macros v0.1.1\n\u001b[1m\u001b[92m Compiling\u001b[0m thiserror-impl v2.0.18\n\u001b[1m\u001b[92m Compiling\u001b[0m clap_derive v4.6.1\n\u001b[1m\u001b[92m Compiling\u001b[0m async-trait v0.1.89\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-util v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio v1.52.3\n\u001b[1m\u001b[92m Compiling\u001b[0m zerofrom v0.1.8\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing v0.1.44\n\u001b[1m\u001b[92m Compiling\u001b[0m yoke v0.8.3\n\u001b[1m\u001b[92m Compiling\u001b[0m clap v4.6.1\n\u001b[1m\u001b[92m Compiling\u001b[0m zerovec v0.11.6\n\u001b[1m\u001b[92m Compiling\u001b[0m zerotrie v0.2.4\n\u001b[1m\u001b[92m Compiling\u001b[0m tinystr v0.8.3\n\u001b[1m\u001b[92m Compiling\u001b[0m potential_utf v0.1.5\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_collections v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_locale_core v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_spanned v0.6.9\n\u001b[1m\u001b[92m Compiling\u001b[0m toml_datetime v0.6.11\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-serde v0.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_urlencoded v0.7.1\n\u001b[1m\u001b[92m Compiling\u001b[0m chrono v0.4.45\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-subscriber v0.3.23\n\u001b[1m\u001b[92m Compiling\u001b[0m toml_edit v0.22.27\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_provider v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-executor v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_normalizer v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_properties v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m futures v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m toml v0.8.23\n\u001b[1m\u001b[92m Compiling\u001b[0m idna_adapter v1.2.2\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio-util v0.7.18\n\u001b[1m\u001b[92m Compiling\u001b[0m tower v0.5.3\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio-native-tls v0.3.1\n\u001b[1m\u001b[92m Compiling\u001b[0m idna v1.1.0\n\u001b[1m\u001b[92m Compiling\u001b[0m h2 v0.4.14\n\u001b[1m\u001b[92m Compiling\u001b[0m url v2.5.8\n\u001b[1m\u001b[92m Compiling\u001b[0m tower-http v0.6.11\n\u001b[1m\u001b[92m Compiling\u001b[0m hyper v1.10.1\n\u001b[1m\u001b[92m Compiling\u001b[0m hyper-util v0.1.20\n\u001b[1m\u001b[92m Compiling\u001b[0m hyper-tls v0.6.0\n\u001b[1m\u001b[92m Compiling\u001b[0m reqwest v0.12.28\n\u001b[1m\u001b[92m Compiling\u001b[0m tent-backend v0.1.0 (/mnt/c/Users/jarlyn/Documents/make money/GautamKumarOffical-TentOfTrials-api/GautamKumarOffical-TentOfTrials-2b54872/backend)\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `warn`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/embeddings.rs:28:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `error`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:25:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `error` and `warn`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:40:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m40\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `c_int` and `c_uint`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:38:20\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_int, c_uint, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `std::ffi::CString`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:35:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m35\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::ffi::CString;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `c_char`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:36:20\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m36\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_char, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `CStr`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/types.rs:27:16\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::ffi::{CStr, CString};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `c_double` and `c_long`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/types.rs:29:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m29\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_char, c_double, c_int, c_uint, c_void, c_long, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `AtomicBool`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:14:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m14\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `EntityKind` and `legacy_normalize_phone_number`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/v1_compat.rs:8:47\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m8\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use crate::legacy::deprecations::{LegacyUuid, EntityKind, LegacyPagination, legacy_normalize_phone_number};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `super::ProtocolError`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/validate.rs:27:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::ProtocolError;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/codec.rs:25:38\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use crate::protocol::{ProtocolError, MAX_MESSAGE_SIZE, MIN_COMPATIBLE_VERSION, PROTOCOL_VERSION};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `Write`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/codec.rs:26:29\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m26\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::io::{Cursor, Read, Write};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `Ordering`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:25:36\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::sync::atomic::{AtomicU64, Ordering};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `Duration` and `Instant`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:27:17\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::time::{Duration, Instant};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `Deserialize` and `Serialize`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:28:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use serde::{Deserialize, Serialize};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:31:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m31\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::{ProtocolError, MAX_MESSAGE_SIZE, DEFAULT_TIMEOUT_MS};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `FrameDecoder` and `FrameEncoder`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:32:27\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m32\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::codec::{Frame, FrameEncoder, FrameDecoder, FLAG_REQUIRES_ACK};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:244:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m244\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Team => \"org\", // Legacy mapping\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(deprecated)]` on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:245:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m245\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Project => \"workspace\", // Legacy mapping\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:266:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m266\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Team\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:267:31\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m267\u001b[0m \u001b[1m\u001b[94m|\u001b[0m | EntityKind::Project\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:317:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m317\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m----\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94mhelp: remove this `mut`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_mut)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `initialized`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:440:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m440\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let initialized = Arc::new(AtomicBool::new(true));\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_initialized`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:267:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m267\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m----\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94mhelp: remove this `mut`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `value`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:508:15\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m508\u001b[0m \u001b[1m\u001b[94m|\u001b[0m for (key, value) in configs {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_value`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `obj`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/validate.rs:282:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m282\u001b[0m \u001b[1m\u001b[94m|\u001b[0m if let Some(obj) = value.as_object() {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_obj`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: type `BridgeStats` is more private than the item `ConnectorBridge::stats`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:415:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m415\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub fn stats(&self) -> BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mmethod `ConnectorBridge::stats` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `BridgeStats` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:225:1\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m225\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(private_interfaces)]` on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: type `CircuitState` is more private than the item `ConnectorBridge::circuit_state`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:423:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m423\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub fn circuit_state(&self) -> CircuitState {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mmethod `ConnectorBridge::circuit_state` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `CircuitState` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:79:1\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m 79\u001b[0m \u001b[1m\u001b[94m|\u001b[0m enum CircuitState {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `NCP_TEMPERATURE` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:53:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m53\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const NCP_TEMPERATURE: f64 = 0.42;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MIN_CONFIDENCE_THRESHOLD` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:61:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m61\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MIN_CONFIDENCE_THRESHOLD: f64 = 0.65;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MAX_INFERENCE_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:65:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m65\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MAX_INFERENCE_RETRIES: u32 = 5;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `discovery`, `broker`, and `registry` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:173:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m171\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct AiOrchestrator {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m--------------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m172\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the service discovery subsystem\n\u001b[1m\u001b[94m173\u001b[0m \u001b[1m\u001b[94m|\u001b[0m discovery: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m174\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the message broker subsystem\n\u001b[1m\u001b[94m175\u001b[0m \u001b[1m\u001b[94m|\u001b[0m broker: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\u001b[1m\u001b[94m176\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the service registry subsystem\n\u001b[1m\u001b[94m177\u001b[0m \u001b[1m\u001b[94m|\u001b[0m registry: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `window_start` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/embeddings.rs:661:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m658\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ContextWindowManager {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m--------------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m661\u001b[0m \u001b[1m\u001b[94m|\u001b[0m window_start: Instant,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MAX_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:41:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m41\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MAX_RETRIES: u32 = 3;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `RETRY_BASE_DELAY_MS` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:44:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m44\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const RETRY_BASE_DELAY_MS: u64 = 1000;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `api_key`, `base_url`, and `client` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:453:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m452\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct AnthropicClient {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m453\u001b[0m \u001b[1m\u001b[94m|\u001b[0m api_key: String,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m454\u001b[0m \u001b[1m\u001b[94m|\u001b[0m base_url: String,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m455\u001b[0m \u001b[1m\u001b[94m|\u001b[0m models: Vec,\n\u001b[1m\u001b[94m456\u001b[0m \u001b[1m\u001b[94m|\u001b[0m client: reqwest::Client,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `AnthropicClient` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `routing_table` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:719:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m716\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ModelRouter {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m719\u001b[0m \u001b[1m\u001b[94m|\u001b[0m routing_table: RwLock>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `ModelRouter` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `cost_history` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:951:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m947\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct TokenCounter {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m951\u001b[0m \u001b[1m\u001b[94m|\u001b[0m cost_history: RwLock>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `HEALTH_CHECK_TIMEOUT_MS` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:64:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m64\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const HEALTH_CHECK_TIMEOUT_MS: u64 = 1000;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `id` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:152:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m151\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct PoolEntry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m152\u001b[0m \u001b[1m\u001b[94m|\u001b[0m id: usize,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: method `stats` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:195:8\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m163\u001b[0m \u001b[1m\u001b[94m|\u001b[0m impl ConnectionPool {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-------------------\u001b[0m \u001b[1m\u001b[94mmethod in this implementation\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m195\u001b[0m \u001b[1m\u001b[94m|\u001b[0m fn stats(&self) -> PoolStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: struct `PoolStats` is never constructed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:203:8\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m203\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct PoolStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `circuit_breaker_trips` and `health_check_failures` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:229:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m225\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m229\u001b[0m \u001b[1m\u001b[94m|\u001b[0m circuit_breaker_trips: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m230\u001b[0m \u001b[1m\u001b[94m|\u001b[0m health_check_failures: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `BridgeStats` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `consumers` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/messaging/mod.rs:38:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m35\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct MessageBroker {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m consumers: DashMap>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/messages.rs:293:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m291\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct MessageRegistry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m292\u001b[0m \u001b[1m\u001b[94m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[94m293\u001b[0m \u001b[1m\u001b[94m|\u001b[0m version: u32,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:258:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m255\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct Schema {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m258\u001b[0m \u001b[1m\u001b[94m|\u001b[0m version: u32,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `required` and `default_value` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:264:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m261\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct SchemaField {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m264\u001b[0m \u001b[1m\u001b[94m|\u001b[0m required: bool,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m265\u001b[0m \u001b[1m\u001b[94m|\u001b[0m default_value: Option,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variant `Custom` is never constructed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:276:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m269\u001b[0m \u001b[1m\u001b[94m|\u001b[0m enum FieldValidation {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mvariant in this enum\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m276\u001b[0m \u001b[1m\u001b[94m|\u001b[0m Custom(String),\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `next_request_id`, `pending_requests`, `serializer`, and `timeout_ms` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:218:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m217\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct RpcClient {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m218\u001b[0m \u001b[1m\u001b[94m|\u001b[0m next_request_id: AtomicU64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m219\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pending_requests: Arc, RpcError>>>>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m220\u001b[0m \u001b[1m\u001b[94m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m221\u001b[0m \u001b[1m\u001b[94m|\u001b[0m timeout_ms: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `serializer` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:271:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m269\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct RpcServer {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m270\u001b[0m \u001b[1m\u001b[94m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[94m271\u001b[0m \u001b[1m\u001b[94m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `events` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/registry/mod.rs:31:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ServiceRegistry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m31\u001b[0m \u001b[1m\u001b[94m|\u001b[0m events: Arc>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m: `tent-backend` (lib) generated 52 warnings (run `cargo fix --lib -p tent-backend` to apply 23 suggestions)\n\u001b[1m\u001b[92m Finished\u001b[0m `dev` profile [unoptimized + debuginfo] target(s) in 35.12s" + }, + { + "name": "frontend", + "status": "PASS", + "elapsed_seconds": 17.976, + "artifact": "/mnt/c/Users/jarlyn/Documents/make money/GautamKumarOffical-TentOfTrials-api/GautamKumarOffical-TentOfTrials-2b54872/frontend/dist", + "output": "> tent-frontend@0.0.0 build\n> tsc -b && vite build\n\n\u001b[36mvite v6.4.3 \u001b[32mbuilding for production...\u001b[36m\u001b[39m\ntransforming...\n\u001b[32m\u2713\u001b[39m 100 modules transformed.\nrendering chunks...\ncomputing gzip size...\n\u001b[2mdist/\u001b[22m\u001b[32mindex.html \u001b[39m\u001b[1m\u001b[2m 0.62 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u2502 gzip: 0.34 kB\u001b[22m\n\u001b[2mdist/\u001b[22m\u001b[36massets/state-BkjSKDbY.js \u001b[39m\u001b[1m\u001b[2m 8.91 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u2502 gzip: 3.54 kB\u001b[22m\u001b[2m \u2502 map: 57.15 kB\u001b[22m\n\u001b[2mdist/\u001b[22m\u001b[36massets/vendor-CREcWLHI.js \u001b[39m\u001b[1m\u001b[2m 48.93 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u2502 gzip: 17.25 kB\u001b[22m\u001b[2m \u2502 map: 481.27 kB\u001b[22m\n\u001b[2mdist/\u001b[22m\u001b[36massets/index-CyxcoTyU.js \u001b[39m\u001b[1m\u001b[2m231.32 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u2502 gzip: 72.16 kB\u001b[22m\u001b[2m \u2502 map: 1,044.42 kB\u001b[22m\n\u001b[32m\u2713 built in 1.16s\u001b[39m" + }, + { + "name": "market", + "status": "FAIL", + "elapsed_seconds": 33.543, + "artifact": null, + "output": "go: downloading go1.26 (linux/amd64)\ngo: download go1.26: golang.org/toolchain@v0.0.1-go1.26.linux-amd64: Get \"https://proxy.golang.org/golang.org/toolchain/@v/v0.0.1-go1.26.linux-amd64.zip\": dial tcp 142.250.204.49:443: i/o timeout" + }, { "name": "frailbox", + "status": "PASS", + "elapsed_seconds": 0.053, + "artifact": "/mnt/c/Users/jarlyn/Documents/make money/GautamKumarOffical-TentOfTrials-api/GautamKumarOffical-TentOfTrials-2b54872/frailbox/frailbox", + "output": "make: Nothing to be done for 'all'." + }, + { + "name": "engine", + "status": "PASS", + "elapsed_seconds": 13.492, + "artifact": "/mnt/c/Users/jarlyn/Documents/make money/GautamKumarOffical-TentOfTrials-api/GautamKumarOffical-TentOfTrials-2b54872/frailbox/engine/build/trial-engine", + "output": "[ 11%] Building CXX object CMakeFiles/trial-engine.dir/main.cpp.o\n[ 22%] Building CXX object CMakeFiles/trial-engine.dir/core/math.cpp.o\n[ 33%] Building CXX object CMakeFiles/trial-engine.dir/core/ecs.cpp.o\n[ 44%] Building CXX object CMakeFiles/trial-engine.dir/dynamics/rigidbody.cpp.o\n[ 55%] Building CXX object CMakeFiles/trial-engine.dir/dynamics/constraint.cpp.o\n[ 66%] Building CXX object CMakeFiles/trial-engine.dir/collision/collision.cpp.o\n[ 77%] Building CXX object CMakeFiles/trial-engine.dir/mnt/c/Users/jarlyn/Documents/make_money/GautamKumarOffical-TentOfTrials-api/GautamKumarOffical-TentOfTrials-2b54872/frailbox/wat.cpp.o\n[ 88%] Building CXX object CMakeFiles/trial-engine.dir/mnt/c/Users/jarlyn/Documents/make_money/GautamKumarOffical-TentOfTrials-api/GautamKumarOffical-TentOfTrials-2b54872/frailbox/engine.cpp.o\n[100%] Linking CXX executable trial-engine\n[100%] Built target trial-engine" + }, + { + "name": "compliance", + "status": "PASS", + "elapsed_seconds": 0.659, + "artifact": "/mnt/c/Users/jarlyn/Documents/make money/GautamKumarOffical-TentOfTrials-api/GautamKumarOffical-TentOfTrials-2b54872/compliance/build", + "output": "Note: ComplianceAuditor.java uses or overrides a deprecated API.\nNote: Recompile with -Xlint:deprecation for details." + }, + { + "name": "v2-market-stream", + "status": "PASS", + "elapsed_seconds": 0.025, + "artifact": null, + "output": "Syntax OK" + }, + { + "name": "nfc-scanner", + "status": "PASS", + "elapsed_seconds": 0.005, + "artifact": null, + "output": "" + }, + { + "name": "openapi-haskell", "status": "FAIL", - "elapsed_seconds": 0, + "elapsed_seconds": -1.678, + "artifact": null, + "output": "[1 of 8] Compiling Network.HTTP.Types ( Network/HTTP/Types.hs, nothing )\n[2 of 8] Compiling Network.Wai ( Network/Wai.hs, nothing )\n[3 of 8] Compiling Network.Wai.Handler.Warp ( Network/Wai/Handler/Warp.hs, nothing )\n[4 of 8] Compiling Network.Wai.Logger ( Network/Wai/Logger.hs, nothing )\n[5 of 8] Compiling Tent.OpenAPI.Types ( Types.hs, /tmp/ghc13220_0/ghc_6.o, /tmp/ghc13220_0/ghc_6.dyn_o )\n[6 of 8] Compiling Tent.OpenAPI.Generate ( Generate.hs, /tmp/ghc13220_0/ghc_4.o, /tmp/ghc13220_0/ghc_4.dyn_o )\n[7 of 8] Compiling Tent.OpenAPI.Validate ( Validate.hs, nothing )\nTypes.hs:173:34: warning: [-Wderiving-defaults]\n \u2022 Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled\n Defaulting to the DeriveAnyClass strategy for instantiating FromJSON\n \u2022 In the newtype declaration for \u2018Paths\u2019\n Suggested fix:\n Use DerivingStrategies\n to pick a different strategy\n |\n173 | } deriving (Show, Eq, Generic, A.FromJSON)\n | ^^^^^^^^^^\n\nTypes.hs:279:34: warning: [-Wderiving-defaults]\n \u2022 Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled\n Defaulting to the DeriveAnyClass strategy for instantiating FromJSON\n \u2022 In the newtype declaration for \u2018Responses\u2019\n Suggested fix:\n Use DerivingStrategies\n to pick a different strategy\n |\n279 | } deriving (Show, Eq, Generic, A.FromJSON)\n | ^^^^^^^^^^\n\nValidate.hs:80:10: error:\n Variable not in scope:\n liftA2\n :: (a2 -> a2 -> a2) -> ValidateM a -> ValidateM a -> ValidateM a\n |\n80 | (<>) = liftA2 (<>)\n | ^^^^^^" + }, + { + "name": "openapi-tools", + "status": "PASS", + "elapsed_seconds": 0.009, "artifact": null, - "output": "Command not found: [Errno 2] No such file or directory: 'make'" + "output": "" } ], - "pr_note": "Include this JSON diagnostic report and diagnostic/build-00000000.logd in your PR. Maintainers may ask you to remove these diagnostic artifacts before merging." + "pr_note": "Include the encrypted diagnostic logd artifact(s): diagnostic/build-00000000.logd. The encrypted .logd is the required diagnostic content for PR review; this JSON file is metadata. Maintainers may ask you to remove these diagnostic artifacts before merging." } diff --git a/diagnostic/build-00000000.logd b/diagnostic/build-00000000.logd index b5a046a2ab565bee8075f4afa6698ca2344a37d8..434f24f47b9c05d1c6db6b2dd4deec8332f54ce6 100644 GIT binary patch literal 52509 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 +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BUDDY_MIN_BLOCK_SIZE 64U +#define BUDDY_DEFAULT_HEAP_SIZE (1024ULL * 1024ULL) + +typedef struct buddy_stats { + uint64_t total_allocated; + uint64_t total_freed; + uint64_t peak_usage; + uint64_t current_usage; + uint64_t allocation_count; + uint64_t deallocation_count; + uint64_t allocated_blocks; + uint64_t free_blocks; + size_t heap_size; + size_t largest_free_block; + double fragmentation_ratio; +} buddy_stats_t; + +int buddy_init(size_t heap_size); +void buddy_shutdown(void); +void *buddy_alloc(size_t size); +void buddy_free(void *ptr); +buddy_stats_t buddy_stats(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/frailbox/src/buddy.c b/frailbox/src/buddy.c new file mode 100644 index 000000000..d94ec1723 --- /dev/null +++ b/frailbox/src/buddy.c @@ -0,0 +1,317 @@ +#include "buddy.h" + +#include +#include +#include + +#define BUDDY_MAX_ORDER 56U + +typedef struct buddy_block { + struct buddy_block *next; + size_t requested_size; + unsigned int order; + int is_free; +} buddy_block_t; + +typedef struct buddy_allocator { + void *heap; + size_t heap_size; + unsigned int max_order; + buddy_block_t *free_lists[BUDDY_MAX_ORDER + 1U]; + buddy_stats_t stats; + int initialized; +} buddy_allocator_t; + +static buddy_allocator_t allocator; + +static int is_power_of_two(size_t value) { + return value != 0 && (value & (value - 1U)) == 0; +} + +static size_t next_power_of_two(size_t value) { + size_t power = BUDDY_MIN_BLOCK_SIZE; + + while (power < value) { + if (power > SIZE_MAX / 2U) { + return 0; + } + power <<= 1U; + } + + return power; +} + +static size_t block_size_for_order(unsigned int order) { + return (size_t)BUDDY_MIN_BLOCK_SIZE << order; +} + +static unsigned int order_for_block_size(size_t size) { + unsigned int order = 0; + + while (size > BUDDY_MIN_BLOCK_SIZE) { + size >>= 1U; + order++; + } + + return order; +} + +static unsigned int order_for_request(size_t size) { + size_t needed = size + sizeof(buddy_block_t); + size_t block_size = next_power_of_two(needed); + + if (block_size == 0) { + return BUDDY_MAX_ORDER + 1U; + } + + return order_for_block_size(block_size); +} + +static void insert_free_block(buddy_block_t *block) { + unsigned int order = block->order; + + block->is_free = 1; + block->requested_size = 0; + block->next = allocator.free_lists[order]; + allocator.free_lists[order] = block; +} + +static int remove_free_block(buddy_block_t *block, unsigned int order) { + buddy_block_t **cursor = &allocator.free_lists[order]; + + while (*cursor != NULL) { + if (*cursor == block) { + *cursor = block->next; + block->next = NULL; + return 1; + } + cursor = &(*cursor)->next; + } + + return 0; +} + +static int block_in_heap(const buddy_block_t *block) { + const char *start = allocator.heap; + const char *end = start + allocator.heap_size; + const char *addr = (const char *)block; + + return addr >= start && addr < end; +} + +static buddy_block_t *buddy_for_block(buddy_block_t *block) { + size_t block_size = block_size_for_order(block->order); + uintptr_t heap_addr = (uintptr_t)allocator.heap; + uintptr_t block_addr = (uintptr_t)block; + uintptr_t offset = block_addr - heap_addr; + uintptr_t buddy_offset = offset ^ block_size; + + if (buddy_offset >= allocator.heap_size) { + return NULL; + } + + return (buddy_block_t *)(heap_addr + buddy_offset); +} + +int buddy_init(size_t heap_size) { + buddy_block_t *initial; + + if (allocator.initialized) { + buddy_shutdown(); + } + + if (heap_size == 0) { + heap_size = BUDDY_DEFAULT_HEAP_SIZE; + } + if (!is_power_of_two(heap_size)) { + heap_size = next_power_of_two(heap_size); + } + if (heap_size < BUDDY_MIN_BLOCK_SIZE) { + heap_size = BUDDY_MIN_BLOCK_SIZE; + } + + if (heap_size == 0 || order_for_block_size(heap_size) > BUDDY_MAX_ORDER) { + return -1; + } + + allocator.heap = mmap(NULL, heap_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (allocator.heap == MAP_FAILED) { + allocator.heap = NULL; + return -1; + } + + allocator.heap_size = heap_size; + allocator.max_order = order_for_block_size(heap_size); + allocator.initialized = 1; + memset(&allocator.stats, 0, sizeof(allocator.stats)); + memset(allocator.free_lists, 0, sizeof(allocator.free_lists)); + + initial = allocator.heap; + initial->next = NULL; + initial->requested_size = 0; + initial->order = allocator.max_order; + initial->is_free = 1; + allocator.free_lists[allocator.max_order] = initial; + allocator.stats.heap_size = heap_size; + allocator.stats.largest_free_block = heap_size; + allocator.stats.free_blocks = 1; + + return 0; +} + +void buddy_shutdown(void) { + if (!allocator.initialized) { + return; + } + + (void)munmap(allocator.heap, allocator.heap_size); + memset(&allocator, 0, sizeof(allocator)); +} + +void *buddy_alloc(size_t size) { + buddy_block_t *block; + unsigned int order; + unsigned int current_order; + + if (size == 0 || size > SIZE_MAX - sizeof(buddy_block_t)) { + return NULL; + } + + if (!allocator.initialized && buddy_init(0) != 0) { + return NULL; + } + + order = order_for_request(size); + if (order > allocator.max_order) { + return NULL; + } + + current_order = order; + while (current_order <= allocator.max_order && + allocator.free_lists[current_order] == NULL) { + current_order++; + } + if (current_order > allocator.max_order) { + return NULL; + } + + block = allocator.free_lists[current_order]; + (void)remove_free_block(block, current_order); + + while (current_order > order) { + buddy_block_t *split_buddy; + size_t split_size; + + current_order--; + split_size = block_size_for_order(current_order); + split_buddy = (buddy_block_t *)((char *)block + split_size); + split_buddy->order = current_order; + split_buddy->is_free = 1; + split_buddy->requested_size = 0; + split_buddy->next = NULL; + + block->order = current_order; + insert_free_block(split_buddy); + } + + block->next = NULL; + block->is_free = 0; + block->requested_size = size; + + allocator.stats.total_allocated += size; + allocator.stats.current_usage += size; + allocator.stats.allocation_count++; + allocator.stats.allocated_blocks++; + if (allocator.stats.current_usage > allocator.stats.peak_usage) { + allocator.stats.peak_usage = allocator.stats.current_usage; + } + + return (void *)(block + 1); +} + +void buddy_free(void *ptr) { + buddy_block_t *block; + + if (ptr == NULL || !allocator.initialized) { + return; + } + + block = ((buddy_block_t *)ptr) - 1; + if (!block_in_heap(block) || block->is_free) { + return; + } + + allocator.stats.total_freed += block->requested_size; + if (allocator.stats.current_usage >= block->requested_size) { + allocator.stats.current_usage -= block->requested_size; + } else { + allocator.stats.current_usage = 0; + } + allocator.stats.deallocation_count++; + if (allocator.stats.allocated_blocks > 0) { + allocator.stats.allocated_blocks--; + } + + block->requested_size = 0; + block->is_free = 1; + + while (block->order < allocator.max_order) { + buddy_block_t *buddy = buddy_for_block(block); + + if (buddy == NULL || !block_in_heap(buddy) || + !buddy->is_free || buddy->order != block->order) { + break; + } + if (!remove_free_block(buddy, buddy->order)) { + break; + } + + if (buddy < block) { + block = buddy; + } + block->order++; + block->requested_size = 0; + block->is_free = 1; + block->next = NULL; + } + + insert_free_block(block); +} + +buddy_stats_t buddy_stats(void) { + buddy_stats_t stats = allocator.stats; + size_t total_free = 0; + size_t largest_free = 0; + uint64_t free_blocks = 0; + + stats.heap_size = allocator.heap_size; + + if (!allocator.initialized) { + return stats; + } + + for (unsigned int order = 0; order <= allocator.max_order; order++) { + for (buddy_block_t *block = allocator.free_lists[order]; + block != NULL; + block = block->next) { + size_t size = block_size_for_order(order); + + free_blocks++; + total_free += size; + if (size > largest_free) { + largest_free = size; + } + } + } + + stats.free_blocks = free_blocks; + stats.largest_free_block = largest_free; + if (total_free == 0 || largest_free == total_free) { + stats.fragmentation_ratio = 0.0; + } else { + stats.fragmentation_ratio = 1.0 - ((double)largest_free / (double)total_free); + } + + return stats; +} diff --git a/frailbox/tests/test_buddy.c b/frailbox/tests/test_buddy.c new file mode 100644 index 000000000..dddef3e11 --- /dev/null +++ b/frailbox/tests/test_buddy.c @@ -0,0 +1,74 @@ +#include "../include/buddy.h" + +#include + +#define CHECK(cond, msg) do { \ + if (!(cond)) { \ + fprintf(stderr, "check failed: %s\n", msg); \ + return 1; \ + } \ +} while (0) + +static int test_alloc_free_and_stats(void) { + CHECK(buddy_init(4096) == 0, "buddy_init should create a 4096 byte heap"); + + void *first = buddy_alloc(17); + void *second = buddy_alloc(80); + CHECK(first != NULL, "first allocation should succeed"); + CHECK(second != NULL, "second allocation should succeed"); + CHECK(first != second, "allocations should return distinct blocks"); + + buddy_stats_t stats = buddy_stats(); + CHECK(stats.heap_size == 4096, "heap size should be tracked"); + CHECK(stats.allocation_count == 2, "allocation count should be tracked"); + CHECK(stats.current_usage >= 97, "current requested usage should be tracked"); + CHECK(stats.peak_usage >= stats.current_usage, "peak usage should cover current usage"); + CHECK(stats.allocated_blocks == 2, "allocated block count should be tracked"); + + buddy_free(first); + buddy_free(second); + + stats = buddy_stats(); + CHECK(stats.deallocation_count == 2, "free count should be tracked"); + CHECK(stats.current_usage == 0, "usage should return to zero after frees"); + CHECK(stats.free_blocks == 1, "freed buddies should coalesce to one block"); + CHECK(stats.largest_free_block == stats.heap_size, "coalesced heap should be the largest free block"); + CHECK(stats.fragmentation_ratio == 0.0, "single free block should have zero fragmentation"); + + buddy_shutdown(); + return 0; +} + +static int test_fragmentation_and_oversized_alloc(void) { + CHECK(buddy_init(4096) == 0, "buddy_init should reset allocator state"); + + void *left = buddy_alloc(128); + void *middle = buddy_alloc(128); + void *right = buddy_alloc(128); + CHECK(left != NULL, "left allocation should succeed"); + CHECK(middle != NULL, "middle allocation should succeed"); + CHECK(right != NULL, "right allocation should succeed"); + + buddy_free(middle); + buddy_stats_t stats = buddy_stats(); + CHECK(stats.fragmentation_ratio >= 0.0, "fragmentation ratio should not be negative"); + CHECK(stats.fragmentation_ratio <= 1.0, "fragmentation ratio should not exceed one"); + CHECK(buddy_alloc(8192) == NULL, "oversized allocation should fail"); + + buddy_free(left); + buddy_free(right); + buddy_shutdown(); + return 0; +} + +int main(void) { + if (test_alloc_free_and_stats() != 0) { + return 1; + } + if (test_fragmentation_and_oversized_alloc() != 0) { + return 1; + } + + puts("buddy allocator tests passed"); + return 0; +}