syscall.Mmap在golang上的实现

问题描述 投票:1回答:1

源代码为here

我对自己的理解发表了评论

type mmapper struct {
    sync.Mutex
    active map[*byte][]byte // active mappings; key is last byte in mapping
    mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
    munmap func(addr uintptr, length uintptr) error
}

func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
    if length <= 0 {
        return nil, EINVAL
    }

    // Map the requested memory using a operating-system dependent function
    addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
    if errno != nil {
        return nil, errno
    }

    // Create slice memory layout
    var sl = struct {
        addr uintptr
        len  int
        cap  int
    }{addr, length, length}

    // Cast it to byte slice
    b := *(*[]byte)(unsafe.Pointer(&sl))

    // ??
    p := &b[cap(b)-1]
    m.Lock()
    defer m.Unlock()
    m.active[p] = b
    return b, nil
}

func (m *mmapper) Munmap(data []byte) (err error) {
    if len(data) == 0 || len(data) != cap(data) {
        return EINVAL
    }

    // Check if the slice is valid ?
    p := &data[cap(data)-1]
    m.Lock()
    defer m.Unlock()
    b := m.active[p]
    if b == nil || &b[0] != &data[0] {
        return EINVAL
    }

    // Unmap the memory and update m.
    if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
        return errno
    }
    delete(m.active, p)
    return nil
}

所以我的问题只是关于字段mmapper.active,我不明白它的用途。

我已经阅读过有关uintptr和垃圾收集器的问题,也许是为了避免它们?还是只是为了在调用Munmap时验证切片?

go mmap
1个回答
0
投票
b := []byte{1,2,3,4} fmt.Println(&b[0]) // 0x40e020 b = b[1:] fmt.Println(&b[0]) // 0x40e021

https://play.golang.org/p/WJogLiMOfj7

© www.soinside.com 2019 - 2024. All rights reserved.