linux/mm/memory.c/int share_page(unsigned long address)

/*
 * share_page() tries to find a process that could share a page with
 * the current one. Address is the address of the wanted page relative
 * to the current data space.
 *
 * We first check if it is at all feasible by checking executable->i_count.
 * It should be >1 if there are other tasks sharing this inode.
 */
// 首先,address为逻辑地址。
// share_page用来确定当前进程address地址处的页面是否有可能与某个其他进程的一个
// 页面共享。所谓共享,即让当前进程在寻址address页面时直接寻址到那个共享页面上
// 这种效果是通过修改当前进程页表中address地址处的页表项内容(这个内容就是address
// 地址对应的物理页面地址)为目标共享页面的物理地址来实现的。
static int share_page(unsigned long address)
{
struct task_struct ** p;


// 若当前进程没有可执行文件部分,直接退出。
if (!current->executable)
return 0;
// 若当前进程可执行部分存在,但是其inode引用次数小于2则退出。
// executable->i_count记录当前的进程可执行文件的inode被引用的次数,这个次数为1
// 说明这个可执行文件只被当前进程引用,这样根本就不用查找别的进程就可以知道
// 不可能找到别的进程页面可以用来共享的,所以直接返回。若这个引用计数为2,就说明
// 除当前进程外还有一个进程在引用这个executable文件,这样就共享的前提了。
if (current->executable->i_count < 2)
return 0;
// 执行到这里,说明除当前进程外还有别的进程引用了这个executable,于是遍历task[64]
// 来检测所有进程,来找到这些也引用了executable文件的进程然后try_to_share他们
for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
// 若为空项,即task[64]中这个进程槽并未注册进程,直接进行下一个for项目。
if (!*p)
continue;
// 跳过当前进程,因为你总不能和自己try_to_share吧
if (current == *p)
continue;
// 跳过那些executable和当前进程不同的进程。
if ((*p)->executable != current->executable)
continue;
// 最后剩下的就是那些引用了当前进程executable文件的进程了,调用try_to_share
// 来试图和它共享页面。此处注意返回值。若share成功则返回1,若失败则返回0.
if (try_to_share(address,*p))
return 1;
}
// linux0.11的编程风格中有一个明显的特色,那就是return的使用。
// 首先,返回值反映了函数执行成功与否的信息。譬如本函数,成功则返回1,失败便返回0.
// 其次,函数运行逻辑中极少使用if + else来分化逻辑,而是采用if + return来分化:即
// 首先用if把那些不要的情况return掉,最后剩下的即是想要的逻辑分支了。
// 这种构架写起来和读起来都更加清晰,并且有利于函数的模块化封装,值得学习。
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

朱有鹏老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值