ronantakizawa/codereview-bench huggingface dataset:
Repository: firecracker-microvm/firecracker
File: tests/integration_tests/functional/test_steal_time.py (Python)

Code before:
    steal_before = get_steal_time_ms(vm)

    snapshot = vm.snapshot_full()
    vm.kill()

    # Restore microVM from snapshot and resume
    restored_vm = microvm_factory.build()
    restored_vm.spawn()
    restored_vm.restore_from_snapshot(snapshot, resume=False)
    snapshot.delete()

    restored_vm.pin_vcpu(0, 0)
    restored_vm.pin_vcpu(1, 0)
    restored_vm.resume()

    # Steal time just after restoring
    steal_after_snap = get_steal_time_ms(restored_vm)

    time.sleep(2)

    # Steal time after running resumed VM
    steal_after_resume = get_steal_time_ms(restored_vm)

    # Ensure steal time persisted and continued increasing
    tolerance = 1500  # 1.5 seconds tolerance for persistence check
    persisted = steal_after_snap - steal_before < tolerance
    increased = steal_after_resume > steal_after_snap

    assert (
        persisted and increased
    ), "Steal time did not persist through snapshot or failed to increase after resume"


Review comment (suggestion):
We also want to assert it didn't go back.

```suggestion
    persisted = steal_before < steal_after_snap and steal_after_snap - steal_before < tolerance
```

Code after:
    steal_before = get_steal_time_ms(vm)

    snapshot = vm.snapshot_full()
    vm.kill()

    # Restore microVM from snapshot and resume
    restored_vm = microvm_factory.build()
    restored_vm.spawn()
    restored_vm.restore_from_snapshot(snapshot, resume=False)
    snapshot.delete()

    restored_vm.pin_vcpu(0, 0)
    restored_vm.pin_vcpu(1, 0)
    restored_vm.resume()

    # Steal time just after restoring
    steal_after_snap = get_steal_time_ms(restored_vm)

    time.sleep(2)

    # Steal time after running resumed VM
    steal_after_resume = get_steal_time_ms(restored_vm)

    # Ensure steal time persisted and continued increasing
    tolerance = 2000  # 2.0 seconds tolerance for persistence check
    persisted = (
        steal_before < steal_after_snap and steal_after_snap - steal_before < tolerance
    )
    increased = steal_after_resume > steal_after_snap

    assert (
        persisted and increased
    ), "Steal time did not persist through snapshot or failed to increase after resume"
Repository: firecracker-microvm/firecracker
File: tests/integration_tests/functional/test_net.py (Python)

Code before:
    If tap offload features are not configured, an attempt to send a message will fail with EIO "Input/output error".
    More info (search for "TUN_F_CSUM is a must"): https://blog.cloudflare.com/fr-fr/virtual-networking-101-understanding-tap/
    """
    vm = uvm_any
    port = "81"
    out_filename = "/tmp/out.txt"
    message = "x"

    # Start a UDP server in the guest
    # vm.ssh.check_output(f"nohup socat UDP-LISTEN:{port} - > {out_filename} &")
    vm.ssh.check_output(
        f"nohup socat UDP4-LISTEN:{port} OPEN:{out_filename},creat > /dev/null 2>&1 &"
    )

    # Try to send a UDP message from host with UDP offload enabled
    vm.netns.check_output(f"python3 ./host_tools/udp_offload.py {vm.ssh.host} {port}")

    # Check that the server received the message
    # Allow for some delay due to the asynchronous nature of the test
    retry = 10
    while retry > 0:
        ret = vm.ssh.run(f"sync ; cat {out_filename}")
        if ret.stdout.strip():
            break
        time.sleep(0.1)
        retry -= 1

    assert ret.stdout == message, f"{ret.stdout=} {ret.stderr=}"


Review comment (suggestion):
```suggestion
    for attempt in Retrying(
        stop=stop_after_attempt(10),
        wait=wait_fixed(0.1),
        reraise=True,
    ):
        with attempt: 
            ret = vm.ssh.check_output(f"sync; cat {out_filename}")

Code after:

    If tap offload features are not configured, an attempt to send a message will fail with EIO "Input/output error".
    More info (search for "TUN_F_CSUM is a must"): https://blog.cloudflare.com/fr-fr/virtual-networking-101-understanding-tap/
    """
    vm = uvm_any
    port = "81"
    out_filename = "/tmp/out.txt"
    message = "x"

    # Start a UDP server in the guest
    # vm.ssh.check_output(f"nohup socat UDP-LISTEN:{port} - > {out_filename} &")
    vm.ssh.check_output(
        f"nohup socat UDP4-LISTEN:{port} OPEN:{out_filename},creat > /dev/null 2>&1 &"
    )

    # Try to send a UDP message from host with UDP offload enabled
    vm.netns.check_output(f"python3 ./host_tools/udp_offload.py {vm.ssh.host} {port}")

    # Check that the server received the message
    # Allow for some delay due to the asynchronous nature of the test
    for attempt in Retrying(
        stop=stop_after_attempt(10),
        wait=wait_fixed(0.1),
        reraise=True,
    ):
        with attempt:
            ret = vm.ssh.check_output(f"sync; cat {out_filename}")
            assert ret.stdout == message, f"{ret.stdout=} {ret.stderr=}"
