文章来源:
http:
//gliethttp.cublog.cn
对于order=
0,
索引0-
[
0]
,
索引1-
[
1]
是伙伴
索引2-
[
2]
,
索引3-
[
3]
是伙伴
.
.
.
索引2*
n-
[
2*
n]
,
索引2*
n+
1-
[
2*
n+
1]
是伙伴
对于order=
1,
[
索引0-
页地址0,
索引1-
页地址2]
是伙伴
[
索引2-
页地址4,
索引3-
页地址6]
是伙伴
.
.
.
[
索引n-
页地址2n,
索引n+
1-
页地址2*
(
n+
1)
]
是伙伴
对于order=
2,
[
索引0-
页地址0,
索引1-
页地址4 ]
是伙伴
[
索引2-
页地址8,
索引3-
页地址12]
是伙伴
.
.
.
[
索引n-
页地址4n,
索引n+
1-
页地址4(
n+
1)
]
是伙伴
可以看出,
索引号就是对应的相应order下的位图号,
有这样一个规律:
"对于每一个伙伴都是以偶号n索引[位图号]开始,以下一个奇数号n+1索引[位图号]结束"
.
好了,
知道这样一个规律之后,
我们就可以开始"找朋友"
了,
armlinux中是这样来"找朋友"
的:
1.
mask =
(
~
0UL)
<
<
order;
//mask=页面指数order的掩码
2.
//page_idx=page页在所有页中的页帧号
3.
if
(
page_idx &
~
mask)
BUG(
)
;
//page_idx页帧号必须以1<<order对齐
4.
buddy_page_idx =
page_idx^-
mask;
//通过^运算,一下子就找到朋友buddy_page_idx的页帧号了
我们来看看为什么一个^-
mask操作之后,
就轻松找到了我们需要的伙伴页帧号,
先看一下下面的对照表:
order 0 1 2 3 4 5 6 7 8 9
mask -
1 -
2 -
4 -
8 -
16 -
32 -
64 -
128 -
256 -
512
-
maks 1 2 4 8 16 32 64 128 256 512
~
mask 0 1 3 7 15 31 63 127 255 511
1.
首先对于if(
page_idx &
~
mask)
首先保证在相应order值下,
page_idx页帧号是以1<
<
order为对齐模式的
2.
-
mask为1<
<
order的结果,
刚好是对齐模式的边界值
3.
page_idx^-
mask,
因为page_idx是对齐的,
所以page_idx在边界值(
1<
<
order)
即:
-
maks之下的(
(
1<
<
order)
-
1)
即:
~
mask空间为全0bit
对于异或操作,
比如:
page_idx^0明显等于page_idx,
即保留所有含1的位,
page_idx^0x02只改变0x02中是1的bit1位,
其他位保留,
-
mask中为1的位刚好就是边界位,
即:
(
1<
<
order)
,
所以-
mask仅仅改变边界位所在处的page_idx值,
即仅仅改变page_idx的第order位,
而改变之后的结果无非有二,
不是1就是0,
比如page_idx的第order位为1[
奇数]
,
那么page_idx^-
mask之后,
page_idx的第order位将置0[
-
1偶数-
刚好就是page_idx的朋友]
,
page_idx的其它位保持不变,
比如page_idx的第order位为0[
偶数]
,
那么page_idx^-
mask之后,
page_idx的第order位将置1[
+
1奇数-
刚好就是page_idx的朋友]
,
所有情况就这些,
"找朋友"
就这样轻松的完成了.
[
gliethttp]
我看Buddy(伙伴)算法-到底是怎么计算"伙伴"地址的
最新推荐文章于 2025-05-09 08:36:33 发布