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

2023-05-16

/*
 * 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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux/mm/memory.c/int share_page(unsigned long address) 的相关文章

  • std::deque 的内存开销到底是怎么回事?

    我正在研究一种使用外部排序算法std queue并且必须仔细限制其内存使用 我注意到在合并阶段 使用了几个std queues 固定长度 我的内存使用量增加到我预期的大约 2 5 倍 自从std queue默认情况下使用std deque作
  • /sys/device/ 和 dmidecode 报告的不同 CPU 缓存大小

    我正在尝试获取系统中不同缓存级别的大小 我尝试了两种技术 a 使用 sys device 中的信息 这是输出 cat sys devices system cpu cpu0 cache index1 size 32K cat sys dev
  • 寻找嵌套列表中的最低值?

    我正在尝试编写一个函数 它接受一个列表并可以打印该列表中的最小整数 现在我试图弄清楚在嵌套列表中该怎么做 如果最低数字位于这些嵌套列表之一中 那么总的来说它将打印该数字 我的代码在这里 def listMin list2 3 4 2 99
  • Linux无法删除文件

    当我找到文件时 我在删除它们时遇到问题 任务 必须找到带有空格的文件并将其删除 我的尝试 rm find L root grep i 但我有错误 rm cannot remove root test No such file or dire
  • 调整巨大数组的大小

    我正在我的应用程序中处理巨大的数组 需要调整它们的大小 假设您有一个 2Gb 的阵列 并且想要将其大小调整为 3Gb 有没有办法在暂时不需要 5Gb 的情况下调整它的大小 例如 给定一个 1Gb 堆 使用 Xmx1G flag public
  • 在 docker 中重定向命令输出

    我想为我的服务器做一些简单的日志记录 它是一个在 Docker 容器中运行的小型 Flask 应用程序 这是 Dockerfile Dockerfile FROM dreen flask MAINTAINER dreen WORKDIR s
  • 为什么 Go 中只有 int 而没有 float?

    在 Go 中 有这样的类型int这可能相当于int32 or int64取决于系统架构 我可以声明一个整数变量而不用担心它的大小 var x int 为什么没有这个类型float 这相当于float32 or float64取决于我的系统架
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu
  • C# 将 IntPtr 转换为 int

    我正在动态调用 Windows API 我在网上找到了一些可以做到这一点的代码 并且我对它非常感兴趣 至少可以说 这个想法本身就很出色 但是 我似乎无法让它适用于我的代码 动态调用的参数是类型string string int 我想使用 A
  • Mysql 将 int 转换为 MAC

    我有一些数据可以转换 其中有 2 列 其中一列有 IP 它包含整数值 我在 mysql 查询中使用了以下函数 是否有一个函数可以用来转换我的 mac 列 其中包含整数和数据类型是bigint to MAC地址 SELECT INET NTO
  • linux下无法创建僵尸进程

    嗯 我有一个奇怪的问题 我无法在我的项目中创建僵尸进程 但我可以在其他文件中创建僵尸进程 有简单的说明 int main if fork 0 printf Some instructions n else sleep 10 wait 0 r
  • 确定 C 字符串是否是 C 中的有效 int

    我需要检查 C 字符串是否是有效整数 我都尝试过 int num atoi str and int res sscanf str d num 但发送字符串 8 9 10 这两行都仅返回 8 而没有指示该字符串的无效性 谁能提出替代方案 看看
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 在 Linux 上以编程方式设置 DNS 名称服务器

    我希望能够通过我的 C C 程序为 Linux 上的 DNS 名称服务器添加 IP 地址 我在一个带有只读 etc resolv conf 的嵌入式平台上 这意味着我不能简单地将 nameserver xxx xxx xxx xxx 行添加
  • linux-x64 二进制文件无法在 linuxmusl-x64 平台上使用错误

    我正在安装Sharp用于使用 package json 的 Nodejs 项目的 docker 映像上的映像压缩包 当我创建容器时 我收到有关 Sharp 包的以下错误 app node modules sharp lib libvips
  • 如何在linux中以编程方式获取dir的大小?

    我想通过 C 程序获取 linux 中特定目录的确切大小 我尝试使用 statfs path struct statfs 但它没有给出确切的大小 我也尝试过 stat 但它返回任何目录的大小为 4096 请建议我如何获取 dir 的确切大小
  • GMail 421 4.7.0 稍后重试,关闭连接

    我试图找出为什么它无法使用 GMail 从我的服务器发送邮件 为此 我使用 SwiftMailer 但我可以将问题包含在以下独立代码中
  • 使用非规范地址检索内存数据会导致 SIGSEGV 而不是 SIGBUS

    我无法使用以下汇编代码产生 总线错误 这里我使用的内存地址不是合法的 规范地址 那么 我怎样才能触发该错误呢 我在带有 NASM 2 14 02 的 Ubuntu 20 04 LTS 下运行这段代码 但它会导致负载出现 SIGSEGV 分段
  • Valgrind 输出中的错误摘要?

    我看过一些关于 valgrind 的帖子 但没有一篇帖子帮助我理解 valgrind 输出的解释 我用 valgrind 运行了两个程序 都有内存泄漏 测试 1 的示例输出 20422 LEAK SUMMARY 20422 definite

随机推荐