Repository: firecracker-microvm/firecracker
File: tools/ab_test.py (Python)

Code before:
    for dimension, distinct_values in values_per_dimension.items():
        if len(distinct_values) == 1:
            uninteresting.add(dimension)

    return uninteresting


def collect_data(tag: str, binary_dir: Path, pytest_opts: str):
    """Executes the specified test using the provided firecracker binaries"""
    binary_dir = binary_dir.resolve()

    print(f"Collecting samples with {binary_dir}")
    subprocess.run(
        f"./tools/test.sh --binary-dir={binary_dir} {pytest_opts} -m ''",
        env=os.environ
        | {
            "AWS_EMF_ENVIRONMENT": "local",
            "AWS_EMF_NAMESPACE": "local",
        },
        check=True,
        shell=True,
    )

    # move results into a tag directory
    os.mkdir(tag)
    os.rename("test_results", f"{tag}")

    return load_data_series(Path(f"{tag}/test-report.json"), binary_dir, reemit=True)


def analyze_data(
    processed_emf_a,
    processed_emf_b,
    p_thresh,
    strength_abs_thresh,
    noise_threshold,
    *,
    n_resamples: int = 9999,
):
    """
    Analyzes the A/B-test data produced by `collect_data`, by performing regression tests
    as described this script's doc-comment.

    Returns a mapping of dimensions and properties/metrics to the result of their regression test.
    """
    assert set(processed_emf_a.keys()) == set(
        processed_emf_b.keys()
    ), "A and B run produced incomparable data. This is a bug in the test!"

    results = {}


Review comment (suggestion):
```suggestion
    os.rename("test_results", tag)
```

Code after:

    for dimension, distinct_values in values_per_dimension.items():
        if len(distinct_values) == 1:
            uninteresting.add(dimension)

    return uninteresting


def collect_data(tag: str, binary_dir: Path, pytest_opts: str):
    """
    Executes the specified test using the provided firecracker binaries and
    stores results into the `test_results/tag` directory
    """
    binary_dir = binary_dir.resolve()

    print(f"Collecting samples with {binary_dir}")
    test_report_path = f"test_results/{tag}/test-report.json"
    subprocess.run(
        f"./tools/test.sh --binary-dir={binary_dir} {pytest_opts} -m '' --json-report-file=../{test_report_path}",
        env=os.environ
        | {
            "AWS_EMF_ENVIRONMENT": "local",
            "AWS_EMF_NAMESPACE": "local",
        },
        check=True,
        shell=True,
    )

    return load_data_series(Path(test_report_path), binary_dir, reemit=True)


def analyze_data(
    processed_emf_a,
    processed_emf_b,
    p_thresh,
    strength_abs_thresh,
    noise_threshold,
    *,
    n_resamples: int = 9999,
):
    """
    Analyzes the A/B-test data produced by `collect_data`, by performing regression tests
    as described this script's doc-comment.

    Returns a mapping of dimensions and properties/metrics to the result of their regression test.
    """
    assert set(processed_emf_a.keys()) == set(
        processed_emf_b.keys()
    ), "A and B run produced incomparable data. This is a bug in the test!"

    results = {}
Repository: firecracker-microvm/firecracker
File: tests/data/msr/msr_reader.c (C)

Code before:
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

// Helper script used to read MSR values from ranges known to contain MSRs.

#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>

void print_msr(int msr_fd, uint64_t msr) {
  uint64_t value;
  if (pread(msr_fd, &value, sizeof(value), msr) == sizeof(value))
    printf("0x%llx,0x%llx\n", msr, value);
}

