diff --git a/Base/usr/share/man/man1/allocate.md b/Base/usr/share/man/man1/allocate.md index 8a8282408b..5f43506be7 100644 --- a/Base/usr/share/man/man1/allocate.md +++ b/Base/usr/share/man/man1/allocate.md @@ -5,36 +5,31 @@ allocate - allocate memory ## Synopsis ```**sh -$ allocate [number [unit (B/KiB/MiB)]] +$ allocate [--unit B/KiB/MiB/GiB] [--sleep-time N] [number] ``` ## Description -`allocate` allocates a specific amount of virtual memory (specified in `number` and `unit`, by default 50 MiB), It also writes to each allocated page and then sleeps for 10 seconds. It is primarily used to test the kernel's memory management capabilities. +`allocate` allocates a specific amount of virtual memory. If nothing is specified +then it will allocate 100 bytes of memory. +If `number` is specified without `unit`, it will default to `number` of bytes. +It also writes to each allocated page and then sleeps for N seconds (by default 10). +It is primarily used to test the kernel's memory management capabilities. -## Arguments +## Options -* `number`: A number of `units` to allocate; the default is **50** -* `unit`: Data size unit, can be `B` (bytes), `KiB` (kibibytes) or `MiB` (mebibytes); the default is **MiB** +* `-u`, `--size-unit`: Allocation's Size Unit (Base 2 units - B, KiB, MiB or GiB) +* `-n`, `--sleep-time`: Number of seconds to sleep before freeing memory ## Examples ```sh -$ allocate 100 MiB -allocating memory (104857600 bytes)... -done in 13ms +$ allocate 500 +allocating memory (500 bytes)... +done in 0ms writing one byte to each page of allocated memory... -step took 46ms (217.391304MiB/s) -step took 32ms (312.500000MiB/s) -step took 31ms (322.580645MiB/s) -step took 55ms (181.818181MiB/s) -step took 35ms (285.714285MiB/s) -step took 40ms (250.000000MiB/s) -step took 39ms (256.410256MiB/s) -step took 52ms (192.307692MiB/s) -step took 44ms (227.272727MiB/s) -done in 426ms -sleeping for ten seconds... +done in 0ms +sleeping for 10 seconds... 0 1 2 @@ -47,5 +42,58 @@ sleeping for ten seconds... 9 done. freeing memory... -done in 119ms +done in 0ms + +$ allocate 500 -u KiB +allocating memory (512000 bytes)... +done in 0ms +writing one byte to each page of allocated memory... +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +done in 4ms +sleeping for 10 seconds... +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +done. +freeing memory... +done in 0ms + +$ allocate -u KiB -n 2 500 +allocating memory (512000 bytes)... +done in 0ms +writing one byte to each page of allocated memory... +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +step took 1ms (46.875MiB/s) +done in 0ms +sleeping for 2 seconds... +0 +1 +done. +freeing memory... +done in 0ms + ``` diff --git a/Userland/Utilities/allocate.cpp b/Userland/Utilities/allocate.cpp index 3cd582365c..b58aeab143 100644 --- a/Userland/Utilities/allocate.cpp +++ b/Userland/Utilities/allocate.cpp @@ -1,81 +1,85 @@ /* * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2023, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #include #include +#include #include #include #include -static void usage() -{ - warnln("usage: allocate [number [unit (B/KiB/MiB)]]"); - exit(1); -} - enum class Unit { Bytes, KiB, MiB, + GiB, }; ErrorOr serenity_main(Main::Arguments arguments) { - int count = 50; - auto unit = Unit::MiB; + size_t iterations_count = 10; + size_t allocation_size = 100; + auto unit = Unit::Bytes; + StringView chosen_unit {}; - if (arguments.argc >= 2) { - auto number = arguments.strings[1].to_uint(); - if (!number.has_value()) { - usage(); - } - count = number.value(); - } + Core::ArgsParser args_parser; + args_parser.add_option(chosen_unit, "Allocation's Size Unit in base 2 (B, KiB, MiB, GiB)", "unit", 'u', "unit"); + args_parser.add_option(iterations_count, "Number of seconds to sleep before freeing memory", "sleep-time", 'n', "seconds"); + args_parser.add_positional_argument(allocation_size, "Allocation Size", "size", Core::ArgsParser::Required::No); + args_parser.parse(arguments); - if (arguments.argc >= 3) { - if (arguments.strings[2] == "B") + if (!chosen_unit.is_null()) { + if (chosen_unit == "B"sv) { unit = Unit::Bytes; - else if (arguments.strings[2] == "KiB") + } else if (chosen_unit == "KiB"sv) { unit = Unit::KiB; - else if (arguments.strings[2] == "MiB") + } else if (chosen_unit == "MiB") { unit = Unit::MiB; - else - usage(); + } else if (chosen_unit == "GiB") { + unit = Unit::GiB; + } else { + args_parser.print_usage(stderr, arguments.strings[0]); + return 1; + } } switch (unit) { case Unit::Bytes: break; case Unit::KiB: - count *= KiB; + allocation_size *= KiB; break; case Unit::MiB: - count *= MiB; + allocation_size *= MiB; + break; + case Unit::GiB: + allocation_size *= GiB; break; } - outln("allocating memory ({} bytes)...", count); + outln("allocating memory ({} bytes)...", allocation_size); auto timer = Core::ElapsedTimer::start_new(); - char* ptr = (char*)malloc(count); + auto* ptr = reinterpret_cast(malloc(allocation_size)); if (!ptr) { outln("failed."); return 1; } outln("done in {}ms", timer.elapsed_milliseconds()); - auto pages = count / PAGE_SIZE; - auto step = pages / 10; + size_t pages_count = allocation_size / PAGE_SIZE; + auto step = pages_count / 10; outln("writing one byte to each page of allocated memory..."); timer.start(); auto timer2 = Core::ElapsedTimer::start_new(); - for (int i = 0; i < pages; ++i) { - ptr[i * PAGE_SIZE] = 1; + for (size_t page_index = 0; page_index < pages_count; ++page_index) { + ptr[page_index * PAGE_SIZE] = 1; - if (i != 0 && (i % step) == 0) { + if (page_index != 0 && (page_index % step) == 0) { auto ms = timer2.elapsed_milliseconds(); if (ms == 0) ms = 1; @@ -89,9 +93,9 @@ ErrorOr serenity_main(Main::Arguments arguments) } outln("done in {}ms", timer.elapsed_milliseconds()); - outln("sleeping for ten seconds..."); - for (int i = 0; i < 10; i++) { - outln("{}", i); + outln("sleeping for {} seconds...", iterations_count); + for (unsigned iteration_index = 0; iteration_index < iterations_count; iteration_index++) { + outln("{}", iteration_index); sleep(1); } outln("done.");