Goog下午,我最近下载了www.kernel.org主线2.6.39 Linux内核源代码发行版。我们正在寻找voidmmap的Linux源代码(voidstart,size_t length,int prot,int flags,int fd,off_t offset)。在解压缩tar.bz2发行版之后,我们发现了一个包含内存映射源代码的文件mmap.c。然而,我们无法在mmap.c中获得voidmmap(voidstart,size_t length,int prot,int flags,int fd,off_t offset)的Linux源代码。有没有Linux工程师或管理员知道我们在哪里获得voidmmap的Linux源代码(voidstart,size_t length,int prot,int flags,int fd,off_t offset)?此外,我们对MapViewOfFile的Windows源代码感兴趣。我知道这是一个延伸,因为微软操作系统的源代码不在开源领域。如果有人想知道我们为什么需要这个源代码,我们将尝试在32位体系结构上使用缓存内存映射文件实现来优化C++重复数据消除程序原型的运行时性能。我们想了解如何使用mmap和MapViewOfFile来优化原型的运行时性能?非常感谢。
从android源代码中提取;
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
extern void* __mmap2(void*, size_t, int, int, int, size_t);
#define MMAP2_SHIFT 12
void* mmap( void* addr, size_t size, int prot, int flags, int fd, long offset )
{
if ( offset & ((1UL << MMAP2_SHIFT)-1) ) {
errno = EINVAL;
return MAP_FAILED;
}
return __mmap2(addr, size, prot, flags, fd, (size_t)offset >> MMAP2_SHIFT);
}
来源:mmap.c
现在,实际的__mmap2
调用具有assembly,所以它将取决于您的arch。这是一个x86版本:
/* autogenerated by gensyscalls.py */
#include <sys/linux-syscalls.h>
.text
.type __mmap2, @function
.globl __mmap2
.align 4
__mmap2:
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
pushl %ebp
mov 28(%esp), %ebx
mov 32(%esp), %ecx
mov 36(%esp), %edx
mov 40(%esp), %esi
mov 44(%esp), %edi
mov 48(%esp), %ebp
movl $__NR_mmap2, %eax
int $0x80
cmpl $-129, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno
addl $4, %esp
orl $-1, %eax
1:
popl %ebp
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
ret
来源:__mmap2.S
要获得Win32 MapViewOfFile
实现,您必须支付昂贵的订阅费、签署法律保密协议等。
linux mmap
是公开可读的。但是,您应该知道有两个部分:glibc中的mmap
函数和内核中的匹配系统调用,所有感兴趣的部分都在其中。您显示的签名是针对glibc函数的,不要期望系统调用具有完全相同的参数。
但是您可以在不阅读实现的情况下"理解如何使用mmap
和MapViewOfFile
"。
对于MapViewOfFile
,我会检查Winbase.h,但可能只是声明,否则你必须转向逆向工程,这在大多数国家被认为是非法的。
我在这里找到了一篇关于MMAP及其工作原理的文章。也许这会有所帮助。
我的直接猜测是,试图弄清楚如何从源代码到函数更好地使用这些功能(充其量)可能是一种非常迂回的方法。特别是,您可能需要查看更多/其他代码才能获得大部分内容。当你深入研究时,mmap/MapViewOfFile中的代码本身可能(充其量)帮助很小,而其他代码(如文件系统驱动程序和文件缓存中的)可能更有意义。
归根结底,mmap和MapViewOfFile有相对简单的工作:设置页面描述符,将一系列虚拟地址映射到某个文件的某个部分。
在您尝试访问其中一个页面之前,不会发生太多其他/更多的事情。这将触发"不存在"故障。故障处理程序将使用I/O子系统从磁盘读取相应的数据,并返回让原始指令执行。还是不太有趣。
至少从优化的角度来看,事情变得有趣的地方在于I/O子系统内部。这可以(例如)跟踪页面故障的历史记录,并使用它来预测可能很快需要哪些页面(如果需要,则在故障发生之前读取预测页面的问题)。
然而,充其量,mmap/MapViewOfFile的源代码根本不会直接指向您可能关心的I/O子系统的部分(事实上,它们在这方面可能几乎完全无用)。
很有趣,但我也需要mmap源…:)
到目前为止,我只能在NetBSD上找到答案。基于此评论:
- libc函数位于src/libc/sys/mmap.c中
-
相应的内核函数位于src/sys/uvm/uvm_map.c:中
int uvm_map(struct vm_map*map,vaddr_tstartp/IN/OUT*/,vsize_t size,structuvm_object*uobj,voff_t uoffset,vsize_t-align,uvm_flag_t flags)
实际的链接对应于NetBSD版本8,但您可以用任何其他版本替换它。
谨致问候。