int main() {
  int msr_fd = open("/dev/cpu/0/msr", O_RDONLY);
  if (msr_fd < 0) return -1;

  printf("MSR_ADDR,VALUE\n");
  for (uint64_t msr = 0;          msr <=      0xFFF; msr++) print_msr(msr_fd, msr);
  for (uint64_t msr = 0x10000;    msr <=    0x10FFF; msr++) print_msr(msr_fd, msr);
  for (uint64_t msr = 0xC0000000; msr <= 0xC0011030; msr++) print_msr(msr_fd, msr);

  print_msr(msr_fd, 0x400000000);
  print_msr(msr_fd, 0x2000000000);
  print_msr(msr_fd, 0x4000000000);
  print_msr(msr_fd, 0x8000000000);
  print_msr(msr_fd, 0x1000000000000);
  print_msr(msr_fd, 0x3c000000000000);
  print_msr(msr_fd, 0x80000000000000);
  print_msr(msr_fd, 0x40000000000000);
}


Review comment (suggestion):
nit, but I'd really appreciate it if you followed typical C style:

```suggestion
  for (uint64_t msr = 0; msr <= 0xFFF; msr++)
      print_msr(msr_fd, msr);
  for (uint64_t msr = 0x10000; msr <= 0x10FFF; msr++)
      print_msr(msr_fd, msr);
  for (uint64_t msr = 0xC0000000; msr <= 0xC0011030; msr++)
      print_msr(msr_fd, msr);
```

Code after:
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

// Helper script used to read MSR values from ranges known to contain MSRs.

#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>

void print_msr(int msr_fd, uint64_t msr) {
  uint64_t value;
  if (pread(msr_fd, &value, sizeof(value), msr) == sizeof(value))
    printf("0x%llx,0x%llx\n", msr, value);
}

int main() {
  int msr_fd = open("/dev/cpu/0/msr", O_RDONLY);
  if (msr_fd < 0)
    return -1;

  printf("MSR_ADDR,VALUE\n");
  for (uint64_t msr = 0; msr <= 0xFFF; msr++)
    print_msr(msr_fd, msr);
  for (uint64_t msr = 0x10000; msr <= 0x10FFF; msr++)
    print_msr(msr_fd, msr);
  for (uint64_t msr = 0xC0000000; msr <= 0xC0011030; msr++)
    print_msr(msr_fd, msr);

  print_msr(msr_fd, 0x400000000);
  print_msr(msr_fd, 0x2000000000);
  print_msr(msr_fd, 0x4000000000);
  print_msr(msr_fd, 0x8000000000);
  print_msr(msr_fd, 0x1000000000000);
  print_msr(msr_fd, 0x3c000000000000);
  print_msr(msr_fd, 0x80000000000000);
  print_msr(msr_fd, 0x40000000000000);
}
Repository: firecracker-microvm/firecracker
File: tests/integration_tests/performance/test_rate_limiter.py (Python)

Code before:
    # Don't check the result of this command because it can fail if no iperf
    # is running.
    utils.run_cmd(iperf_cmd)

    iperf_cmd = "{} {} -sD -f KBytes\n".format(netns_cmd_prefix, IPERF_BINARY)

    utils.check_output(iperf_cmd)

    # Wait for the iperf daemon to start.
    time.sleep(1)


def _run_iperf_on_host(iperf_cmd, test_microvm):
    """Execute a client related iperf command locally."""
    rc, stdout, stderr = utils.run_cmd(iperf_cmd)
    assert rc == 0, "stdout:\n{}\nstderr:\n{}\niperf server log:\n{}\n".format(
        stdout,
        stderr,
        test_microvm.ssh.check_output(f"cat {GUEST_IPERF_SERVER_LOG}").stdout,
    )
    print(f"iperf log:\n{stdout}")

    return stdout


def _diff(measured, base):
    """Return the percentage delta between the arguments."""
    assert base != 0
    return (abs(measured - base) / base) * 100.0


def _process_iperf_line(line):
    """Parse iperf3 summary line and return test time and bandwidth."""
    test_time = line.split("  ")[2].split("-")[1].strip().split(" ")[0]
    test_bw = line.split("  ")[5].split(" ")[0].strip()
    return float(test_time), float(test_bw)


