Исходный код здесь
Я прокомментировал то, что понимаю
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
это вызов?