mirror of
https://github.com/NotAShelf/microfetch.git
synced 2026-04-12 21:07:41 +00:00
Merge pull request #56 from NotAShelf/notashelf/push-kpolspkuxwln
treewide: break into multiple crates
This commit is contained in:
commit
325bc7ab5a
22 changed files with 719 additions and 597 deletions
|
|
@ -1,4 +1,3 @@
|
|||
# https://github.com/rui314/mold?tab=readme-ov-file#how-to-use
|
||||
[target.'cfg(target_os = "linux")']
|
||||
linker = "clang"
|
||||
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
||||
rustflags = [ "-C", "link-arg=-fuse-ld=mold" ]
|
||||
|
|
|
|||
50
.github/workflows/hotpath-comment.yml
vendored
50
.github/workflows/hotpath-comment.yml
vendored
|
|
@ -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"
|
||||
|
|
|
|||
69
.github/workflows/hotpath-profile.yml
vendored
69
.github/workflows/hotpath-profile.yml
vendored
|
|
@ -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
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
|
||||
- name: Run timing profiling on HEAD
|
||||
- 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
|
||||
HOTPATH_OUTPUT_FORMAT: json
|
||||
HOTPATH_OUTPUT_PATH: /tmp/metrics/head_timing.json
|
||||
run: cargo run -p microfetch --release --features='hotpath'
|
||||
|
||||
- name: Run allocation profiling on HEAD
|
||||
- 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
|
||||
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 branch
|
||||
run: |
|
||||
git checkout ${{ github.event.pull_request.base.sha }}
|
||||
- name: Checkout base
|
||||
run: git checkout ${{ github.event.pull_request.base.sha }}
|
||||
|
||||
- name: Run timing profiling on base
|
||||
- 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
|
||||
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: Run allocation profiling on base
|
||||
- name: Base benchmark (alloc)
|
||||
env:
|
||||
HOTPATH_JSON: "true"
|
||||
run: |
|
||||
cargo run --features='hotpath,hotpath-alloc' 2>&1 | grep '^{"hotpath_profiling_mode"' > /tmp/base_alloc.json || echo '{}' > /tmp/base_alloc.json
|
||||
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 number
|
||||
- name: Save PR metadata
|
||||
run: |
|
||||
echo '${{ github.event.pull_request.number }}' > /tmp/pr_number.txt
|
||||
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
|
||||
|
||||
- name: Upload profiling results
|
||||
uses: actions/upload-artifact@v7
|
||||
- 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
|
||||
|
|
|
|||
32
.github/workflows/rust.yml
vendored
32
.github/workflows/rust.yml
vendored
|
|
@ -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,15 @@ 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: "Make Mold the default linker"
|
||||
uses: rui314/setup-mold@v1
|
||||
|
||||
- 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 }}
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,3 +1,3 @@
|
|||
/target
|
||||
**/target
|
||||
result*
|
||||
/.direnv
|
||||
|
|
|
|||
396
Cargo.lock
generated
396
Cargo.lock
generated
|
|
@ -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",
|
||||
|
|
@ -248,10 +251,20 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.8.1"
|
||||
name = "criterion-cycles-per-byte"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed943f81ea2faa8dcecbbfa50164acf95d555afec96a27871663b300e387b2e4"
|
||||
checksum = "5396de42a52e9e5d8f67ef0702dae30451f310a9ba1c3094dcf228f0be0e54bc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"criterion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools",
|
||||
|
|
@ -293,9 +306,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 +355,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 +378,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 +415,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]]
|
||||
|
|
@ -435,9 +448,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",
|
||||
|
|
@ -462,9 +475,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",
|
||||
|
|
@ -491,7 +504,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
|
|||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -511,15 +524,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 +552,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 +573,37 @@ 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 = [
|
||||
"criterion",
|
||||
"hotpath",
|
||||
"microfetch-lib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "microfetch-asm"
|
||||
version = "0.4.13"
|
||||
|
||||
[[package]]
|
||||
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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -584,9 +617,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,15 +645,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"
|
||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
|
|
@ -665,9 +692,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 +716,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",
|
||||
]
|
||||
|
|
@ -707,9 +734,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
|
|
@ -717,9 +744,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.1"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
|
|
@ -738,9 +765,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 +777,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 +788,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 +809,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 +839,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 +858,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 +870,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 +934,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 +977,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 +1000,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 +1048,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 +1067,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 +1077,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"
|
||||
|
|
|
|||
46
Cargo.toml
46
Cargo.toml
|
|
@ -1,36 +1,20 @@
|
|||
[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", "crates/benchmarks" ]
|
||||
resolver = "3"
|
||||
|
||||
[workspace.package]
|
||||
authors = [ "NotAShelf <raf@notashelf.dev>" ]
|
||||
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" }
|
||||
criterion-cycles-per-byte = "0.8.0"
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
|
@ -48,15 +32,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"
|
||||
|
|
|
|||
12
crates/asm/Cargo.toml
Normal file
12
crates/asm/Cargo.toml
Normal file
|
|
@ -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
|
||||
|
|
@ -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,21 +71,37 @@ 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 +120,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,14 +139,30 @@ 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");
|
||||
|
||||
#[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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -152,11 +195,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,14 +214,30 @@ 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");
|
||||
|
||||
#[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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +245,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 +266,7 @@ pub unsafe fn sys_close(fd: i32) -> i32 {
|
|||
ret as i32
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
unsafe {
|
||||
let ret: i64;
|
||||
|
|
@ -220,9 +282,21 @@ 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");
|
||||
|
||||
#[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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -250,7 +324,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 +340,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,9 +362,22 @@ 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");
|
||||
|
||||
#[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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -342,11 +431,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,14 +449,29 @@ 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");
|
||||
|
||||
#[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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -379,7 +485,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<usize> {
|
||||
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"));
|
||||
|
|
@ -408,3 +515,85 @@ pub fn read_file_fast(path: &str, buffer: &mut [u8]) -> io::Result<usize> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
}
|
||||
21
crates/benchmarks/Cargo.toml
Normal file
21
crates/benchmarks/Cargo.toml
Normal file
|
|
@ -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
|
||||
20
crates/lib/Cargo.toml
Normal file
20
crates/lib/Cargo.toml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
[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.14.0" }
|
||||
microfetch-asm.workspace = true
|
||||
|
||||
[features]
|
||||
hotpath = [ "dep:hotpath", "hotpath/hotpath" ]
|
||||
hotpath-alloc = [ "hotpath/hotpath-alloc" ]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
@ -1,41 +1,66 @@
|
|||
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<dyn std::error::Error>> {
|
||||
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,
|
||||
SysInfo,
|
||||
UtsNameBuf,
|
||||
read_file_fast,
|
||||
sys_close,
|
||||
sys_open,
|
||||
sys_read,
|
||||
sys_statfs,
|
||||
sys_sysinfo,
|
||||
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<Self, std::io::Error> {
|
||||
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 +94,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 +131,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<dyn std::error::Error>> {
|
||||
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(())
|
||||
}
|
||||
70
crates/lib/src/uptime.rs
Normal file
70
crates/lib/src/uptime.rs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
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 {
|
||||
if n == 0 {
|
||||
return "0";
|
||||
}
|
||||
|
||||
let mut i = buf.len();
|
||||
while n > 0 {
|
||||
i -= 1;
|
||||
buf[i] = b'0' + (n % 10) as u8;
|
||||
n /= 10;
|
||||
}
|
||||
|
||||
unsafe { std::str::from_utf8_unchecked(&buf[i..]) }
|
||||
}
|
||||
|
||||
/// Gets the current system uptime.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the system uptime cannot be retrieved.
|
||||
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
||||
pub fn get_current() -> Result<String, io::Error> {
|
||||
let uptime_seconds = {
|
||||
let mut info = MaybeUninit::uninit();
|
||||
if unsafe { sys_sysinfo(info.as_mut_ptr()) } != 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
unsafe {
|
||||
info.assume_init().uptime as u64
|
||||
}
|
||||
};
|
||||
|
||||
let days = uptime_seconds / 86400;
|
||||
let hours = (uptime_seconds / 3600) % 24;
|
||||
let minutes = (uptime_seconds / 60) % 60;
|
||||
|
||||
let mut result = String::with_capacity(32);
|
||||
let mut buf = [0u8; 20]; // Enough for u64::MAX
|
||||
|
||||
if days > 0 {
|
||||
result.push_str(itoa(days, &mut buf));
|
||||
result.push_str(if days == 1 { " day" } else { " days" });
|
||||
}
|
||||
if hours > 0 {
|
||||
if !result.is_empty() {
|
||||
result.push_str(", ");
|
||||
}
|
||||
result.push_str(itoa(hours, &mut buf));
|
||||
result.push_str(if hours == 1 { " hour" } else { " hours" });
|
||||
}
|
||||
if minutes > 0 {
|
||||
if !result.is_empty() {
|
||||
result.push_str(", ");
|
||||
}
|
||||
result.push_str(itoa(minutes, &mut buf));
|
||||
result.push_str(if minutes == 1 { " minute" } else { " minutes" });
|
||||
}
|
||||
if result.is_empty() {
|
||||
result.push_str("less than a minute");
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
22
microfetch/Cargo.toml
Normal file
22
microfetch/Cargo.toml
Normal file
|
|
@ -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]
|
||||
hotpath = { optional = true, version = "0.14.0" }
|
||||
microfetch-lib.workspace = true
|
||||
|
||||
[features]
|
||||
hotpath = [ "dep:hotpath" ]
|
||||
hotpath-alloc = [ "hotpath/hotpath-alloc" ]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
3
microfetch/src/main.rs
Normal file
3
microfetch/src/main.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
microfetch_lib::run()
|
||||
}
|
||||
48
src/lib.rs
48
src/lib.rs
|
|
@ -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<Self, std::io::Error> {
|
||||
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()) }
|
||||
}
|
||||
}
|
||||
141
src/uptime.rs
141
src/uptime.rs
|
|
@ -1,141 +0,0 @@
|
|||
use std::{io, mem::MaybeUninit};
|
||||
|
||||
/// Faster integer to string conversion without the formatting overhead.
|
||||
#[inline]
|
||||
fn itoa(mut n: u64, buf: &mut [u8]) -> &str {
|
||||
if n == 0 {
|
||||
return "0";
|
||||
}
|
||||
|
||||
let mut i = buf.len();
|
||||
while n > 0 {
|
||||
i -= 1;
|
||||
buf[i] = b'0' + (n % 10) as u8;
|
||||
n /= 10;
|
||||
}
|
||||
|
||||
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
|
||||
///
|
||||
/// Returns an error if the system uptime cannot be retrieved.
|
||||
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
||||
pub fn get_current() -> Result<String, io::Error> {
|
||||
let uptime_seconds = {
|
||||
let mut info = MaybeUninit::uninit();
|
||||
if unsafe { sys_sysinfo(info.as_mut_ptr()) } != 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
unsafe {
|
||||
info.assume_init().uptime as u64
|
||||
}
|
||||
};
|
||||
|
||||
let days = uptime_seconds / 86400;
|
||||
let hours = (uptime_seconds / 3600) % 24;
|
||||
let minutes = (uptime_seconds / 60) % 60;
|
||||
|
||||
let mut result = String::with_capacity(32);
|
||||
let mut buf = [0u8; 20]; // Enough for u64::MAX
|
||||
|
||||
if days > 0 {
|
||||
result.push_str(itoa(days, &mut buf));
|
||||
result.push_str(if days == 1 { " day" } else { " days" });
|
||||
}
|
||||
if hours > 0 {
|
||||
if !result.is_empty() {
|
||||
result.push_str(", ");
|
||||
}
|
||||
result.push_str(itoa(hours, &mut buf));
|
||||
result.push_str(if hours == 1 { " hour" } else { " hours" });
|
||||
}
|
||||
if minutes > 0 {
|
||||
if !result.is_empty() {
|
||||
result.push_str(", ");
|
||||
}
|
||||
result.push_str(itoa(minutes, &mut buf));
|
||||
result.push_str(if minutes == 1 { " minute" } else { " minutes" });
|
||||
}
|
||||
if result.is_empty() {
|
||||
result.push_str("less than a minute");
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue