From 1408ca9f389bd13ef7e3a5e3d636fafad3d848f3 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 27 Mar 2026 10:55:22 +0300 Subject: [PATCH 1/8] treewide: break into multiple crates Signed-off-by: NotAShelf Change-Id: Ifabe7af523ece1354b301b1a321659ee6a6a6964 --- .gitignore | 2 +- Cargo.lock | 426 +++++++------------ Cargo.toml | 45 +- crates/asm/Cargo.toml | 12 + src/syscall.rs => crates/asm/src/lib.rs | 29 +- crates/lib/Cargo.toml | 28 ++ {benches => crates/lib/benches}/benchmark.rs | 0 {src => crates/lib/src}/colors.rs | 0 {src => crates/lib/src}/desktop.rs | 0 src/main.rs => crates/lib/src/lib.rs | 124 ++++-- {src => crates/lib/src}/release.rs | 0 {src => crates/lib/src}/system.rs | 0 {src => crates/lib/src}/uptime.rs | 0 microfetch/Cargo.toml | 22 + microfetch/src/main.rs | 4 + src/lib.rs | 48 --- 16 files changed, 347 insertions(+), 393 deletions(-) create mode 100644 crates/asm/Cargo.toml rename src/syscall.rs => crates/asm/src/lib.rs (96%) create mode 100644 crates/lib/Cargo.toml rename {benches => crates/lib/benches}/benchmark.rs (100%) rename {src => crates/lib/src}/colors.rs (100%) rename {src => crates/lib/src}/desktop.rs (100%) rename src/main.rs => crates/lib/src/lib.rs (56%) rename {src => crates/lib/src}/release.rs (100%) rename {src => crates/lib/src}/system.rs (100%) rename {src => crates/lib/src}/uptime.rs (100%) create mode 100644 microfetch/Cargo.toml create mode 100644 microfetch/src/main.rs delete mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore index 8799178..3bcdd2e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/target +**/target result* /.direnv diff --git a/Cargo.lock b/Cargo.lock index 48a6768..64584ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -28,9 +28,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -43,15 +43,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -62,7 +62,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -73,14 +73,17 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys", ] [[package]] name = "arc-swap" -version = "1.7.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +checksum = "a07d1f37ff60921c83bdfc7407723bdefe89b44b98a9b772f225c8f9d67141a6" +dependencies = [ + "rustversion", +] [[package]] name = "ascii" @@ -90,21 +93,21 @@ checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "byteorder" @@ -120,9 +123,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.46" +version = "1.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36" +checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" dependencies = [ "find-msvc-tools", "shlex", @@ -130,9 +133,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chunked_transfer" @@ -169,9 +172,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.35" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" dependencies = [ "clap_builder", "clap_derive", @@ -179,9 +182,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.35" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -191,9 +194,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" dependencies = [ "heck", "proc-macro2", @@ -203,30 +206,30 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "colored" -version = "3.0.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" +checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" dependencies = [ - "windows-sys 0.59.0", + "windows-sys", ] [[package]] name = "criterion" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d883447757bb0ee46f233e9dc22eb84d93a9508c9b868687b274fc431d886bf" +checksum = "950046b2aa2492f9a536f5f4f9a3de7b9e2476e575e05bd6c333371add4d98f3" dependencies = [ "alloca", "anes", @@ -238,8 +241,6 @@ dependencies = [ "num-traits", "oorandom", "page_size", - "plotters", - "rayon", "regex", "serde", "serde_json", @@ -249,9 +250,9 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed943f81ea2faa8dcecbbfa50164acf95d555afec96a27871663b300e387b2e4" +checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea" dependencies = [ "cast", "itertools", @@ -266,25 +267,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -293,9 +275,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "dirs-next" @@ -342,21 +324,21 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.5" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", @@ -365,36 +347,35 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", "futures-macro", "futures-sink", "futures-task", "pin-project-lite", - "pin-utils", "slab", ] [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "libc", @@ -403,12 +384,13 @@ dependencies = [ [[package]] name = "half" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "zerocopy", ] [[package]] @@ -491,7 +473,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -511,15 +493,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" dependencies = [ "once_cell", "wasm-bindgen", @@ -539,19 +521,18 @@ checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libredox" -version = "0.1.10" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" dependencies = [ - "bitflags", "libc", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "mach2" @@ -561,16 +542,28 @@ checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b" [[package]] name = "memchr" -version = "2.7.4" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "microfetch" version = "0.4.13" +dependencies = [ + "microfetch-lib", +] + +[[package]] +name = "microfetch-asm" +version = "0.4.13" + +[[package]] +name = "microfetch-lib" +version = "0.4.13" dependencies = [ "criterion", "hotpath", + "microfetch-asm", ] [[package]] @@ -584,9 +577,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -612,43 +605,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "plotters" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" - -[[package]] -name = "plotters-svg" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" -dependencies = [ - "plotters-backend", -] +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "prettytable-rs" @@ -665,9 +624,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -689,9 +648,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -705,26 +664,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "redox_users" version = "0.4.6" @@ -738,9 +677,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -750,9 +689,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -761,21 +700,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "same-file" @@ -788,18 +721,28 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -808,14 +751,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] @@ -826,9 +770,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "strsim" @@ -838,9 +782,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.100" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -902,18 +846,18 @@ dependencies = [ [[package]] name = "tokio" -version = "1.48.0" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ "pin-project-lite", ] [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-width" @@ -945,35 +889,22 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -981,31 +912,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" dependencies = [ "js-sys", "wasm-bindgen", @@ -1029,11 +960,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -1048,15 +979,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.61.2" @@ -1067,65 +989,27 @@ dependencies = [ ] [[package]] -name = "windows-targets" -version = "0.52.6" +name = "zerocopy" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "zerocopy-derive", ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" +name = "zerocopy-derive" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" +name = "zmij" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index 5db56fc..2cc5650 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,36 +1,19 @@ -[package] -name = "microfetch" -description = "Microscopic fetch tool in Rust, for NixOS systems, with special emphasis on speed" -version = "0.4.13" -edition = "2024" +[workspace] +members = [ "crates/*", "microfetch" ] +resolver = "3" + +[workspace.package] authors = [ "NotAShelf " ] -rust-version = "1.91.0" -readme = "./docs/README.md" -repository = "https://github.com/notashelf/microfetch" +edition = "2024" license = "GPL-3.0" +rust-version = "1.92.0" +version = "0.4.13" -[lib] -name = "microfetch_lib" -path = "src/lib.rs" +[workspace.dependencies] +microfetch-asm = { path = "./crates/asm" } +microfetch-lib = { path = "./crates/lib" } -[[bin]] -name = "microfetch" -path = "src/main.rs" - -[dependencies] -hotpath = { optional = true, version = "0.13.0" } - -[dev-dependencies] -criterion = "0.8.1" - -[features] -hotpath = [ "dep:hotpath", "hotpath/hotpath" ] -hotpath-alloc = [ "hotpath/hotpath-alloc" ] -hotpath-off = [ "hotpath/hotpath-off" ] - -[[bench]] -harness = false -name = "benchmark" +criterion = { default-features = false, features = [ "cargo_bench_support" ], version = "0.8.2" } [profile.dev] opt-level = 1 @@ -48,15 +31,13 @@ inherits = "release" split-debuginfo = "unpacked" strip = "none" -[lints.clippy] +[workspace.lints.clippy] complexity = { level = "warn", priority = -1 } nursery = { level = "warn", priority = -1 } pedantic = { level = "warn", priority = -1 } perf = { level = "warn", priority = -1 } style = { level = "warn", priority = -1 } -# The lint groups above enable some less-than-desirable rules, we should manually -# enable those to keep our sanity. absolute_paths = "allow" arbitrary_source_item_ordering = "allow" implicit_return = "allow" diff --git a/crates/asm/Cargo.toml b/crates/asm/Cargo.toml new file mode 100644 index 0000000..24a9eac --- /dev/null +++ b/crates/asm/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "microfetch-asm" +description = "Inline assembly syscall helpers for microfetch" +version.workspace = true +edition.workspace = true +authors.workspace = true +rust-version.workspace = true +publish = false +license.workspace = true + +[lints] +workspace = true diff --git a/src/syscall.rs b/crates/asm/src/lib.rs similarity index 96% rename from src/syscall.rs rename to crates/asm/src/lib.rs index cedc68a..1a3cd87 100644 --- a/src/syscall.rs +++ b/crates/asm/src/lib.rs @@ -70,13 +70,14 @@ pub unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { /// Direct syscall to read from a file descriptor /// -/// # Returns n +/// # Returns /// /// Number of bytes read or -1 on error /// /// # Safety /// -/// The caller must ensure: +/// The caller must ensure that: +/// /// - `buf` points to a valid writable buffer of at least `count` bytes /// - `fd` is a valid open file descriptor #[inline] @@ -95,11 +96,13 @@ pub unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { lateout("r11") _, options(nostack) ); + #[allow(clippy::cast_possible_truncation)] { ret as isize } } + #[cfg(target_arch = "aarch64")] unsafe { let ret: i64; @@ -112,11 +115,13 @@ pub unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { lateout("x0") ret, options(nostack) ); + #[allow(clippy::cast_possible_truncation)] { ret as isize } } + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] { compile_error!("Unsupported architecture for inline assembly syscalls"); @@ -152,11 +157,13 @@ pub unsafe fn sys_write(fd: i32, buf: *const u8, count: usize) -> isize { lateout("r11") _, options(nostack) ); + #[allow(clippy::cast_possible_truncation)] { ret as isize } } + #[cfg(target_arch = "aarch64")] unsafe { let ret: i64; @@ -169,11 +176,13 @@ pub unsafe fn sys_write(fd: i32, buf: *const u8, count: usize) -> isize { lateout("x0") ret, options(nostack) ); + #[allow(clippy::cast_possible_truncation)] { ret as isize } } + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] { compile_error!("Unsupported architecture for inline assembly syscalls"); @@ -184,7 +193,7 @@ pub unsafe fn sys_write(fd: i32, buf: *const u8, count: usize) -> isize { /// /// # Safety /// -/// The caller must ensure `fd` is a valid open file descriptor +/// The caller must ensure that `fd` is a valid open file descriptor #[inline] #[must_use] pub unsafe fn sys_close(fd: i32) -> i32 { @@ -205,6 +214,7 @@ pub unsafe fn sys_close(fd: i32) -> i32 { ret as i32 } } + #[cfg(target_arch = "aarch64")] unsafe { let ret: i64; @@ -220,6 +230,7 @@ pub unsafe fn sys_close(fd: i32) -> i32 { ret as i32 } } + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] { compile_error!("Unsupported architecture for inline assembly syscalls"); @@ -250,7 +261,7 @@ pub struct UtsNameBuf { /// /// # Safety /// -/// The caller must ensure `buf` points to a valid `UtsNameBuf`. +/// The caller must ensure that `buf` points to a valid `UtsNameBuf`. #[inline] #[allow(dead_code)] pub unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 { @@ -266,11 +277,13 @@ pub unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 { lateout("r11") _, options(nostack) ); + #[allow(clippy::cast_possible_truncation)] { ret as i32 } } + #[cfg(target_arch = "aarch64")] unsafe { let ret: i64; @@ -286,6 +299,7 @@ pub unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 { ret as i32 } } + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] { compile_error!("Unsupported architecture for inline assembly syscalls"); @@ -342,11 +356,13 @@ pub unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 { lateout("r11") _, options(nostack) ); + #[allow(clippy::cast_possible_truncation)] { ret as i32 } } + #[cfg(target_arch = "aarch64")] unsafe { let ret: i64; @@ -358,11 +374,13 @@ pub unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 { lateout("x0") ret, options(nostack) ); + #[allow(clippy::cast_possible_truncation)] { ret as i32 } } + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] { compile_error!("Unsupported architecture for inline assembly syscalls"); @@ -379,7 +397,8 @@ pub unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 { pub fn read_file_fast(path: &str, buffer: &mut [u8]) -> io::Result { const O_RDONLY: i32 = 0; - // Use stack-allocated buffer for null-terminated path (max 256 bytes) + // We use stack-allocated buffer for null-terminated path. The maximum + // is 256 bytes. let path_bytes = path.as_bytes(); if path_bytes.len() >= 256 { return Err(io::Error::new(io::ErrorKind::InvalidInput, "Path too long")); diff --git a/crates/lib/Cargo.toml b/crates/lib/Cargo.toml new file mode 100644 index 0000000..25e8e67 --- /dev/null +++ b/crates/lib/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "microfetch-lib" +description = "Microfetch library crate - exports all functionality including main function" +version.workspace = true +edition.workspace = true +authors.workspace = true +rust-version.workspace = true +license.workspace = true +publish = false + +[dependencies] +hotpath = { optional = true, version = "0.13.0" } +microfetch-asm.workspace = true + +[features] +hotpath = [ "dep:hotpath", "hotpath/hotpath" ] +hotpath-alloc = [ "hotpath/hotpath-alloc" ] +hotpath-off = [ "hotpath/hotpath-off" ] + +[dev-dependencies] +criterion.workspace = true + +[[bench]] +harness = false +name = "benchmark" + +[lints] +workspace = true diff --git a/benches/benchmark.rs b/crates/lib/benches/benchmark.rs similarity index 100% rename from benches/benchmark.rs rename to crates/lib/benches/benchmark.rs diff --git a/src/colors.rs b/crates/lib/src/colors.rs similarity index 100% rename from src/colors.rs rename to crates/lib/src/colors.rs diff --git a/src/desktop.rs b/crates/lib/src/desktop.rs similarity index 100% rename from src/desktop.rs rename to crates/lib/src/desktop.rs diff --git a/src/main.rs b/crates/lib/src/lib.rs similarity index 56% rename from src/main.rs rename to crates/lib/src/lib.rs index 351e338..7a2c9c6 100644 --- a/src/main.rs +++ b/crates/lib/src/lib.rs @@ -1,41 +1,64 @@ -use std::io::{self, Cursor, Write}; +pub mod colors; +pub mod desktop; +pub mod release; +pub mod system; +pub mod uptime; -use microfetch_lib::{ - UtsName, - colors::{COLORS, print_dots}, - desktop::get_desktop_info, - release::{get_os_pretty_name, get_system_info}, - syscall::sys_write, - system::{ - get_memory_usage, - get_root_disk_usage, - get_shell, - get_username_and_hostname, - }, - uptime::get_current, +use std::{ + ffi::CStr, + io::{self, Cursor, Write}, + mem::MaybeUninit, }; -#[cfg_attr(feature = "hotpath", hotpath::main)] -fn main() -> Result<(), Box> { - if Some("--version") == std::env::args().nth(1).as_deref() { - println!("Microfetch {}", env!("CARGO_PKG_VERSION")); - } else { - let utsname = UtsName::uname()?; - let fields = Fields { - user_info: get_username_and_hostname(&utsname), - os_name: get_os_pretty_name()?, - kernel_version: get_system_info(&utsname), - shell: get_shell(), - desktop: get_desktop_info(), - uptime: get_current()?, - memory_usage: get_memory_usage()?, - storage: get_root_disk_usage()?, - colors: print_dots(), - }; - print_system_info(&fields)?; +pub use microfetch_asm as syscall; +pub use microfetch_asm::{ + StatfsBuf, + UtsNameBuf, + read_file_fast, + sys_close, + sys_open, + sys_read, + sys_statfs, + sys_uname, + sys_write, +}; + +/// Wrapper for `utsname` with safe accessor methods +pub struct UtsName(UtsNameBuf); + +impl UtsName { + /// Calls `uname(2)` syscall and returns a `UtsName` wrapper + /// + /// # Errors + /// + /// Returns an error if the `uname` syscall fails + pub fn uname() -> Result { + let mut uts = MaybeUninit::uninit(); + if unsafe { sys_uname(uts.as_mut_ptr()) } != 0 { + return Err(std::io::Error::last_os_error()); + } + Ok(Self(unsafe { uts.assume_init() })) } - Ok(()) + #[must_use] + pub const fn nodename(&self) -> &CStr { + unsafe { CStr::from_ptr(self.0.nodename.as_ptr().cast()) } + } + + #[must_use] + pub const fn sysname(&self) -> &CStr { + unsafe { CStr::from_ptr(self.0.sysname.as_ptr().cast()) } + } + + #[must_use] + pub const fn release(&self) -> &CStr { + unsafe { CStr::from_ptr(self.0.release.as_ptr().cast()) } + } + + #[must_use] + pub const fn machine(&self) -> &CStr { + unsafe { CStr::from_ptr(self.0.machine.as_ptr().cast()) } + } } // Struct to hold all the fields we need in order to print the fetch. This @@ -69,9 +92,9 @@ fn print_system_info( colors, } = fields; - let cyan = COLORS.cyan; - let blue = COLORS.blue; - let reset = COLORS.reset; + let cyan = colors::COLORS.cyan; + let blue = colors::COLORS.blue; + let reset = colors::COLORS.reset; let mut buf = [0u8; 2048]; let mut cursor = Cursor::new(&mut buf[..]); @@ -106,3 +129,32 @@ fn print_system_info( } Ok(()) } + +/// Main entry point for microfetch - can be called by the binary crate +/// or by other consumers of the library +/// +/// # Errors +/// +/// Returns an error if any system call fails +#[cfg_attr(feature = "hotpath", hotpath::main)] +pub fn run() -> Result<(), Box> { + if Some("--version") == std::env::args().nth(1).as_deref() { + println!("Microfetch {}", env!("CARGO_PKG_VERSION")); + } else { + let utsname = UtsName::uname()?; + let fields = Fields { + user_info: system::get_username_and_hostname(&utsname), + os_name: release::get_os_pretty_name()?, + kernel_version: release::get_system_info(&utsname), + shell: system::get_shell(), + desktop: desktop::get_desktop_info(), + uptime: uptime::get_current()?, + memory_usage: system::get_memory_usage()?, + storage: system::get_root_disk_usage()?, + colors: colors::print_dots(), + }; + print_system_info(&fields)?; + } + + Ok(()) +} diff --git a/src/release.rs b/crates/lib/src/release.rs similarity index 100% rename from src/release.rs rename to crates/lib/src/release.rs diff --git a/src/system.rs b/crates/lib/src/system.rs similarity index 100% rename from src/system.rs rename to crates/lib/src/system.rs diff --git a/src/uptime.rs b/crates/lib/src/uptime.rs similarity index 100% rename from src/uptime.rs rename to crates/lib/src/uptime.rs diff --git a/microfetch/Cargo.toml b/microfetch/Cargo.toml new file mode 100644 index 0000000..ce1cbfb --- /dev/null +++ b/microfetch/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "microfetch" +description = "Microscopic fetch tool in Rust, for NixOS systems, with special emphasis on speed" +version.workspace = true +edition.workspace = true +authors.workspace = true +rust-version.workspace = true +license.workspace = true +readme = "../docs/README.md" +repository = "https://github.com/notashelf/microfetch" +publish = false + +[dependencies] +microfetch-lib.workspace = true + +[features] +hotpath = [ "microfetch-lib/hotpath" ] +hotpath-alloc = [ "microfetch-lib/hotpath-alloc" ] +hotpath-off = [ "microfetch-lib/hotpath-off" ] + +[lints] +workspace = true diff --git a/microfetch/src/main.rs b/microfetch/src/main.rs new file mode 100644 index 0000000..36e19da --- /dev/null +++ b/microfetch/src/main.rs @@ -0,0 +1,4 @@ +#[cfg_attr(feature = "hotpath", hotpath::main)] +fn main() -> Result<(), Box> { + microfetch_lib::run() +} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index ab21d03..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,48 +0,0 @@ -pub mod colors; -pub mod desktop; -pub mod release; -pub mod syscall; -pub mod system; -pub mod uptime; - -use std::{ffi::CStr, mem::MaybeUninit}; - -use crate::syscall::{UtsNameBuf, sys_uname}; - -/// Wrapper for `utsname` with safe accessor methods -pub struct UtsName(UtsNameBuf); - -impl UtsName { - /// Calls `uname(2)` syscall and returns a `UtsName` wrapper - /// - /// # Errors - /// - /// Returns an error if the `uname` syscall fails - pub fn uname() -> Result { - let mut uts = MaybeUninit::uninit(); - if unsafe { sys_uname(uts.as_mut_ptr()) } != 0 { - return Err(std::io::Error::last_os_error()); - } - Ok(Self(unsafe { uts.assume_init() })) - } - - #[must_use] - pub const fn nodename(&self) -> &CStr { - unsafe { CStr::from_ptr(self.0.nodename.as_ptr().cast()) } - } - - #[must_use] - pub const fn sysname(&self) -> &CStr { - unsafe { CStr::from_ptr(self.0.sysname.as_ptr().cast()) } - } - - #[must_use] - pub const fn release(&self) -> &CStr { - unsafe { CStr::from_ptr(self.0.release.as_ptr().cast()) } - } - - #[must_use] - pub const fn machine(&self) -> &CStr { - unsafe { CStr::from_ptr(self.0.machine.as_ptr().cast()) } - } -} From 1c781aff562ce26dc4b8e0ffcb83f476598d31a4 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 27 Mar 2026 13:49:26 +0300 Subject: [PATCH 2/8] chore: don't benchmark binary crate; centralize assembly helpers Signed-off-by: NotAShelf Change-Id: Ia24cb1647df93034937a8fcd6cad895c6a6a6964 --- Cargo.lock | 9 +- crates/asm/src/lib.rs | 210 +++++++++++++++++++++++++++++++++++---- crates/lib/Cargo.toml | 3 +- crates/lib/src/lib.rs | 2 + crates/lib/src/uptime.rs | 75 +------------- microfetch/Cargo.toml | 6 +- microfetch/src/main.rs | 1 - 7 files changed, 203 insertions(+), 103 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64584ba..1b9a1e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,9 +417,9 @@ checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hotpath" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51462b35dc551217e1d1dd3f8c5eebbb5df7103370b1e55d24c19a3411d290f7" +checksum = "2fde50be006a0fe95cc2fd6d25d884aa6932218e4055d7df2fa0d95c386acf8d" dependencies = [ "arc-swap", "cfg-if", @@ -444,9 +444,9 @@ dependencies = [ [[package]] name = "hotpath-macros" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f022365c90cc04455f17a2b9ba5fe0e661cde1ab27434d382f1f8693fe124e7d" +checksum = "dd884cee056e269e41e1127549458e1c4e309f31897ebbc1416982a74d40a5b5" dependencies = [ "proc-macro2", "quote", @@ -550,6 +550,7 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" name = "microfetch" version = "0.4.13" dependencies = [ + "hotpath", "microfetch-lib", ] diff --git a/crates/asm/src/lib.rs b/crates/asm/src/lib.rs index 1a3cd87..a58fb96 100644 --- a/crates/asm/src/lib.rs +++ b/crates/asm/src/lib.rs @@ -5,11 +5,20 @@ //! What do you mean I wasted two whole hours to make the program only 100µs //! faster? //! -//! Supports `x86_64` and `aarch64` architectures. Riscv support will be -//! implemented when and ONLY WHEN I can be bothered to work on it. +//! Supports `x86_64`, `aarch64`, and `riscv64` architectures. use std::io; +// Ensure we're compiling for a supported architecture. +#[cfg(not(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "riscv64" +)))] +compile_error!( + "Unsupported architecture: only x86_64, aarch64, and riscv64 are supported" +); + /// Direct syscall to open a file /// /// # Returns @@ -62,9 +71,24 @@ pub unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { fd as i32 } } - #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] - { - compile_error!("Unsupported architecture for inline assembly syscalls"); + #[cfg(target_arch = "riscv64")] + unsafe { + let fd: i64; + std::arch::asm!( + "ecall", + in("a7") 56i64, // SYS_openat + in("a0") -100i32, // AT_FDCWD + in("a1") path, + in("a2") flags, + in("a3") 0i32, // mode + lateout("a0") fd, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + fd as i32 + } } } @@ -122,9 +146,23 @@ pub unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { } } - #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] - { - compile_error!("Unsupported architecture for inline assembly syscalls"); + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + std::arch::asm!( + "ecall", + in("a7") 63i64, // SYS_read + in("a0") fd, + in("a1") buf, + in("a2") count, + lateout("a0") ret, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as isize + } } } @@ -183,9 +221,23 @@ pub unsafe fn sys_write(fd: i32, buf: *const u8, count: usize) -> isize { } } - #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] - { - compile_error!("Unsupported architecture for inline assembly syscalls"); + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + std::arch::asm!( + "ecall", + in("a7") 64i64, // SYS_write + in("a0") fd, + in("a1") buf, + in("a2") count, + lateout("a0") ret, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as isize + } } } @@ -231,9 +283,20 @@ pub unsafe fn sys_close(fd: i32) -> i32 { } } - #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] - { - compile_error!("Unsupported architecture for inline assembly syscalls"); + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + std::arch::asm!( + "ecall", + in("a7") 57i64, // SYS_close + in("a0") fd, + lateout("a0") ret, + options(nostack) + ); + #[allow(clippy::cast_possible_truncation)] + { + ret as i32 + } } } @@ -300,9 +363,21 @@ pub unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 { } } - #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] - { - compile_error!("Unsupported architecture for inline assembly syscalls"); + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + std::arch::asm!( + "ecall", + in("a7") 160i64, // SYS_uname + in("a0") buf, + lateout("a0") ret, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as i32 + } } } @@ -381,9 +456,22 @@ pub unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 { } } - #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] - { - compile_error!("Unsupported architecture for inline assembly syscalls"); + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + std::arch::asm!( + "ecall", + in("a7") 43i64, // SYS_statfs + in("a0") path, + in("a1") buf, + lateout("a0") ret, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as i32 + } } } @@ -427,3 +515,85 @@ pub fn read_file_fast(path: &str, buffer: &mut [u8]) -> io::Result { } } } + +/// Raw buffer for the `sysinfo(2)` syscall. +/// +/// In the Linux ABI `uptime` is a `long` at offset 0. The remaining fields are +/// not needed, but are declared to give the struct its correct size (112 bytes +/// on 64-bit Linux). +/// +/// The layout matches the kernel's `struct sysinfo` *exactly*: +/// `mem_unit` ends at offset 108, then 4 bytes of implicit padding to 112. +#[repr(C)] +pub struct SysInfo { + pub uptime: i64, + pub loads: [u64; 3], + pub totalram: u64, + pub freeram: u64, + pub sharedram: u64, + pub bufferram: u64, + pub totalswap: u64, + pub freeswap: u64, + pub procs: u16, + _pad: u16, + _pad2: u32, /* alignment padding to reach 8-byte boundary for + * totalhigh */ + pub totalhigh: u64, + pub freehigh: u64, + pub mem_unit: u32, + // 4 bytes implicit trailing padding to reach 112 bytes total; no field + // needed +} + +/// Direct `sysinfo(2)` syscall +/// +/// # Returns +/// +/// 0 on success, negative errno on error +/// +/// # Safety +/// +/// The caller must ensure that `info` points to a valid `SysInfo` buffer. +#[inline] +pub unsafe fn sys_sysinfo(info: *mut SysInfo) -> i64 { + #[cfg(target_arch = "x86_64")] + unsafe { + let ret: i64; + std::arch::asm!( + "syscall", + in("rax") 99_i64, // __NR_sysinfo + in("rdi") info, + out("rcx") _, + out("r11") _, + lateout("rax") ret, + options(nostack) + ); + ret + } + + #[cfg(target_arch = "aarch64")] + unsafe { + let ret: i64; + std::arch::asm!( + "svc #0", + in("x8") 179_i64, // __NR_sysinfo + in("x0") info, + lateout("x0") ret, + options(nostack) + ); + ret + } + + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + std::arch::asm!( + "ecall", + in("a7") 179_i64, // __NR_sysinfo + in("a0") info, + lateout("a0") ret, + options(nostack) + ); + ret + } +} diff --git a/crates/lib/Cargo.toml b/crates/lib/Cargo.toml index 25e8e67..290932b 100644 --- a/crates/lib/Cargo.toml +++ b/crates/lib/Cargo.toml @@ -9,13 +9,12 @@ license.workspace = true publish = false [dependencies] -hotpath = { optional = true, version = "0.13.0" } +hotpath = { optional = true, version = "0.14.0" } microfetch-asm.workspace = true [features] hotpath = [ "dep:hotpath", "hotpath/hotpath" ] hotpath-alloc = [ "hotpath/hotpath-alloc" ] -hotpath-off = [ "hotpath/hotpath-off" ] [dev-dependencies] criterion.workspace = true diff --git a/crates/lib/src/lib.rs b/crates/lib/src/lib.rs index 7a2c9c6..28147f7 100644 --- a/crates/lib/src/lib.rs +++ b/crates/lib/src/lib.rs @@ -13,12 +13,14 @@ use std::{ pub use microfetch_asm as syscall; pub use microfetch_asm::{ StatfsBuf, + SysInfo, UtsNameBuf, read_file_fast, sys_close, sys_open, sys_read, sys_statfs, + sys_sysinfo, sys_uname, sys_write, }; diff --git a/crates/lib/src/uptime.rs b/crates/lib/src/uptime.rs index c6c4b26..b529f53 100644 --- a/crates/lib/src/uptime.rs +++ b/crates/lib/src/uptime.rs @@ -1,5 +1,7 @@ use std::{io, mem::MaybeUninit}; +use crate::syscall::sys_sysinfo; + /// Faster integer to string conversion without the formatting overhead. #[inline] fn itoa(mut n: u64, buf: &mut [u8]) -> &str { @@ -17,79 +19,6 @@ fn itoa(mut n: u64, buf: &mut [u8]) -> &str { unsafe { std::str::from_utf8_unchecked(&buf[i..]) } } -/// Raw buffer for the `sysinfo(2)` syscall. -/// -/// In the Linux ABI `uptime` is a `long` at offset 0. The remaining fields are -/// not needed, but are declared to give the struct its correct size (112 bytes -/// on 64-bit Linux). -/// -/// The layout matches the kernel's `struct sysinfo` *exactly*: -/// `mem_unit` ends at offset 108, then 4 bytes of implicit padding to 112. -#[repr(C)] -struct SysInfo { - uptime: i64, - loads: [u64; 3], - totalram: u64, - freeram: u64, - sharedram: u64, - bufferram: u64, - totalswap: u64, - freeswap: u64, - procs: u16, - _pad: u16, - _pad2: u32, // alignment padding to reach 8-byte boundary for totalhigh - totalhigh: u64, - freehigh: u64, - mem_unit: u32, - // 4 bytes implicit trailing padding to reach 112 bytes total; no field - // needed -} - -/// Direct `sysinfo(2)` syscall using inline assembly -/// -/// # Safety -/// -/// The caller must ensure the sysinfo pointer is valid. -#[inline] -unsafe fn sys_sysinfo(info: *mut SysInfo) -> i64 { - #[cfg(target_arch = "x86_64")] - { - let ret: i64; - unsafe { - std::arch::asm!( - "syscall", - in("rax") 99_i64, // __NR_sysinfo - in("rdi") info, - out("rcx") _, - out("r11") _, - lateout("rax") ret, - options(nostack) - ); - } - ret - } - - #[cfg(target_arch = "aarch64")] - { - let ret: i64; - unsafe { - std::arch::asm!( - "svc #0", - in("x8") 179_i64, // __NR_sysinfo - in("x0") info, - lateout("x0") ret, - options(nostack) - ); - } - ret - } - - #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] - { - compile_error!("Unsupported architecture for inline assembly syscalls"); - } -} - /// Gets the current system uptime. /// /// # Errors diff --git a/microfetch/Cargo.toml b/microfetch/Cargo.toml index ce1cbfb..4680aa8 100644 --- a/microfetch/Cargo.toml +++ b/microfetch/Cargo.toml @@ -11,12 +11,12 @@ repository = "https://github.com/notashelf/microfetch" publish = false [dependencies] +hotpath = { optional = true, version = "0.14.0" } microfetch-lib.workspace = true [features] -hotpath = [ "microfetch-lib/hotpath" ] -hotpath-alloc = [ "microfetch-lib/hotpath-alloc" ] -hotpath-off = [ "microfetch-lib/hotpath-off" ] +hotpath = [ "dep:hotpath" ] +hotpath-alloc = [ "hotpath/hotpath-alloc" ] [lints] workspace = true diff --git a/microfetch/src/main.rs b/microfetch/src/main.rs index 36e19da..8f22041 100644 --- a/microfetch/src/main.rs +++ b/microfetch/src/main.rs @@ -1,4 +1,3 @@ -#[cfg_attr(feature = "hotpath", hotpath::main)] fn main() -> Result<(), Box> { microfetch_lib::run() } From 0d4377ffcaf667ce248781f99ed2c7abced137fd Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 27 Mar 2026 14:38:15 +0300 Subject: [PATCH 3/8] ci: use cargo-cross for multi-arch testing Signed-off-by: NotAShelf Change-Id: I6f5fac0de48162e114976da3aa5adf216a6a6964 --- .github/workflows/rust.yml | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 5f435fb..7367640 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -12,15 +12,14 @@ env: jobs: test: name: Test on ${{ matrix.target }} - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest strategy: fail-fast: false matrix: - include: - - os: ubuntu-latest - target: x86_64-unknown-linux-gnu - - os: ubuntu-latest - target: aarch64-unknown-linux-gnu + target: + - x86_64-unknown-linux-gnu + - aarch64-unknown-linux-gnu + - riscv64gc-unknown-linux-gnu steps: - name: "Checkout" @@ -31,24 +30,12 @@ jobs: with: target: ${{ matrix.target }} - - name: "Install cross-compilation tools" - if: matrix.target == 'aarch64-unknown-linux-gnu' - run: | - sudo apt-get update - sudo apt-get install -y gcc-aarch64-linux-gnu - - - name: "Configure linker for aarch64" - if: matrix.target == 'aarch64-unknown-linux-gnu' - run: | - mkdir -p .cargo - cat >> .cargo/config.toml << EOF - [target.aarch64-unknown-linux-gnu] - linker = "aarch64-linux-gnu-gcc" - EOF + - name: "Install cross" + run: cargo install cross --git https://github.com/cross-rs/cross - name: "Build" - run: cargo build --verbose --target ${{ matrix.target }} + run: cross build --verbose --target ${{ matrix.target }} - name: "Run tests" if: matrix.target == 'x86_64-unknown-linux-gnu' - run: cargo test --verbose --target ${{ matrix.target }} + run: cross test --verbose --target ${{ matrix.target }} From 35d0f67812c62be053b5fe2b72c5fae1f11138c1 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 27 Mar 2026 15:31:42 +0300 Subject: [PATCH 4/8] chore: use clang only on `x86_64-unknown-linux-gnu` I don't want to configure cargo-cross tbh Signed-off-by: NotAShelf Change-Id: I749bc02bbdf8922fdf7a5904508b8af66a6a6964 --- .cargo/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index b7efcee..e989948 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,4 +1,4 @@ # https://github.com/rui314/mold?tab=readme-ov-file#how-to-use -[target.'cfg(target_os = "linux")'] +[target.x86_64-unknown-linux-gnu] linker = "clang" rustflags = ["-C", "link-arg=-fuse-ld=mold"] From 26c7a9f528d1f15cc78857b5e3855d897109b66f Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 27 Mar 2026 15:44:28 +0300 Subject: [PATCH 5/8] ci: use hotpath-utils for benchmark workflows Signed-off-by: NotAShelf Change-Id: Iaae187e8320a3642c813ca2095a616056a6a6964 --- .github/workflows/hotpath-comment.yml | 50 +++++----------- .github/workflows/hotpath-profile.yml | 85 +++++++++++++-------------- 2 files changed, 56 insertions(+), 79 deletions(-) diff --git a/.github/workflows/hotpath-comment.yml b/.github/workflows/hotpath-comment.yml index 2fd3ca9..e1ed5df 100644 --- a/.github/workflows/hotpath-comment.yml +++ b/.github/workflows/hotpath-comment.yml @@ -14,49 +14,31 @@ jobs: comment: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion == 'success' }} - steps: - - name: Checkout - uses: actions/checkout@v6 + - uses: actions/checkout@v4 - - name: Download profiling results - uses: actions/download-artifact@v8 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + + - uses: actions/download-artifact@v4 with: - name: hotpath-results - path: /tmp/ + name: profile-metrics + path: /tmp/metrics/ github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} - - name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@v1 + - name: Install hotpath-utils CLI + run: cargo install hotpath --bin hotpath-utils --features=utils - - name: Install hotpath CLI - run: cargo install hotpath - - - name: Post timing comparison comment + - name: Post PR comment env: GH_TOKEN: ${{ github.token }} run: | set -euo pipefail - HEAD_METRICS=$(cat /tmp/head_timing.json) - BASE_METRICS=$(cat /tmp/base_timing.json) - PR_NUMBER=$(cat /tmp/pr_number.txt) - hotpath profile-pr \ - --head-metrics "$HEAD_METRICS" \ - --base-metrics "$BASE_METRICS" \ + export GITHUB_BASE_REF=$(cat /tmp/metrics/base_ref.txt) + export GITHUB_HEAD_REF=$(cat /tmp/metrics/head_ref.txt) + hotpath-utils profile-pr \ + --head-metrics /tmp/metrics/head_timing.json \ + --base-metrics /tmp/metrics/base_timing.json \ --github-token "$GH_TOKEN" \ - --pr-number "$PR_NUMBER" - - - name: Post allocation comparison comment - env: - GH_TOKEN: ${{ github.token }} - run: | - set -euo pipefail - HEAD_METRICS=$(cat /tmp/head_alloc.json) - BASE_METRICS=$(cat /tmp/base_alloc.json) - PR_NUMBER=$(cat /tmp/pr_number.txt) - hotpath profile-pr \ - --head-metrics "$HEAD_METRICS" \ - --base-metrics "$BASE_METRICS" \ - --github-token "$GH_TOKEN" \ - --pr-number "$PR_NUMBER" + --pr-number "$(cat /tmp/metrics/pr_number.txt)" \ + --benchmark-id "timing" diff --git a/.github/workflows/hotpath-profile.yml b/.github/workflows/hotpath-profile.yml index 5fa1026..244fb2b 100644 --- a/.github/workflows/hotpath-profile.yml +++ b/.github/workflows/hotpath-profile.yml @@ -4,62 +4,57 @@ on: pull_request: branches: [ "main" ] -env: - CARGO_TERM_COLOR: always +permissions: + contents: read jobs: profile: runs-on: ubuntu-latest - steps: - - name: Checkout PR HEAD - uses: actions/checkout@v6 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - - name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@v1 - - - name: Run timing profiling on HEAD + + - uses: actions-rust-lang/setup-rust-toolchain@v1 + + - name: Create metrics directory + run: mkdir -p /tmp/metrics + + - name: Head benchmark (timing) env: - HOTPATH_JSON: "true" - run: | - cargo run --features='hotpath' 2>&1 | grep '^{"hotpath_profiling_mode"' > /tmp/head_timing.json - - - name: Run allocation profiling on HEAD + HOTPATH_OUTPUT_FORMAT: json + HOTPATH_OUTPUT_PATH: /tmp/metrics/head_timing.json + run: cargo run -p microfetch --release --features='hotpath' + + - name: Head benchmark (alloc) env: - HOTPATH_JSON: "true" - run: | - cargo run --features='hotpath,hotpath-alloc' 2>&1 | grep '^{"hotpath_profiling_mode"' > /tmp/head_alloc.json - - - name: Checkout base branch - run: | - git checkout ${{ github.event.pull_request.base.sha }} - - - name: Run timing profiling on base + HOTPATH_OUTPUT_FORMAT: json + HOTPATH_OUTPUT_PATH: /tmp/metrics/head_alloc.json + run: cargo run -p microfetch --release --features='hotpath,hotpath-alloc' + + - name: Checkout base + run: git checkout ${{ github.event.pull_request.base.sha }} + + - name: Base benchmark (timing) env: - HOTPATH_JSON: "true" - run: | - cargo run --features='hotpath' 2>&1 | grep '^{"hotpath_profiling_mode"' > /tmp/base_timing.json || echo '{}' > /tmp/base_timing.json - - - name: Run allocation profiling on base + HOTPATH_OUTPUT_FORMAT: json + HOTPATH_OUTPUT_PATH: /tmp/metrics/base_timing.json + run: cargo run -p microfetch --release --features='hotpath' || echo '{}' > /tmp/metrics/base_timing.json + + - name: Base benchmark (alloc) env: - HOTPATH_JSON: "true" + HOTPATH_OUTPUT_FORMAT: json + HOTPATH_OUTPUT_PATH: /tmp/metrics/base_alloc.json + run: cargo run -p microfetch --release --features='hotpath,hotpath-alloc' || echo '{}' > /tmp/metrics/base_alloc.json + + - name: Save PR metadata run: | - cargo run --features='hotpath,hotpath-alloc' 2>&1 | grep '^{"hotpath_profiling_mode"' > /tmp/base_alloc.json || echo '{}' > /tmp/base_alloc.json - - - name: Save PR number - run: | - echo '${{ github.event.pull_request.number }}' > /tmp/pr_number.txt - - - name: Upload profiling results - uses: actions/upload-artifact@v7 + echo '${{ github.event.pull_request.number }}' > /tmp/metrics/pr_number.txt + echo '${{ github.base_ref }}' > /tmp/metrics/base_ref.txt + echo '${{ github.head_ref }}' > /tmp/metrics/head_ref.txt + + - uses: actions/upload-artifact@v4 with: - name: hotpath-results - path: | - /tmp/head_timing.json - /tmp/head_alloc.json - /tmp/base_timing.json - /tmp/base_alloc.json - /tmp/pr_number.txt + name: profile-metrics + path: /tmp/metrics/ retention-days: 1 From d8da2218a4879a2c3591e46d496f2099f7785506 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 27 Mar 2026 16:28:26 +0300 Subject: [PATCH 6/8] ci: use mold globally; drop clang linker Signed-off-by: NotAShelf Change-Id: Iadb9cd4ce33acdd2de585a740ac72da86a6a6964 --- .cargo/config.toml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index e989948..c7125dc 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,4 +1,3 @@ # https://github.com/rui314/mold?tab=readme-ov-file#how-to-use -[target.x86_64-unknown-linux-gnu] -linker = "clang" -rustflags = ["-C", "link-arg=-fuse-ld=mold"] +[target.'cfg(target_os = "linux")'] +rustflags = [ "-C", "link-arg=-fuse-ld=mold" ] From 23e994a8fb4eb669d153aded0a49f5f77305eb84 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 27 Mar 2026 16:29:47 +0300 Subject: [PATCH 7/8] ci: make Mold the default linker Signed-off-by: NotAShelf Change-Id: I36756896731a4df6903fcafea68246c76a6a6964 --- .github/workflows/rust.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 7367640..deb45e3 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -30,6 +30,9 @@ jobs: with: target: ${{ matrix.target }} + - name: "Make Mold the default linker" + uses: rui314/setup-mold@v1 + - name: "Install cross" run: cargo install cross --git https://github.com/cross-rs/cross From 77d9c725c7f123c165972f5aa8eb551f5af7154e Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 27 Mar 2026 16:57:50 +0300 Subject: [PATCH 8/8] meta: move benchmarks to dedicated crate Signed-off-by: NotAShelf Change-Id: I753245e75da3a995c622a2c73f77bcb26a6a6964 --- Cargo.lock | 89 ++++++++++++++++++- Cargo.toml | 5 +- crates/benchmarks/Cargo.toml | 21 +++++ .../benches/microfetch.rs} | 0 crates/lib/Cargo.toml | 7 -- 5 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 crates/benchmarks/Cargo.toml rename crates/{lib/benches/benchmark.rs => benchmarks/benches/microfetch.rs} (100%) diff --git a/Cargo.lock b/Cargo.lock index 1b9a1e3..fa82609 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -241,6 +241,8 @@ dependencies = [ "num-traits", "oorandom", "page_size", + "plotters", + "rayon", "regex", "serde", "serde_json", @@ -248,6 +250,16 @@ dependencies = [ "walkdir", ] +[[package]] +name = "criterion-cycles-per-byte" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5396de42a52e9e5d8f67ef0702dae30451f310a9ba1c3094dcf228f0be0e54bc" +dependencies = [ + "cfg-if", + "criterion", +] + [[package]] name = "criterion-plot" version = "0.8.2" @@ -267,6 +279,25 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -559,10 +590,18 @@ name = "microfetch-asm" version = "0.4.13" [[package]] -name = "microfetch-lib" +name = "microfetch-bench" version = "0.4.13" dependencies = [ "criterion", + "criterion-cycles-per-byte", + "microfetch-lib", +] + +[[package]] +name = "microfetch-lib" +version = "0.4.13" +dependencies = [ "hotpath", "microfetch-asm", ] @@ -610,6 +649,34 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + [[package]] name = "prettytable-rs" version = "0.10.0" @@ -665,6 +732,26 @@ dependencies = [ "bitflags", ] +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_users" version = "0.4.6" diff --git a/Cargo.toml b/Cargo.toml index 2cc5650..f8bd2a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = [ "crates/*", "microfetch" ] +members = [ "crates/*", "microfetch", "crates/benchmarks" ] resolver = "3" [workspace.package] @@ -13,7 +13,8 @@ version = "0.4.13" microfetch-asm = { path = "./crates/asm" } microfetch-lib = { path = "./crates/lib" } -criterion = { default-features = false, features = [ "cargo_bench_support" ], version = "0.8.2" } +criterion = { default-features = false, features = [ "cargo_bench_support" ], version = "0.8.2" } +criterion-cycles-per-byte = "0.8.0" [profile.dev] opt-level = 1 diff --git a/crates/benchmarks/Cargo.toml b/crates/benchmarks/Cargo.toml new file mode 100644 index 0000000..22fcd8e --- /dev/null +++ b/crates/benchmarks/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "microfetch-bench" +description = "Benchmarks for microfetch" +version.workspace = true +edition.workspace = true +authors.workspace = true +rust-version.workspace = true +license.workspace = true +publish = false + +[dependencies] +criterion.workspace = true +criterion-cycles-per-byte.workspace = true +microfetch-lib.workspace = true + +[[bench]] +harness = false +name = "microfetch" + +[lints] +workspace = true diff --git a/crates/lib/benches/benchmark.rs b/crates/benchmarks/benches/microfetch.rs similarity index 100% rename from crates/lib/benches/benchmark.rs rename to crates/benchmarks/benches/microfetch.rs diff --git a/crates/lib/Cargo.toml b/crates/lib/Cargo.toml index 290932b..176502a 100644 --- a/crates/lib/Cargo.toml +++ b/crates/lib/Cargo.toml @@ -16,12 +16,5 @@ microfetch-asm.workspace = true hotpath = [ "dep:hotpath", "hotpath/hotpath" ] hotpath-alloc = [ "hotpath/hotpath-alloc" ] -[dev-dependencies] -criterion.workspace = true - -[[bench]] -harness = false -name = "benchmark" - [lints] workspace = true