1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/* Copyright (c) Fortanix, Inc.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/// Given a size in bytes, return the size in bytes of the total full pages
/// required to cover the size.
pub fn size_fit_page(size: u64) -> u64 {
    match size & 0xfff {
        0 => size,
        remainder => size + (0x1000 - remainder),
    }
}

/// Given a size in bytes, return the size in bytes of the naturally-aligned
/// structure required to cover the size.
///
/// This is the smallest power of two that is equal to or higher than the input
/// size.
pub fn size_fit_natural(size: u64) -> u64 {
    use std::num::Wrapping;
    let mut v = Wrapping(size);
    v -= Wrapping(1);
    v |= v >> 1;
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;
    v |= v >> 32;
    v += Wrapping(1);
    v.0
}

#[test]
fn test_size_fit_natural() {
    let mut i = 0x1000;
    loop {
        assert_eq!(size_fit_natural(i - 1), i);
        assert_eq!(size_fit_natural(i), i);
        assert_eq!(size_fit_natural(i + 1), i << 1);
        if i > 0x8000_0000_0000_0000 {
            i <<= 1;
        } else {
            break;
        }
    }
}