将虚拟地址与紧邻的下一页边界对齐

我遇到了以下算法,它将虚拟地址与紧邻的下一页边界对齐。

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) 

如果lenPageSize的倍数,则为零。 在这种情况下, 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 以避免警告。