瀏覽代碼

Utilities/allocate: Modernize the code a bit

Use LibCore ArgsParser to parse the parameters instead of using the raw
strings from the argv (Main::Arguments) array.

Also, use indicative names for variables in the code so the utility code
is more understandable.
Liav A 2 年之前
父節點
當前提交
b74cb569ec
共有 2 個文件被更改,包括 107 次插入55 次删除
  1. 68 20
      Base/usr/share/man/man1/allocate.md
  2. 39 35
      Userland/Utilities/allocate.cpp

+ 68 - 20
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
+
 ```

+ 39 - 35
Userland/Utilities/allocate.cpp

@@ -1,81 +1,85 @@
 /*
  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <AK/Format.h>
 #include <AK/Optional.h>
+#include <LibCore/ArgsParser.h>
 #include <LibCore/ElapsedTimer.h>
 #include <LibMain/Main.h>
 #include <unistd.h>
 
-static void usage()
-{
-    warnln("usage: allocate [number [unit (B/KiB/MiB)]]");
-    exit(1);
-}
-
 enum class Unit {
     Bytes,
     KiB,
     MiB,
+    GiB,
 };
 
 ErrorOr<int> serenity_main(Main::Arguments arguments)
 {
-    int count = 50;
-    auto unit = Unit::MiB;
-
-    if (arguments.argc >= 2) {
-        auto number = arguments.strings[1].to_uint();
-        if (!number.has_value()) {
-            usage();
-        }
-        count = number.value();
-    }
-
-    if (arguments.argc >= 3) {
-        if (arguments.strings[2] == "B")
+    size_t iterations_count = 10;
+    size_t allocation_size = 100;
+    auto unit = Unit::Bytes;
+    StringView chosen_unit {};
+
+    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 (!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<char*>(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<int> 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.");