diff --git a/Cargo.lock b/Cargo.lock index 3f4d52a..f3adad2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,18 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -11,6 +23,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -94,9 +112,9 @@ checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytesize" @@ -104,11 +122,26 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "castaway" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" +dependencies = [ + "rustversion", +] + [[package]] name = "cc" -version = "1.0.90" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" [[package]] name = "cfg-if" @@ -158,9 +191,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "885e4d7d5af40bfb99ae6f9433e292feac98d452dcb3ec3d25dfe7552b77da8c" +checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e" dependencies = [ "clap", ] @@ -187,6 +220,19 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "compact_str" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "ryu", + "static_assertions", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -218,6 +264,31 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.5.0", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + [[package]] name = "deranged" version = "0.3.11" @@ -269,9 +340,9 @@ checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "libc", @@ -284,6 +355,22 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -313,6 +400,12 @@ dependencies = [ "cc", ] +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -324,6 +417,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -357,18 +459,49 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown", +] + [[package]] name = "memchr" version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + [[package]] name = "nix" version = "0.28.0" @@ -429,6 +562,35 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "phf" version = "0.11.2" @@ -506,11 +668,13 @@ dependencies = [ "clap", "clap_complete", "clap_mangen", + "crossterm", "libc", "phf", "phf_codegen", "pretty_assertions", "rand", + "ratatui", "regex", "rlimit", "sysinfo", @@ -519,6 +683,7 @@ dependencies = [ "uu_free", "uu_pmap", "uu_pwdx", + "uu_slabtop", "uu_w", "uu_watch", "uucore", @@ -527,9 +692,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -564,6 +729,26 @@ dependencies = [ "getrandom", ] +[[package]] +name = "ratatui" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcb12f8fbf6c62614b0d56eb352af54f6a22410c3b079eb53ee93c7b97dd31d8" +dependencies = [ + "bitflags 2.5.0", + "cassowary", + "compact_str", + "crossterm", + "indoc", + "itertools", + "lru", + "paste", + "stability", + "strum", + "unicode-segmentation", + "unicode-width", +] + [[package]] name = "rayon" version = "1.10.0" @@ -584,6 +769,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "regex" version = "1.10.4" @@ -655,6 +849,24 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.197" @@ -672,7 +884,37 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.58", +] + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", ] [[package]] @@ -681,6 +923,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + [[package]] name = "smawk" version = "0.3.2" @@ -697,17 +945,66 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "stability" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd1b177894da2a2d9120208c3386066af06a488255caabc5de8ddca22dbc3ce" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.58", +] [[package]] name = "syn" -version = "2.0.57" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -716,9 +1013,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.30.7" +version = "0.30.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c385888ef380a852a16209afc8cfad22795dd8873d69c9a14d2e2088f118d18" +checksum = "26d7c217777061d5a2d652aea771fb9ba98b6dade657204b08c4b9604d11555b" dependencies = [ "cfg-if", "core-foundation-sys", @@ -775,9 +1072,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -798,9 +1095,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -818,6 +1115,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + [[package]] name = "unicode-width" version = "0.1.11" @@ -856,6 +1159,16 @@ dependencies = [ "uucore", ] +[[package]] +name = "uu_slabtop" +version = "0.0.1" +dependencies = [ + "clap", + "crossterm", + "ratatui", + "uucore", +] + [[package]] name = "uu_w" version = "0.0.1" @@ -909,6 +1222,12 @@ version = "0.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac7a6832a5add86204d5a8d0ef41c5a11e3ddf61c0f1a508f69e7e3e1bf04e3f" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -936,7 +1255,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.58", "wasm-bindgen-shared", ] @@ -958,7 +1277,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.58", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1167,3 +1486,23 @@ name = "yansi" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] diff --git a/Cargo.toml b/Cargo.toml index bc93adb..ea892e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,13 +25,7 @@ build = "build.rs" default = ["feat_common_core"] uudoc = [] -feat_common_core = [ - "pwdx", - "free", - "w", - "watch", - "pmap", -] +feat_common_core = ["pwdx", "free", "w", "watch", "pmap", "slabtop"] [workspace.dependencies] uucore = "0.0.25" @@ -51,6 +45,8 @@ bytesize = "1.3.0" chrono = { version = "0.4.38", default-features = false, features = [ "clock", ] } +ratatui = "0.26.1" +crossterm = "0.27.0" [dependencies] clap = { workspace = true } @@ -60,7 +56,8 @@ uucore = { workspace = true } phf = { workspace = true } textwrap = { workspace = true } sysinfo = { workspace = true } - +ratatui = { workspace = true } +crossterm = { workspace = true } # pwdx = { optional = true, version = "0.0.1", package = "uu_pwdx", path = "src/uu/pwdx" } @@ -68,6 +65,7 @@ free = { optional = true, version = "0.0.1", package = "uu_free", path = "src/uu w = { optional = true, version = "0.0.1", package = "uu_w", path = "src/uu/w" } watch = { optional = true, version = "0.0.1", package = "uu_watch", path = "src/uu/watch" } pmap = { optional = true, version = "0.0.1", package = "uu_pmap", path = "src/uu/pmap" } +slabtop = { optional = true, version = "0.0.1", package = "uu_slabtop", path = "src/uu/slabtop" } [dev-dependencies] pretty_assertions = "1" diff --git a/README.md b/README.md index 69efb5f..e6f3355 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,13 @@ Ongoing: * `w`: Shows who is logged on and what they are doing. * `watch`: Executes a program periodically, showing output fullscreen. * `pmap`: Displays the memory map of a process. +* `slabtop`: Displays detailed kernel slab cache information in real time. TODO: * `ps`: Displays information about active processes. * `pgrep`: Searches for processes based on name and other attributes. * `pidwait`: Waits for a specific process to terminate. * `skill`: Sends a signal to processes based on criteria like user, terminal, etc. -* `slabtop`: Displays detailed kernel slab cache information in real time. * `tload`: Prints a graphical representation of system load average to the terminal. * `top`: Displays real-time information about system processes. * `vmstat`: Reports information about processes, memory, paging, block IO, traps, and CPU activity. diff --git a/src/uu/slabtop/Cargo.toml b/src/uu/slabtop/Cargo.toml new file mode 100644 index 0000000..ba21af7 --- /dev/null +++ b/src/uu/slabtop/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "uu_slabtop" +version = "0.0.1" +edition = "2021" +authors = ["uutils developers"] +license = "MIT" +description = "slabtop ~ (uutils) Display kernel slab cache information in real time" + +homepage = "https://github.com/uutils/procps" +repository = "https://github.com/uutils/procps/tree/main/src/uu/slabtop" +keywords = ["acl", "uutils", "cross-platform", "cli", "utility"] +categories = ["command-line-utilities"] + + +[dependencies] +uucore = { workspace = true } +clap = { workspace = true } +ratatui = { workspace = true } +crossterm = { workspace = true } + +[lib] +path = "src/slabtop.rs" + +[[bin]] +name = "slabtop" +path = "src/main.rs" diff --git a/src/uu/slabtop/slabtop.md b/src/uu/slabtop/slabtop.md new file mode 100644 index 0000000..d1b3cf6 --- /dev/null +++ b/src/uu/slabtop/slabtop.md @@ -0,0 +1,7 @@ +# slabtop + +``` +slabtop [options] +``` + +Display kernel slab cache information in real time diff --git a/src/uu/slabtop/src/main.rs b/src/uu/slabtop/src/main.rs new file mode 100644 index 0000000..69ad1c1 --- /dev/null +++ b/src/uu/slabtop/src/main.rs @@ -0,0 +1 @@ +uucore::bin!(uu_slabtop); diff --git a/src/uu/slabtop/src/parse.rs b/src/uu/slabtop/src/parse.rs new file mode 100644 index 0000000..aaacad3 --- /dev/null +++ b/src/uu/slabtop/src/parse.rs @@ -0,0 +1,295 @@ +// This file is part of the uutils procps package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. +// spell-checker:ignore (words) symdir somefakedir + +use std::{ + cmp::Ordering, + fs, + io::{Error, ErrorKind}, +}; + +#[derive(Debug, Default)] +pub(crate) struct SlabInfo { + pub(crate) meta: Vec, + pub(crate) data: Vec<(String, Vec)>, +} + +impl SlabInfo { + // parse slabinfo from /proc/slabinfo + // need root permission + pub fn new() -> Result { + let content = fs::read_to_string("/proc/slabinfo")?; + + Self::parse(content).ok_or(ErrorKind::Unsupported.into()) + } + + pub fn parse(content: String) -> Option { + let mut lines: Vec<&str> = content.lines().collect(); + + let _ = parse_version(lines.remove(0))?; + let meta = parse_meta(lines.remove(0)); + let data: Vec<(String, Vec)> = lines.into_iter().filter_map(parse_data).collect(); + + Some(SlabInfo { meta, data }) + } + + pub fn fetch(&self, name: &str, meta: &str) -> Option { + // fetch meta's offset + let offset = self.offset(meta)?; + + let (_, item) = self.data.iter().find(|(key, _)| key.eq(name))?; + + item.get(offset).copied() + } + + pub fn names(&self) -> Vec<&String> { + self.data.iter().map(|(k, _)| k).collect() + } + + pub fn sort(mut self, by: char, ascending_order: bool) -> Self { + let mut sort = |by_meta: &str| { + if let Some(offset) = self.offset(by_meta) { + self.data.sort_by(|(_, data1), (_, data2)| { + match (data1.get(offset), data2.get(offset)) { + (Some(v1), Some(v2)) => { + if ascending_order { + v1.cmp(v2) + } else { + v2.cmp(v1) + } + } + _ => Ordering::Equal, + } + }); + } + }; + + match by { + // + 'a' => sort("active_objs"), + // + 'b' => sort("objperslab"), + // Maybe cache size I guess? + // TODO: Check is + 'c' => sort("objsize"), + // + 'l' => sort("num_slabs"), + // + 'v' => sort("active_slabs"), + // name, sort by lexicographical order + 'n' => self.data.sort_by(|(name1, _), (name2, _)| { + if ascending_order { + name1.cmp(name2) + } else { + name2.cmp(name1) + } + }), + // + 'p' => sort("pagesperslab"), + // + 's' => sort("objsize"), + // sort by cache utilization + 'u' => { + let offset_active_objs = self.offset("active_objs"); + let offset_num_objs = self.offset("num_objs"); + + if let (Some(offset_active_objs), Some(offset_num_objs)) = + (offset_active_objs, offset_num_objs) + { + self.data.sort_by(|(_, data1), (_, data2)| { + let cu = |active_jobs: Option<&u64>, num_jobs: Option<&u64>| match ( + active_jobs, + num_jobs, + ) { + (Some(active_jobs), Some(num_jobs)) => { + Some((*active_jobs as f64) / (*num_jobs as f64)) + } + _ => None, + }; + let cu1 = cu(data1.get(offset_active_objs), data1.get(offset_num_objs)); + let cu2 = cu(data2.get(offset_active_objs), data2.get(offset_num_objs)); + + if let (Some(cu1), Some(cu2)) = (cu1, cu2) { + let result = if ascending_order { + cu1.partial_cmp(&cu2) + } else { + cu2.partial_cmp(&cu1) + }; + match result { + Some(ord) => ord, + None => Ordering::Equal, + } + } else { + Ordering::Equal + } + }) + } + } + + // + // Default branch : `o` + _ => sort("num_objs"), + } + + self + } + + fn offset(&self, meta: &str) -> Option { + self.meta.iter().position(|it| it.eq(meta)) + } + + /////////////////////////////////// helpers /////////////////////////////////// + + #[inline] + fn total(&self, meta: &str) -> u64 { + let Some(offset) = self.offset(meta) else { + return 0; + }; + + self.data + .iter() + .filter_map(|(_, data)| data.get(offset)) + .sum::() + } + + pub fn object_minimum(&self) -> u64 { + let Some(offset) = self.offset("objsize") else { + return 0; + }; + + match self + .data + .iter() + .filter_map(|(_, data)| data.get(offset)) + .min() + { + Some(min) => *min, + None => 0, + } + } + + pub fn object_maximum(&self) -> u64 { + let Some(offset) = self.offset("objsize") else { + return 0; + }; + + match self + .data + .iter() + .filter_map(|(_, data)| data.get(offset)) + .max() + { + Some(max) => *max, + None => 0, + } + } + + pub fn object_avg(&self) -> u64 { + let Some(offset) = self.offset("objsize") else { + return 0; + }; + + let iter = self.data.iter().filter_map(|(_, data)| data.get(offset)); + + let count = iter.clone().count(); + let sum = iter.sum::(); + + if count == 0 { + 0 + } else { + (sum) / (count as u64) + } + } + + pub fn total_active_objs(&self) -> u64 { + self.total("active_objs") + } + + pub fn total_objs(&self) -> u64 { + self.total("num_objs") + } + + pub fn total_active_slabs(&self) -> u64 { + self.total("active_slabs") + } + + pub fn total_slabs(&self) -> u64 { + self.total("num_slabs") + } + + pub fn total_active_size(&self) -> u64 { + self.names() + .iter() + .map(|name| { + self.fetch(name, "active_objs").unwrap_or_default() + * self.fetch(name, "objsize").unwrap_or_default() + }) + .sum::() + } + + pub fn total_size(&self) -> u64 { + self.names() + .iter() + .map(|name| { + self.fetch(name, "num_objs").unwrap_or_default() + * self.fetch(name, "objsize").unwrap_or_default() + }) + .sum::() + } + + pub fn total_active_cache(&self) -> u64 { + self.names() + .iter() + .map(|name| { + self.fetch(name, "objsize").unwrap_or_default() + * self.fetch(name, "active_objs").unwrap_or_default() + }) + .sum::() + } + + pub fn total_cache(&self) -> u64 { + self.names() + .iter() + .map(|name| { + self.fetch(name, "objsize").unwrap_or_default() + * self.fetch(name, "num_objs").unwrap_or_default() + }) + .sum::() + } +} + +pub(crate) fn parse_version(line: &str) -> Option { + line.replace(':', " ") + .split_whitespace() + .last() + .map(String::from) +} + +pub(crate) fn parse_meta(line: &str) -> Vec { + line.replace(['#', ':'], " ") + .split_whitespace() + .filter(|it| it.starts_with('<') && it.ends_with('>')) + .map(|it| it.replace(['<', '>'], "")) + .collect() +} + +pub(crate) fn parse_data(line: &str) -> Option<(String, Vec)> { + let split: Vec = line + .replace(':', " ") + .split_whitespace() + .map(String::from) + .collect(); + + split.first().map(|name| { + ( + name.to_string(), + split + .clone() + .into_iter() + .flat_map(|it| it.parse::()) + .collect(), + ) + }) +} diff --git a/src/uu/slabtop/src/slabtop.rs b/src/uu/slabtop/src/slabtop.rs new file mode 100644 index 0000000..ebe04f9 --- /dev/null +++ b/src/uu/slabtop/src/slabtop.rs @@ -0,0 +1,139 @@ +// This file is part of the uutils procps package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +use crate::parse::SlabInfo; +use clap::{arg, crate_version, ArgAction, Command}; +use uucore::{error::UResult, format_usage, help_about, help_usage}; + +const ABOUT: &str = help_about!("slabtop.md"); +const USAGE: &str = help_usage!("slabtop.md"); + +mod parse; + +#[uucore::main] +pub fn uumain(args: impl uucore::Args) -> UResult<()> { + let matches = uu_app().try_get_matches_from(args)?; + + let sort_flag = matches + .try_get_one::("sort") + .ok() + .unwrap_or(Some(&'o')) + .unwrap_or(&'o'); + + let slabinfo = SlabInfo::new()?.sort(*sort_flag, false); + + println!( + r" Active / Total Objects (% used) : {} / {} ({:.1}%)", + slabinfo.total_active_objs(), + slabinfo.total_objs(), + percentage(slabinfo.total_active_objs(), slabinfo.total_objs()) + ); + println!( + r" Active / Total Slabs (% used) : {} / {} ({:.1}%)", + slabinfo.total_active_slabs(), + slabinfo.total_slabs(), + percentage(slabinfo.total_active_slabs(), slabinfo.total_slabs(),) + ); + + // TODO: I don't know the 'cache' meaning. + println!( + r" Active / Total Caches (% used) : {} / {} ({:.1}%)", + slabinfo.total_active_cache(), + slabinfo.total_cache(), + percentage(slabinfo.total_active_cache(), slabinfo.total_cache()) + ); + + println!( + r" Active / Total Size (% used) : {:.2}K / {:.2}K ({:.1}%)", + to_kb(slabinfo.total_active_size()), + to_kb(slabinfo.total_size()), + percentage(slabinfo.total_active_size(), slabinfo.total_size()) + ); + + println!( + r" Minimum / Average / Maximum Object : {:.2}K / {:.2}K / {:.2}K", + to_kb(slabinfo.object_minimum()), + to_kb(slabinfo.object_avg()), + to_kb(slabinfo.object_maximum()) + ); + + // TODO: TUI Implementation + let title = format!( + "{:>6} {:>6} {:>4} {:>8} {:>6} {:>8} {:>10} {:<}", + "OBJS", "ACTIVE", "USE", "OBJ SIZE", "SLABS", "OBJ/SLAB", "CACHE SIZE", "NAME" + ); + println!("{}", title); + + output(&slabinfo); + + Ok(()) +} + +fn to_kb(byte: u64) -> f64 { + byte as f64 / 1024.0 +} + +fn percentage(numerator: u64, denominator: u64) -> f64 { + if denominator == 0 { + return 0.0; + } + + let numerator = numerator as f64; + let denominator = denominator as f64; + + (numerator / denominator) * 100.0 +} + +fn output(info: &SlabInfo) { + for name in info.names() { + let objs = info.fetch(name, "num_objs").unwrap_or_default(); + let active = info.fetch(name, "active_objs").unwrap_or_default(); + let used = format!("{:.0}%", percentage(active, objs)); + let objsize = { + let size = info.fetch(name, "objsize").unwrap_or_default(); // Byte to KB :1024 + size as f64 / 1024.0 + }; + let slabs = info.fetch(name, "num_slabs").unwrap_or_default(); + let obj_per_slab = info.fetch(name, "objperslab").unwrap_or_default(); + + let cache_size = (objsize * (objs as f64)) as u64; + let objsize = format!("{:.2}", objsize); + + let content = format!( + "{:>6} {:>6} {:>4} {:>7}K {:>6} {:>8} {:>10} {:<}", + objs, active, used, objsize, slabs, obj_per_slab, cache_size, name + ); + + println!("{}", content); + } +} + +pub fn uu_app() -> Command { + Command::new(uucore::util_name()) + .version(crate_version!()) + .about(ABOUT) + .override_usage(format_usage(USAGE)) + .infer_long_args(true) + .disable_help_flag(true) + .args([ + // arg!(-d --delay "delay updates"), + // arg!(-o --once "only display once, then exit"), + arg!(-s --sort "specify sort criteria by character (see below)"), + arg!(-h --help "display this help and exit").action(ArgAction::Help), + ]) + .after_help( + r"The following are valid sort criteria: + a: sort by number of active objects + b: sort by objects per slab + c: sort by cache size + l: sort by number of slabs + v: sort by (non display) number of active slabs + n: sort by name + o: sort by number of objects (the default) + p: sort by (non display) pages per slab + s: sort by object size + u: sort by cache utilization", + ) +} diff --git a/tests/by-util/test_slabtop.rs b/tests/by-util/test_slabtop.rs new file mode 100644 index 0000000..a4b1c4d --- /dev/null +++ b/tests/by-util/test_slabtop.rs @@ -0,0 +1,78 @@ +use crate::common::util::TestScenario; +use crate::test_slabtop::parse::parse_data; +use crate::test_slabtop::parse::parse_meta; +use crate::test_slabtop::parse::parse_version; +use crate::test_slabtop::parse::SlabInfo; + +#[path = "../../src/uu/slabtop/src/parse.rs"] +mod parse; + +#[test] +fn test_invalid_arg() { + new_ucmd!().arg("--definitely-invalid").fails().code_is(1); +} + +#[test] +fn test_slabtop() { + new_ucmd!().arg("--help").succeeds().code_is(0); +} + +#[test] +fn test_parse_version() { + let test = "slabinfo - version: 2.1"; + assert_eq!("2.1", parse_version(test).unwrap()) +} + +#[test] +fn test_parse_meta() { + let test="# name : tunables : slabdata "; + + let result = parse_meta(test); + + assert_eq!( + result, + [ + "active_objs", + "num_objs", + "objsize", + "objperslab", + "pagesperslab", + "limit", + "batchcount", + "sharedfactor", + "active_slabs", + "num_slabs", + "sharedavail" + ] + ) +} + +#[test] +fn test_parse_data() { + // Success case + + let test = "nf_conntrack_expect 0 0 208 39 2 : tunables 0 0 0 : slabdata 0 0 0"; + let (name, value) = parse_data(test).unwrap(); + + assert_eq!(name, "nf_conntrack_expect"); + assert_eq!(value, [0, 0, 208, 39, 2, 0, 0, 0, 0, 0, 0]); + + // Fail case + let test = + "0 0 208 39 2 : tunables 0 0 0 : slabdata 0 0 0"; + let (name, _value) = parse_data(test).unwrap(); + + assert_ne!(name, "nf_conntrack_expect"); +} + +#[test] +fn test_parse() { + let test = include_str!("../fixtures/slabtop/data.txt"); + let result = SlabInfo::parse(test.into()).unwrap(); + + assert_eq!(result.fetch("nf_conntrack_expect", "objsize").unwrap(), 208); + assert_eq!( + result.fetch("dmaengine-unmap-2", "active_slabs").unwrap(), + 16389 + ); +} diff --git a/tests/by-util/test_w.rs b/tests/by-util/test_w.rs index 42341e6..90053ae 100644 --- a/tests/by-util/test_w.rs +++ b/tests/by-util/test_w.rs @@ -29,13 +29,13 @@ fn test_output_format() { let output_lines = cmd.stdout_str().lines(); for line in output_lines { - let line_vec: Vec = line.split_whitespace().map(String::from).collect(); + let line_vec: Vec = line.split_whitespace().map(|s| String::from(s)).collect(); // Check the time formatting, this should be the third entry in list // For now, we are just going to check that that length of time is 5 and it has a colon, else // it is possible that a time can look like Fri13, so it can start with a letter and end // with a number assert!( - (line_vec[2].contains(':') && line_vec[2].chars().count() == 5) + (line_vec[2].contains(":") && line_vec[2].chars().count() == 5) || (line_vec[2].starts_with(char::is_alphabetic) && line_vec[2].ends_with(char::is_numeric) && line_vec[2].chars().count() == 5) diff --git a/tests/fixtures/slabtop/data.txt b/tests/fixtures/slabtop/data.txt new file mode 100644 index 0000000..8935f54 --- /dev/null +++ b/tests/fixtures/slabtop/data.txt @@ -0,0 +1,176 @@ +slabinfo - version: 2.1 +# name : tunables : slabdata +nf_conntrack_expect 0 0 208 39 2 : tunables 0 0 0 : slabdata 0 0 0 +nf_conntrack 1428 1536 256 32 2 : tunables 0 0 0 : slabdata 48 48 0 +QIPCRTR 2 78 832 39 8 : tunables 0 0 0 : slabdata 2 2 0 +ovl_inode 264 540 720 45 8 : tunables 0 0 0 : slabdata 12 12 0 +kvm_vcpu 0 0 7288 4 8 : tunables 0 0 0 : slabdata 0 0 0 +x86_emulator 0 0 2656 12 8 : tunables 0 0 0 : slabdata 0 0 0 +fat_inode_cache 12 246 792 41 8 : tunables 0 0 0 : slabdata 6 6 0 +fat_cache 0 102 40 102 1 : tunables 0 0 0 : slabdata 1 1 0 +kcopyd_job 0 0 3240 10 8 : tunables 0 0 0 : slabdata 0 0 0 +dm_uevent 0 0 2888 11 8 : tunables 0 0 0 : slabdata 0 0 0 +btrfs_delayed_ref_head 1140 1140 136 30 1 : tunables 0 0 0 : slabdata 38 38 0 +btrfs_ordered_extent 1178 1178 424 38 4 : tunables 0 0 0 : slabdata 31 31 0 +btrfs_extent_map 78368 78512 144 28 1 : tunables 0 0 0 : slabdata 2804 2804 0 +bio-304 2 25 320 25 2 : tunables 0 0 0 : slabdata 1 1 0 +bio-368 1344 1554 384 42 4 : tunables 0 0 0 : slabdata 37 37 0 +btrfs_extent_buffer 7805 13906 240 34 2 : tunables 0 0 0 : slabdata 409 409 0 +btrfs_free_space 8100 8541 104 39 1 : tunables 0 0 0 : slabdata 219 219 0 +btrfs_path 1440 1440 112 36 1 : tunables 0 0 0 : slabdata 40 40 0 +bio-384 2 36 448 36 4 : tunables 0 0 0 : slabdata 1 1 0 +btrfs_inode 81157 81172 1136 28 8 : tunables 0 0 0 : slabdata 2899 2899 0 +bio-440 2 36 448 36 4 : tunables 0 0 0 : slabdata 1 1 0 +bio-128 1260 1260 192 42 2 : tunables 0 0 0 : slabdata 30 30 0 +scsi_sense_cache 160 160 128 32 1 : tunables 0 0 0 : slabdata 5 5 0 +fsverity_info 0 0 272 30 2 : tunables 0 0 0 : slabdata 0 0 0 +fscrypt_info 0 0 128 32 1 : tunables 0 0 0 : slabdata 0 0 0 +MPTCPv6 0 0 2112 15 8 : tunables 0 0 0 : slabdata 0 0 0 +ip6-frags 0 0 184 44 2 : tunables 0 0 0 : slabdata 0 0 0 +PINGv6 0 0 1216 26 8 : tunables 0 0 0 : slabdata 0 0 0 +RAWv6 234 234 1216 26 8 : tunables 0 0 0 : slabdata 9 9 0 +UDPv6 480 480 1344 24 8 : tunables 0 0 0 : slabdata 20 20 0 +tw_sock_TCPv6 150 180 272 30 2 : tunables 0 0 0 : slabdata 6 6 0 +request_sock_TCPv6 0 0 312 26 2 : tunables 0 0 0 : slabdata 0 0 0 +TCPv6 286 286 2432 13 8 : tunables 0 0 0 : slabdata 22 22 0 +io_kiocb 0 0 256 32 2 : tunables 0 0 0 : slabdata 0 0 0 +mqueue_inode_cache 38 204 960 34 8 : tunables 0 0 0 : slabdata 6 6 0 +fuse_request 234 234 152 26 1 : tunables 0 0 0 : slabdata 9 9 0 +fuse_inode 112 468 896 36 8 : tunables 0 0 0 : slabdata 13 13 0 +kioctx 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 +userfaultfd_ctx_cache 0 0 192 42 2 : tunables 0 0 0 : slabdata 0 0 0 +dnotify_struct 0 0 32 128 1 : tunables 0 0 0 : slabdata 0 0 0 +UNIX 1495 1590 1088 30 8 : tunables 0 0 0 : slabdata 53 53 0 +ip4-frags 0 0 200 40 2 : tunables 0 0 0 : slabdata 0 0 0 +MPTCP 0 0 1984 16 8 : tunables 0 0 0 : slabdata 0 0 0 +request_sock_subflow_v6 0 0 384 42 4 : tunables 0 0 0 : slabdata 0 0 0 +request_sock_subflow_v4 0 0 384 42 4 : tunables 0 0 0 : slabdata 0 0 0 +xfrm_dst_cache 25668 25675 320 25 2 : tunables 0 0 0 : slabdata 1027 1027 0 +xfrm_state 0 0 768 42 8 : tunables 0 0 0 : slabdata 0 0 0 +ip_fib_trie 680 680 48 85 1 : tunables 0 0 0 : slabdata 8 8 0 +ip_fib_alias 584 584 56 73 1 : tunables 0 0 0 : slabdata 8 8 0 +PING 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0 +RAW 32 32 1024 32 8 : tunables 0 0 0 : slabdata 1 1 0 +tw_sock_TCP 690 690 272 30 2 : tunables 0 0 0 : slabdata 23 23 0 +request_sock_TCP 494 494 312 26 2 : tunables 0 0 0 : slabdata 19 19 0 +TCP 658 658 2304 14 8 : tunables 0 0 0 : slabdata 47 47 0 +hugetlbfs_inode_cache 25 72 664 24 4 : tunables 0 0 0 : slabdata 3 3 0 +dquot 0 0 256 32 2 : tunables 0 0 0 : slabdata 0 0 0 +bio-256 50 50 320 25 2 : tunables 0 0 0 : slabdata 2 2 0 +ep_head 5888 5888 16 256 1 : tunables 0 0 0 : slabdata 23 23 0 +dax_cache 39 39 832 39 8 : tunables 0 0 0 : slabdata 1 1 0 +request_queue 47 175 936 35 8 : tunables 0 0 0 : slabdata 5 5 0 +blkdev_ioc 184 184 88 46 1 : tunables 0 0 0 : slabdata 4 4 0 +bio-192 896 1024 256 32 2 : tunables 0 0 0 : slabdata 32 32 0 +biovec-max 429 440 4096 8 8 : tunables 0 0 0 : slabdata 55 55 0 +biovec-128 16 64 2048 16 8 : tunables 0 0 0 : slabdata 4 4 0 +biovec-64 32 192 1024 32 8 : tunables 0 0 0 : slabdata 6 6 0 +khugepaged_mm_slot 2652 2652 40 102 1 : tunables 0 0 0 : slabdata 26 26 0 +user_namespace 135 234 624 26 4 : tunables 0 0 0 : slabdata 9 9 0 +dmaengine-unmap-256 15 15 2112 15 8 : tunables 0 0 0 : slabdata 1 1 0 +dmaengine-unmap-128 30 30 1088 30 8 : tunables 0 0 0 : slabdata 1 1 0 +dmaengine-unmap-2 1048896 1048896 64 64 1 : tunables 0 0 0 : slabdata 16389 16389 0 +audit_buffer 170 1020 24 170 1 : tunables 0 0 0 : slabdata 6 6 0 +sock_inode_cache 2428 3042 832 39 8 : tunables 0 0 0 : slabdata 78 78 0 +skbuff_ext_cache 3815 4872 192 42 2 : tunables 0 0 0 : slabdata 116 116 0 +skbuff_small_head 950 950 640 25 4 : tunables 0 0 0 : slabdata 38 38 0 +skbuff_head_cache 1440 1440 256 32 2 : tunables 0 0 0 : slabdata 45 45 0 +tracefs_inode_cache 236 240 656 24 4 : tunables 0 0 0 : slabdata 10 10 0 +file_lock_cache 1036 1036 216 37 2 : tunables 0 0 0 : slabdata 28 28 0 +buffer_head 1587 1755 104 39 1 : tunables 0 0 0 : slabdata 45 45 0 +task_delay_info 38 252 144 28 1 : tunables 0 0 0 : slabdata 9 9 0 +taskstats 925 925 432 37 4 : tunables 0 0 0 : slabdata 25 25 0 +proc_dir_entry 2016 2016 192 42 2 : tunables 0 0 0 : slabdata 48 48 0 +proc_inode_cache 15645 19550 712 46 8 : tunables 0 0 0 : slabdata 425 425 0 +seq_file 1122 1122 120 34 1 : tunables 0 0 0 : slabdata 33 33 0 +sigqueue 2156 2295 80 51 1 : tunables 0 0 0 : slabdata 45 45 0 +bdev_cache 39 100 1600 20 8 : tunables 0 0 0 : slabdata 5 5 0 +shmem_inode_cache 5690 5840 800 40 8 : tunables 0 0 0 : slabdata 146 146 0 +kernfs_node_cache 56421 56480 128 32 1 : tunables 0 0 0 : slabdata 1765 1765 0 +mnt_cache 1925 1925 320 25 2 : tunables 0 0 0 : slabdata 77 77 0 +filp 23221 24768 256 32 2 : tunables 0 0 0 : slabdata 774 774 0 +inode_cache 11014 12325 640 25 4 : tunables 0 0 0 : slabdata 493 493 0 +dentry 206491 207690 192 42 2 : tunables 0 0 0 : slabdata 4945 4945 0 +names_cache 160 160 4096 8 8 : tunables 0 0 0 : slabdata 20 20 0 +net_namespace 44 63 4480 7 8 : tunables 0 0 0 : slabdata 9 9 0 +iint_cache 0 0 128 32 1 : tunables 0 0 0 : slabdata 0 0 0 +lsm_file_cache 137599 139392 32 128 1 : tunables 0 0 0 : slabdata 1089 1089 0 +uts_namespace 296 296 432 37 4 : tunables 0 0 0 : slabdata 8 8 0 +nsproxy 896 896 72 56 1 : tunables 0 0 0 : slabdata 16 16 0 +vma_lock 121072 124746 40 102 1 : tunables 0 0 0 : slabdata 1223 1223 0 +vm_area_struct 120603 123816 184 44 2 : tunables 0 0 0 : slabdata 2814 2814 0 +files_cache 1196 1196 704 46 8 : tunables 0 0 0 : slabdata 26 26 0 +signal_cache 1074 1148 1152 28 8 : tunables 0 0 0 : slabdata 41 41 0 +sighand_cache 844 885 2112 15 8 : tunables 0 0 0 : slabdata 59 59 0 +task_struct 2645 2670 6528 5 8 : tunables 0 0 0 : slabdata 534 534 0 +cred_jar 2310 2310 192 42 2 : tunables 0 0 0 : slabdata 55 55 0 +anon_vma_chain 60015 65280 64 64 1 : tunables 0 0 0 : slabdata 1020 1020 0 +anon_vma 38443 40443 104 39 1 : tunables 0 0 0 : slabdata 1037 1037 0 +pid 4045 4224 128 32 1 : tunables 0 0 0 : slabdata 132 132 0 +irq_remap_cache 27 48 8192 4 8 : tunables 0 0 0 : slabdata 12 12 0 +Acpi-State 3430 3519 80 51 1 : tunables 0 0 0 : slabdata 69 69 0 +shared_policy_node 3315 3315 48 85 1 : tunables 0 0 0 : slabdata 39 39 0 +numa_policy 30 30 272 30 2 : tunables 0 0 0 : slabdata 1 1 0 +perf_event 550 550 1264 25 8 : tunables 0 0 0 : slabdata 22 22 0 +trace_event_file 2191 2562 96 42 1 : tunables 0 0 0 : slabdata 61 61 0 +ftrace_event_field 8395 8395 56 73 1 : tunables 0 0 0 : slabdata 115 115 0 +pool_workqueue 1792 1792 512 32 4 : tunables 0 0 0 : slabdata 56 56 0 +maple_node 12054 13728 256 32 2 : tunables 0 0 0 : slabdata 429 429 0 +radix_tree_node 208307 208628 584 28 4 : tunables 0 0 0 : slabdata 7451 7451 0 +task_group 700 700 640 25 4 : tunables 0 0 0 : slabdata 28 28 0 +mm_struct 667 667 1408 23 8 : tunables 0 0 0 : slabdata 29 29 0 +vmap_area 16392 19432 72 56 1 : tunables 0 0 0 : slabdata 347 347 0 +kmalloc-cg-8k 88 88 8192 4 8 : tunables 0 0 0 : slabdata 22 22 0 +kmalloc-cg-4k 400 400 4096 8 8 : tunables 0 0 0 : slabdata 50 50 0 +kmalloc-cg-2k 864 912 2048 16 8 : tunables 0 0 0 : slabdata 57 57 0 +kmalloc-cg-1k 1132 1280 1024 32 8 : tunables 0 0 0 : slabdata 40 40 0 +kmalloc-cg-512 1462 1504 512 32 4 : tunables 0 0 0 : slabdata 47 47 0 +kmalloc-cg-256 704 704 256 32 2 : tunables 0 0 0 : slabdata 22 22 0 +kmalloc-cg-192 1638 1638 192 42 2 : tunables 0 0 0 : slabdata 39 39 0 +kmalloc-cg-128 1024 1024 128 32 1 : tunables 0 0 0 : slabdata 32 32 0 +kmalloc-cg-96 1386 1386 96 42 1 : tunables 0 0 0 : slabdata 33 33 0 +kmalloc-cg-64 2509 2752 64 64 1 : tunables 0 0 0 : slabdata 43 43 0 +kmalloc-cg-32 3584 3584 32 128 1 : tunables 0 0 0 : slabdata 28 28 0 +kmalloc-cg-16 6400 6400 16 256 1 : tunables 0 0 0 : slabdata 25 25 0 +kmalloc-cg-8 6772 7680 8 512 1 : tunables 0 0 0 : slabdata 15 15 0 +dma-kmalloc-8k 0 0 8192 4 8 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-4k 0 0 4096 8 8 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-2k 0 0 2048 16 8 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-1k 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-512 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-256 0 0 256 32 2 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-192 0 0 192 42 2 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-128 0 0 128 32 1 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-96 0 0 96 42 1 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-64 0 0 64 64 1 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-32 0 0 32 128 1 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-16 0 0 16 256 1 : tunables 0 0 0 : slabdata 0 0 0 +dma-kmalloc-8 0 0 8 512 1 : tunables 0 0 0 : slabdata 0 0 0 +kmalloc-rcl-8k 0 0 8192 4 8 : tunables 0 0 0 : slabdata 0 0 0 +kmalloc-rcl-4k 0 0 4096 8 8 : tunables 0 0 0 : slabdata 0 0 0 +kmalloc-rcl-2k 0 0 2048 16 8 : tunables 0 0 0 : slabdata 0 0 0 +kmalloc-rcl-1k 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0 +kmalloc-rcl-512 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 +kmalloc-rcl-256 32 32 256 32 2 : tunables 0 0 0 : slabdata 1 1 0 +kmalloc-rcl-192 256 336 192 42 2 : tunables 0 0 0 : slabdata 8 8 0 +kmalloc-rcl-128 1408 1408 128 32 1 : tunables 0 0 0 : slabdata 44 44 0 +kmalloc-rcl-96 3926 3948 96 42 1 : tunables 0 0 0 : slabdata 94 94 0 +kmalloc-rcl-64 39865 39872 64 64 1 : tunables 0 0 0 : slabdata 623 623 0 +kmalloc-rcl-32 0 0 32 128 1 : tunables 0 0 0 : slabdata 0 0 0 +kmalloc-rcl-16 0 0 16 256 1 : tunables 0 0 0 : slabdata 0 0 0 +kmalloc-rcl-8 0 0 8 512 1 : tunables 0 0 0 : slabdata 0 0 0 +kmalloc-8k 543 580 8192 4 8 : tunables 0 0 0 : slabdata 145 145 0 +kmalloc-4k 1201 1240 4096 8 8 : tunables 0 0 0 : slabdata 155 155 0 +kmalloc-2k 1655 1808 2048 16 8 : tunables 0 0 0 : slabdata 113 113 0 +kmalloc-1k 10620 11488 1024 32 8 : tunables 0 0 0 : slabdata 359 359 0 +kmalloc-512 18788 18880 512 32 4 : tunables 0 0 0 : slabdata 590 590 0 +kmalloc-256 16020 16192 256 32 2 : tunables 0 0 0 : slabdata 506 506 0 +kmalloc-192 3353 3444 192 42 2 : tunables 0 0 0 : slabdata 82 82 0 +kmalloc-128 19951 20160 128 32 1 : tunables 0 0 0 : slabdata 630 630 0 +kmalloc-96 5736 6258 96 42 1 : tunables 0 0 0 : slabdata 149 149 0 +kmalloc-64 22592 24256 64 64 1 : tunables 0 0 0 : slabdata 379 379 0 +kmalloc-32 20258 20480 32 128 1 : tunables 0 0 0 : slabdata 160 160 0 +kmalloc-16 25920 26112 16 256 1 : tunables 0 0 0 : slabdata 102 102 0 +kmalloc-8 30083 30208 8 512 1 : tunables 0 0 0 : slabdata 59 59 0 +kmem_cache_node 219 576 64 64 1 : tunables 0 0 0 : slabdata 9 9 0 +kmem_cache 187 352 256 32 2 : tunables 0 0 0 : slabdata 11 11 0 diff --git a/tests/tests.rs b/tests/tests.rs index 7fc2305..f66e6e5 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -24,3 +24,7 @@ mod test_watch; #[cfg(feature = "pmap")] #[path = "by-util/test_pmap.rs"] mod test_pmap; + +#[cfg(feature = "slabtop")] +#[path = "by-util/test_slabtop.rs"] +mod test_slabtop;