...

Source file src/cmd/internal/bio/buf_mmap.go

     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	

View as plain text