buf_mmap.go raw

   1  // Copyright 2019 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  // +build darwin dragonfly freebsd linux netbsd openbsd
   6  
   7  package bio
   8  
   9  import (
  10  	"runtime"
  11  	"sync/atomic"
  12  	"syscall"
  13  )
  14  
  15  // mmapLimit is the maximum number of mmaped regions to create before
  16  // falling back to reading into a heap-allocated slice. This exists
  17  // because some operating systems place a limit on the number of
  18  // distinct mapped regions per process. As of this writing:
  19  //
  20  //  Darwin    unlimited
  21  //  DragonFly   1000000 (vm.max_proc_mmap)
  22  //  FreeBSD   unlimited
  23  //  Linux         65530 (vm.max_map_count) // TODO: query /proc/sys/vm/max_map_count?
  24  //  NetBSD    unlimited
  25  //  OpenBSD   unlimited
  26  var mmapLimit int32 = 1<<31 - 1
  27  
  28  func init() {
  29  	// Linux is the only practically concerning OS.
  30  	if runtime.GOOS == "linux" {
  31  		mmapLimit = 30000
  32  	}
  33  }
  34  
  35  func (r *Reader) sliceOS(length uint64) ([]byte, bool) {
  36  	// For small slices, don't bother with the overhead of a
  37  	// mapping, especially since we have no way to unmap it.
  38  	const threshold = 16 << 10
  39  	if length < threshold {
  40  		return nil, false
  41  	}
  42  
  43  	// Have we reached the mmap limit?
  44  	if atomic.AddInt32(&mmapLimit, -1) < 0 {
  45  		atomic.AddInt32(&mmapLimit, 1)
  46  		return nil, false
  47  	}
  48  
  49  	// Page-align the offset.
  50  	off := r.Offset()
  51  	align := syscall.Getpagesize()
  52  	aoff := off &^ int64(align-1)
  53  
  54  	data, err := syscall.Mmap(int(r.f.Fd()), aoff, int(length+uint64(off-aoff)), syscall.PROT_READ, syscall.MAP_SHARED|syscall.MAP_FILE)
  55  	if err != nil {
  56  		return nil, false
  57  	}
  58  
  59  	data = data[off-aoff:]
  60  	r.MustSeek(int64(length), 1)
  61  	return data, true
  62  }
  63