Skip to content

Latest commit

 

History

History
122 lines (67 loc) · 7.66 KB

cgo_mmap.go.md

File metadata and controls

122 lines (67 loc) · 7.66 KB

File: cgo_mmap.go

cgo_mmap.go这个文件的作用是实现Go语言中的cgo mmap函数,它负责将堆空间中的虚拟内存映射到物理内存地址上,从而实现内存的动态分配和管理。

具体来说,cgo_mmap.go中的函数实现了以下几个功能:

  1. mmap函数:该函数映射一段指定大小的内存空间到指定地址上。

  2. munmap函数:该函数释放指定地址映射的内存空间。

  3. mprotect函数:该函数修改指定地址映射的内存访问权限。

  4. madvise函数:该函数预处理指定地址映射的内存空间,以便对其进行更高效的操作。

通过实现这些函数,cgo_mmap.go为Go语言提供了强大的底层内存管理能力,使得Go语言能够更好地调用C语言库和操作系统底层接口,并实现高效的内存分配和管理。

Functions:

mmap

在go/src/runtime/cgo_mmap.go文件中的mmap函数是用于分配内存的函数。具体来说,它使用操作系统提供的mmap系统调用来在进程的虚拟地址空间中分配一段指定大小的内存区域。

在Go语言中,CGO用于让Go程序调用C/C++的函数。CGO使用mmap函数来为C/C++代码分配内存,通常用于分配动态内存。例如,当C/C++程序需要分配大量内存,或需要动态修改分配的内存时,就可以使用mmap函数进行内存分配和释放。

mmap函数的具体作用是:将某段物理地址映射到进程的虚拟地址空间中,使得进程可以直接访问该物理地址。mmap函数可以用于创建新的内存映射区域,也可以用于调整已有内存映射区域的大小或属性。

在cgo_mmap.go文件中,mmap函数被用于分配和回收内存,并且根据不同的平台,采用了不同的实现方式。具体来说,在Linux平台上,mmap函数是通过调用系统调用来实现的,而在Windows平台上,它则使用了WinAPI提供的VirtualAlloc和VirtualFree函数来实现。

munmap

cgo_mmap.go文件中的munmap函数的作用是用于释放一个由mmap函数分配的内存映射区域。

具体来说,调用munmap函数可以将一个进程中先前通过调用mmap函数创建的内存映射区域从进程的地址空间中解除映射,从而释放该内存。

munmap函数接受两个参数,第一个是指向映射区域起始地址的指针,第二个是指定映射区域长度的整数参数。调用munmap函数后,操作系统会将该内存解除映射,并将其返回给系统内部的内存池。这样可以避免内存泄漏,同时还可以为其他进程或应用程序提供更多的内存空间。

需要注意的是,在调用munmap函数之前,必须保证对映射区域的所有访问均已结束,否则可能会导致程序崩溃或其他异常情况。如果有必要,可以使用msync函数将内存中的数据写回磁盘,以确保数据的完整性。

总之,munmap函数是一个用于释放内存映射区域的重要函数,对于管理内存的应用程序和操作系统来说都非常重要。

sysMmap

sysMmap是一个系统调用函数,在cgo_mmap.go文件中被用来在指定地址范围内映射一个文件或匿名存储区域。

具体来说,sysMmap函数是通过调用内核的mmap系统调用来实现内存映射的。mmap系统调用用于将一段物理内存区域映射到进程的地址空间。它通过将一个文件或者设备映射到进程的地址空间,使得进程可以像访问内存一样访问文件或设备。

在cgo_mmap.go文件中,sysMmap函数被用来映射一段指定长度的空闲虚拟地址空间,并将这段空间映射到指定的文件描述符或者直接映射到匿名存储区域。这个函数的具体实现涉及到了底层的内存映射机制,因此在使用时需要非常谨慎,并了解相关的原理和机制。

callCgoMmap

