mmap_unix.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright 2011 Evan Shaw. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE-MMAP-GO file.
  4. //go:build unix
  5. // Modifications (c) 2017 The Memory Authors.
  6. package memory // import "modernc.org/memory"
  7. import (
  8. "golang.org/x/sys/unix"
  9. "os"
  10. "unsafe"
  11. )
  12. const pageSizeLog = 16
  13. var (
  14. osPageMask = osPageSize - 1
  15. osPageSize = os.Getpagesize()
  16. )
  17. func unmap(addr uintptr, size int) error {
  18. return unix.MunmapPtr(unsafe.Pointer(addr), uintptr(size))
  19. }
  20. // pageSize aligned.
  21. func mmap(size int) (uintptr, int, error) {
  22. size = roundup(size, osPageSize)
  23. // Ask for more so we can align the result at a pageSize boundary
  24. n := size + pageSize
  25. up, err := unix.MmapPtr(-1, 0, nil, uintptr(n), unix.PROT_READ|unix.PROT_WRITE, unix.MAP_PRIVATE|unix.MAP_ANON)
  26. if err != nil {
  27. return 0, 0, err
  28. }
  29. p := uintptr(up)
  30. if p&uintptr(osPageMask) != 0 {
  31. panic("internal error")
  32. }
  33. mod := int(p) & pageMask
  34. if mod != 0 { // Return the extra part before pageSize aligned block
  35. m := pageSize - mod
  36. if err := unmap(p, m); err != nil {
  37. unmap(p, n) // Do not leak the first mmap
  38. return 0, 0, err
  39. }
  40. n -= m
  41. p += uintptr(m)
  42. }
  43. if p&uintptr(pageMask) != 0 {
  44. panic("internal error")
  45. }
  46. if n > size { // Return the extra part after pageSize aligned block
  47. if err := unmap(p+uintptr(size), n-size); err != nil {
  48. // Do not error when the kernel rejects the extra part after, just return the
  49. // unexpectedly enlarged size.
  50. //
  51. // Fixes the bigsort.test failures on linux/s390x, see: https://gitlab.com/cznic/sqlite/-/issues/207
  52. size = n
  53. }
  54. }
  55. return p, size, nil
  56. }