def _process_iperf_output(iperf_out):
    """Parse iperf3 output and return average test time and bandwidth."""
    iperf_out_lines = iperf_out.splitlines()
    send_time = send_bw = rcv_time = rcv_bw = None
    for line in iperf_out_lines:
        if line.find("sender") != -1:
            send_time, send_bw = _process_iperf_line(line)
        if line.find("receiver") != -1:
            rcv_time, rcv_bw = _process_iperf_line(line)
    iperf_out_time = (send_time + rcv_time) / 2.0
    iperf_out_bw = (send_bw + rcv_bw) / 2.0
    return float(iperf_out_time), float(iperf_out_bw)


Review comment (suggestion):
The correct term for this quantity is "relative change". Maybe we can name the function that? :sweat_smile: 

While we're at it, we should also treat it as a number between 0 and 1 instead of multiplying it by 100. But that's more of a nit. 

Code after:


def _relative_change(measured, base):
    """Return the percentage delta between the arguments."""
    assert base != 0
    return abs(measured - base) / base


def _process_iperf_line(line):
    """Parse iperf3 summary line and return test time and bandwidth."""
    test_time = line.split("  ")[2].split("-")[1].strip().split(" ")[0]
    test_bw = line.split("  ")[5].split(" ")[0].strip()
    return float(test_time), float(test_bw)


def _process_iperf_output(iperf_out):
    """Parse iperf3 output and return average test time and bandwidth."""
    iperf_out_lines = iperf_out.splitlines()
    send_time = send_bw = rcv_time = rcv_bw = None
    for line in iperf_out_lines:
        if line.find("sender") != -1:
            send_time, send_bw = _process_iperf_line(line)
        if line.find("receiver") != -1:
            rcv_time, rcv_bw = _process_iperf_line(line)
    iperf_out_time = (send_time + rcv_time) / 2.0
    iperf_out_bw = (send_bw + rcv_bw) / 2.0
    return float(iperf_out_time), float(iperf_out_bw)
Repository: firecracker-microvm/firecracker
File: .buildkite/pipeline_docker_popular.py (Python)

Code before:
Buildkite pipeline for testing popular Docker containers
"""

from common import BKPipeline, random_str

pipeline = BKPipeline()

ROOTFS_TAR = f"rootfs_$(uname -m)_{random_str(k=8)}.tar.gz"

pipeline.build_group_per_arch(
    ":ship: Rootfs build",
    [
        "sudo yum install -y systemd-container",
        "cd tools/test-popular-containers",
        "sudo ./build_rootfs.sh",
        f'tar czf "{ROOTFS_TAR}" *.ext4 *.id_rsa',
        f'buildkite-agent artifact upload "{ROOTFS_TAR}"',
    ],
    depends_on_build=False,
    set_key=ROOTFS_TAR,
)

pipeline.build_group(
    ":whale: Docker Popular Containers",
    [
        "./tools/devtool ensure_current_artifacts_are_set_up",
        f'buildkite-agent artifact download "{ROOTFS_TAR}" .',
        f'tar xzf "{ROOTFS_TAR}" -C tools/test-popular-containers',
        './tools/devtool sh "cd ./tools/test-popular-containers; PYTHONPATH=../../tests ./test-docker-rootfs.py"',
    ],
    depends_on=ROOTFS_TAR,
)

print(pipeline.to_json())


Review comment (suggestion):
this needs to be updated as well

```
        "./tools/devtool ensure_current_artifacts",
```

Code after:
Buildkite pipeline for testing popular Docker containers
"""

from common import BKPipeline, random_str

pipeline = BKPipeline()

ROOTFS_TAR = f"rootfs_$(uname -m)_{random_str(k=8)}.tar.gz"

pipeline.build_group_per_arch(
    "rootfs-build",
    [
        "sudo yum install -y systemd-container",
        "cd tools/test-popular-containers",
        "sudo ./build_rootfs.sh",
        f'tar czf "{ROOTFS_TAR}" *.ext4 *.id_rsa',
        f'buildkite-agent artifact upload "{ROOTFS_TAR}"',
    ],
    depends_on_build=False,
    set_key=ROOTFS_TAR,
)

pipeline.build_group(
    "docker-popular-containers",
    [
        "./tools/devtool ensure_current_artifacts",
        f'buildkite-agent artifact download "{ROOTFS_TAR}" .',
        f'tar xzf "{ROOTFS_TAR}" -C tools/test-popular-containers',
        './tools/devtool sh "cd ./tools/test-popular-containers; PYTHONPATH=../../tests ./test-docker-rootfs.py"',
    ],
    depends_on=ROOTFS_TAR,
)