callCgoMmap是一个用于调用Cgo mmap函数的Go函数。它的作用是在Go程序中使用Cgo调用mmap系统调用,用于在进程的虚拟地址空间中分配一段内存区域。

在callCgoMmap函数中,首先会通过CGO的调用机制将Go程序的运行时堆栈信息传递给Cgo调用,然后使用Cgo调用mmap函数分配一段内存空间,并返回该内存区域的起始地址。在返回地址之前,callCgoMmap会将内存区域的访问权限设置为可读可写,并将内存区域的起始地址和大小保存在一个特殊的Cgo数据结构中,以便之后的使用。

callCgoMmap和其他Cgo函数一样,需要在Go程序中按照CGO的规范进行声明和调用,并且需要在运行时加载CGO库。因此,使用callCgoMmap需要了解CGO机制和Cgo mmap函数的使用方法。使用callCgoMmap可以方便地在Go程序中完成内存分配等底层操作。

sysMunmap

在Go语言中,CGO是一个用来连接Go和C语言代码的工具。cgo_mmap文件是用于CGO的文件之一,其中sysMunmap是一个函数,作用是释放一个映射的内存区域。

当你在使用CGO从Go代码中调用C函数时,有时候会发生内存分配的情况。在这种情况下,可能需要使用CGO提供的内存管理函数来对内存进行释放。其中,sysMunmap函数就是用来释放一块被mmap函数映射的内存区域。当内存不再需要使用时,可以使用sysMunmap函数将这块内存区域释放掉。

具体来讲,sysMunmap函数会接收两个参数。第一个参数是一个指向映射到内存区域的指针,第二个参数是这个映射的大小。当函数被调用时,它会将这块内存区域从进程的地址空间中解除映射,并释放掉这块内存区域所占用的物理内存。

总之,sysMunmap函数是CGO中的一个内存管理函数,用于释放被映射到内存区域的内存。

callCgoMunmap

callCgoMunmap是一个从Go调用C函数的接口,它的作用是使用C语言的munmap系统调用释放操作系统分配的内存。在调用callCgoMunmap时,它会先调用goMunmap函数获取待释放内存的起始地址和长度,然后再调用cgoMunmap函数实际执行释放操作。

具体来说,callCgoMunmap的实现如下:

func callCgoMunmap(addr unsafe.Pointer, n uintptr) {
    mp := acquirem()
    release := true
    defer func() {
        if release {
            releasem(mp)
        }
    }()
    argp, _ := cgocall_errno(unsafe.Pointer(_cgo_munmap), uintptr(addr), n)
    if errno(argp) != 0 {
        throw("munmap")
    }
    mp.acount++
    release = false
}

其中,acquirem和releasem函数用于获取和释放当前Go线程的M(Machine)抽象。这里使用M是为了支持协程调度等操作。cgocall_errno则是一个用于从Go调用C函数的工具函数,它会将C函数的返回值作为结果返回,并检查操作系统的errno是否出现错误。

_cgo_munmap是一个由cgo工具生成的桥接函数,它的实现如下:

//go:cgo_import_static _cgo_munmap
//go:linkname __cgocall _cgo_munmap
//go:linkname _cgo_munmap _cgo_munmap
var _cgo_munmap byte

//go:nosplit
func cgoMunmap(addr unsafe.Pointer, n uintptr) int32 {
    return int32(munmap(addr, n))
}

其中,cgoMunmap函数是callCgoMunmap内部调用的函数,它的作用是将unsafe.Pointer类型的地址和uintptr类型的长度作为参数调用系统的munmap函数,并将返回值转换成int32类型返回。在_cgo_munmap变量定义中,go:cgo_import_static声明了_cgo_munmap变量引用了C语言中的符号_cgo_munmap,然后通过go:linkname将C语言符号和Go语言函数名建立联系,从而完成C和Go语言的桥接。最终,cgoMunmap会通过调用munmap实际执行内存释放操作。

总之,callCgoMunmap的作用是执行内存释放操作,并且它的实现依赖了M抽象和cgo工具生成的桥接函数。