- 论坛徽章:
- 13
|
__alloc_pages()用于分配连续的一组页面,会调用到rmqueue()从空闲区找到合适的页面块并摘下,希望分配4个连续页面时,可能area[2]已经空了,就可以从area[3]分配一个8页面块,割切成两份4页面块,一块挂到area[2],一块作为分配到的页面。
每个area为了快速知道哪些区间的页面块是空闲的,都对应一个位图,否则通过遍历area中的链表头确认效率太低了。
问题在于摘下页面块,或者可能进行割切并将小块链入低一级的area时,对相应area的位图操作都是MARK_USED(),按道理应该是“一个MARK_USED(),一个MARK_UNUSED()”呀?
原因是MARK_USED()这个宏函数的名字有点干扰人,至少我自己被干扰到了(为了避免抠字眼造成尴尬,我不敢说很多人了 ),它不是表示“标记为占用”,而是表示“对占用标记位进行操作”,最终调用到的btcl指令是用于反转,而不是单纯的置1或清0 。
- #include <stdio.h>
- static void change_bit(int nr, void *addr)
- {
- __asm__ __volatile__(
- "btcl %1,%0"
- :"=m"(*(volatile long*)addr)
- :"Ir"(nr));
- }
- int main()
- {
- int n = 0;
- change_bit(8, &n); // bit8由0反转为1
- printf("%d\n", n);
- change_bit(8, &n); // bit8由1反转为0
- printf("%d\n", n);
- return 0;
- }
复制代码
从图中的代码可以看出,当分配到需要的页面块后,为什么没有将这组中所有的页面使用计数置1,而只是set_page_count(page, 1),将这组最开始的页面置1?
|
|