print(pipeline.to_json())
Repository: firecracker-microvm/firecracker
File: tests/framework/artifacts.py (Python)

Code before:
    # TODO: remove this once we drop support for MPTable
    supported_kernels.append(r"vmlinux-5.10.\d+-no-acpi")

    return supported_kernels


def kernels(glob, artifact_dir: Path = ARTIFACT_DIR) -> Iterator:
    """Return supported kernels as kernels supported by the current combination of kernel and
    instance type.
    """
    supported_kernels = select_supported_kernels()
    for kernel in sorted(artifact_dir.glob(glob)):
        for kernel_regex in supported_kernels:
            if re.fullmatch(kernel_regex, kernel.name):
                yield kernel
                break


def disks(glob) -> list:
    """Return supported rootfs"""
    return sorted(ARTIFACT_DIR.glob(glob))


def kernel_params(glob="vmlinux-*", select=kernels, artifact_dir=ARTIFACT_DIR) -> list:
    """Return supported kernels"""
    params = [
        pytest.param(kernel, id=kernel.name) for kernel in select(glob, artifact_dir)
    ]
    if not params:
        return [pytest.param(None, id="no-artifacts")]
    return params


Review comment (suggestion):
Not that it makes a difference, could we even do?

```python
return [
    pytest.param(kernel, id=kernel.name) for kernel in select(glob, artifact_dir)
] or [pytest.param(None, id="no-artifacts")]
```


Code after:
    # TODO: remove this once we drop support for MPTable
    supported_kernels.append(r"vmlinux-5.10.\d+-no-acpi")

    return supported_kernels


def kernels(glob, artifact_dir: Path = ARTIFACT_DIR) -> Iterator:
    """Return supported kernels as kernels supported by the current combination of kernel and
    instance type.
    """
    supported_kernels = select_supported_kernels()
    for kernel in sorted(artifact_dir.glob(glob)):
        for kernel_regex in supported_kernels:
            if re.fullmatch(kernel_regex, kernel.name):
                yield kernel
                break


def disks(glob) -> list:
    """Return supported rootfs"""
    return sorted(ARTIFACT_DIR.glob(glob))


def kernel_params(glob="vmlinux-*", select=kernels, artifact_dir=ARTIFACT_DIR) -> list:
    """Return supported kernels or a single None if no kernels are found"""
    return [
        pytest.param(kernel, id=kernel.name) for kernel in select(glob, artifact_dir)
    ] or [pytest.param(None, id="no-kernel-found")]
Repository: firecracker-microvm/firecracker
File: src/vmm/src/utils/mod.rs (Rust)

Code before:
/// Converts MiB to Bytes
pub const fn mib_to_bytes(mib: usize) -> usize {
    mib << MIB_TO_BYTES_SHIFT
}

/// Converts Bytes to MiB, truncating any remainder
pub const fn bytes_to_mib(bytes: usize) -> usize {
    bytes >> MIB_TO_BYTES_SHIFT
}

/// Align address up to the aligment.
pub const fn align_up(addr: u64, align: u64) -> u64 {
    debug_assert!(align != 0);
    (addr + align - 1) & !(align - 1)
}

/// Align address down to the aligment.
pub const fn align_down(addr: u64, align: u64) -> u64 {
    debug_assert!(align != 0);
    addr & !(align - 1)
}

/// Create and open a file for both reading and writing to it with a O_NONBLOCK flag.
/// In case we open a FIFO, we need all READ, WRITE and O_NONBLOCK in order to not block the process
/// if nobody is consuming the message. Otherwise openning the FIFO with only WRITE and O_NONBLOCK
/// will fail if there is no readear already attached to it.
/// NOTE: writing to a pipe will start failing when reaching 64K of unconsumed content.
pub fn open_file_nonblock(path: &Path) -> Result<File, std::io::Error> {
    OpenOptions::new()
        .custom_flags(O_NONBLOCK)
        .create(true)
        .read(true)
        .write(true)
        .open(path)
}


Review comment (bug):
```suggestion
/// if nobody is consuming the message. Otherwise opening the FIFO with only WRITE and O_NONBLOCK
/// will fail with ENXIO if there is no reader already attached to it.
```

