/// Align downwards. Returns the greatest x with alignment `align`
/// so that x <= addr. The alignment must be a power of 2.
pub fn align_down(addr: usize, align: usize) -> usize {
if align.is_power_of_two() {
addr & !(align - 1)
} else if align == 0 {
addr
} else {
panic!("`align` must be a power of 2");
}
}
/// Align upwards. Returns the smallest x with alignment `align`
/// so that x >= addr. The alignment must be a power of 2.
pub fn align_up(addr: usize, align: usize) -> usize {
align_down(addr + align - 1, align)
}
align的值是内存对齐的参数,是2的倍数{1, 2, 4, 8, 16, ...}
使用二进制表示align,{1, 10, 100, 1000, 10000, ...}
align-1
得到{0, 01, 011, 0111, 01111, ...}
!(align-1)
得到{...11111, ...11110, ...11100, ...11000, ...10000, ...}
addr & !(align-1)
会将addr的高位(左边视为地位,右边视为高位)关闭(0视作关闭,1视作打开)
align_up的处理逻辑如下面两张图,为了在已经对齐的情况下节省内存节省内存做了减1操作