将虚拟地址与紧邻的下一页边界对齐
我遇到了以下算法,它将虚拟地址与紧邻的下一页边界对齐。
VirtualAddr = (VirtualAddr & ~(PageSize-1));
此外,给定一个字节长度将长度(将其舍入)对齐在页面边界上
len = ((PageSize-1)&len) ? ((len+PageSize) & ~(PageSize-1)):len;
我发现很难破译它是如何工作的。 有人可以帮我分解吗?
例如,这些计算假设页面大小是2的幂 (对于我所知道的所有系统都是如此)
PageSize = 4096 = 2^12 = 1000000000000 (binary)
然后(写成二进制数)
PageSize-1 = 00...00111111111111 ~(PageSize-1) = 11...11000000000000
意思就是
(VirtualAddr & ~(PageSize-1))
是VirtualAddr
,低12位设置为零,换句话说, VirtualAddr
向下舍入到下一个2^12 = PageSize
倍数。
现在你可以(希望)看到它
len = ((PageSize-1)&len) ? ((len+PageSize) & ~(PageSize-1)):len;
第一个表达
((PageSize-1)&len)
如果len
是PageSize
的倍数,则为零。 在这种情况下, len
保持不变。 否则(len + PageSize)
向下舍入到PageSize
的下一个倍数。
所以在任何情况下, len
都会向上舍入到PageSize
的下一个倍数。
我想第一个应该是
VirtualAddr = (VirtualAddr & ~(PageSize-1)) + PageSize;
这个单行将执行 – 如果它已经对齐,它将不会跳到下一页边界:
aligned = ((unsigned long) a & (getpagesize()-1)) ? (void *) (((unsigned long) a+getpagesize()) & ~(getpagesize()-1)) : a;
这个单行将执行 – 如果它已经对齐,它将不会跳到下一页边界:
如果你确实想要跳到下一页边界,即使它已经对齐 – 只需这样做:
aligned = (void *) (((unsigned long) a+getpagesize()) & ~(getpagesize()-1))
这应该避免所有编译器警告。
getpagesize()
是一个POSIX的东西。 #include
以避免警告。