diff options
author | 2024-12-12 19:44:53 +0000 | |
---|---|---|
committer | 2024-12-12 19:44:53 +0000 | |
commit | fb12bbb10b228fddf40ebd0e463d5afcd9299ebb (patch) | |
tree | c9239fe362ea38e71ab4363649ceff605cb4ab89 /vendor/github.com/ncruces/go-sqlite3/internal/util/mmap_unix.go | |
parent | Bump nanoid from 3.3.7 to 5.0.9 in /web/source (#3615) (diff) | |
download | gotosocial-fb12bbb10b228fddf40ebd0e463d5afcd9299ebb.tar.xz |
bump ncruces/go-sqlite3 to v0.21.0 (#3621)
Diffstat (limited to 'vendor/github.com/ncruces/go-sqlite3/internal/util/mmap_unix.go')
-rw-r--r-- | vendor/github.com/ncruces/go-sqlite3/internal/util/mmap_unix.go | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/vendor/github.com/ncruces/go-sqlite3/internal/util/mmap_unix.go b/vendor/github.com/ncruces/go-sqlite3/internal/util/mmap_unix.go new file mode 100644 index 000000000..5d5ca3823 --- /dev/null +++ b/vendor/github.com/ncruces/go-sqlite3/internal/util/mmap_unix.go @@ -0,0 +1,87 @@ +//go:build unix + +package util + +import ( + "context" + "os" + "unsafe" + + "github.com/tetratelabs/wazero/api" + "golang.org/x/sys/unix" +) + +type mmapState struct { + regions []*MappedRegion +} + +func (s *mmapState) new(ctx context.Context, mod api.Module, size int32) *MappedRegion { + // Find unused region. + for _, r := range s.regions { + if !r.used && r.size == size { + return r + } + } + + // Allocate page aligned memmory. + alloc := mod.ExportedFunction("aligned_alloc") + stack := [...]uint64{ + uint64(unix.Getpagesize()), + uint64(size), + } + if err := alloc.CallWithStack(ctx, stack[:]); err != nil { + panic(err) + } + if stack[0] == 0 { + panic(OOMErr) + } + + // Save the newly allocated region. + ptr := uint32(stack[0]) + buf := View(mod, ptr, uint64(size)) + addr := unsafe.Pointer(&buf[0]) + s.regions = append(s.regions, &MappedRegion{ + Ptr: ptr, + addr: addr, + size: size, + }) + return s.regions[len(s.regions)-1] +} + +type MappedRegion struct { + addr unsafe.Pointer + Ptr uint32 + size int32 + used bool +} + +func MapRegion(ctx context.Context, mod api.Module, f *os.File, offset int64, size int32, readOnly bool) (*MappedRegion, error) { + s := ctx.Value(moduleKey{}).(*moduleState) + r := s.new(ctx, mod, size) + err := r.mmap(f, offset, readOnly) + if err != nil { + return nil, err + } + return r, nil +} + +func (r *MappedRegion) Unmap() error { + // We can't munmap the region, otherwise it could be remaped. + // Instead, convert it to a protected, private, anonymous mapping. + // If successful, it can be reused for a subsequent mmap. + _, err := unix.MmapPtr(-1, 0, r.addr, uintptr(r.size), + unix.PROT_NONE, unix.MAP_PRIVATE|unix.MAP_FIXED|unix.MAP_ANON) + r.used = err != nil + return err +} + +func (r *MappedRegion) mmap(f *os.File, offset int64, readOnly bool) error { + prot := unix.PROT_READ + if !readOnly { + prot |= unix.PROT_WRITE + } + _, err := unix.MmapPtr(int(f.Fd()), offset, r.addr, uintptr(r.size), + prot, unix.MAP_SHARED|unix.MAP_FIXED) + r.used = err == nil + return err +} |