Code after:
/// Converts MiB to Bytes
pub const fn mib_to_bytes(mib: usize) -> usize {
    mib << MIB_TO_BYTES_SHIFT
}

/// Converts Bytes to MiB, truncating any remainder
pub const fn bytes_to_mib(bytes: usize) -> usize {
    bytes >> MIB_TO_BYTES_SHIFT
}

/// Align address up to the aligment.
pub const fn align_up(addr: u64, align: u64) -> u64 {
    debug_assert!(align != 0);
    (addr + align - 1) & !(align - 1)
}

/// Align address down to the aligment.
pub const fn align_down(addr: u64, align: u64) -> u64 {
    debug_assert!(align != 0);
    addr & !(align - 1)
}

/// Create and open a file for both reading and writing to it with a O_NONBLOCK flag.
/// In case we open a FIFO, we need all READ, WRITE and O_NONBLOCK in order to not block the process
/// if nobody is consuming the message. Otherwise opening the FIFO with only WRITE and O_NONBLOCK
/// will fail with ENXIO if there is no readier already attached to it.
/// NOTE: writing to a pipe will start failing when reaching 64K of unconsumed content.
pub fn open_file_nonblock(path: &Path) -> Result<File, std::io::Error> {
    OpenOptions::new()
        .custom_flags(O_NONBLOCK)
        .create(true)
        .read(true)
        .write(true)
        .open(path)
}
Repository: firecracker-microvm/firecracker
File: src/vmm/src/utils/mod.rs (Rust)

Code before:
/// Converts MiB to Bytes
pub const fn mib_to_bytes(mib: usize) -> usize {
    mib << MIB_TO_BYTES_SHIFT
}

/// Converts Bytes to MiB, truncating any remainder
pub const fn bytes_to_mib(bytes: usize) -> usize {
    bytes >> MIB_TO_BYTES_SHIFT
}

/// Align address up to the aligment.
pub const fn align_up(addr: u64, align: u64) -> u64 {
    debug_assert!(align != 0);
    (addr + align - 1) & !(align - 1)
}

/// Align address down to the aligment.
pub const fn align_down(addr: u64, align: u64) -> u64 {
    debug_assert!(align != 0);
    addr & !(align - 1)
}

/// Create and open a file for both reading and writing to it with a O_NONBLOCK flag.
/// In case we open a FIFO, we need all READ, WRITE and O_NONBLOCK in order to not block the process
/// if nobody is consuming the message. Otherwise opening the FIFO with only WRITE and O_NONBLOCK
/// will fail with ENXIO if there is no readier already attached to it.
/// NOTE: writing to a pipe will start failing when reaching 64K of unconsumed content.
pub fn open_file_nonblock(path: &Path) -> Result<File, std::io::Error> {
    OpenOptions::new()
        .custom_flags(O_NONBLOCK)
        .create(true)
        .read(true)
        .write(true)
        .open(path)
}


Review comment (bug):
```suggestion
/// will fail with ENXIO if there is no reader already attached to it.
```

Code after:
/// Converts MiB to Bytes
pub const fn mib_to_bytes(mib: usize) -> usize {
    mib << MIB_TO_BYTES_SHIFT
}

/// Converts Bytes to MiB, truncating any remainder
pub const fn bytes_to_mib(bytes: usize) -> usize {
    bytes >> MIB_TO_BYTES_SHIFT
}

/// Align address up to the aligment.
pub const fn align_up(addr: u64, align: u64) -> u64 {
    debug_assert!(align != 0);
    (addr + align - 1) & !(align - 1)
}

/// Align address down to the aligment.
pub const fn align_down(addr: u64, align: u64) -> u64 {
    debug_assert!(align != 0);
    addr & !(align - 1)
}

/// Create and open a file for both reading and writing to it with a O_NONBLOCK flag.
/// In case we open a FIFO, we need all READ, WRITE and O_NONBLOCK in order to not block the process
/// if nobody is consuming the message. Otherwise opening the FIFO with only WRITE and O_NONBLOCK
/// will fail with ENXIO if there is no reader already attached to it.
/// NOTE: writing to a pipe will start failing when reaching 64K of unconsumed content.
pub fn open_file_nonblock(path: &Path) -> Result<File, std::io::Error> {
    OpenOptions::new()
        .custom_flags(O_NONBLOCK)
        .create(true)
        .read(true)
        .write(true)
        .open(path)
}