...
  
  
     1  
     2  
     3  
     4  
     5  
     6  
     7  package bio
     8  
     9  import (
    10  	"runtime"
    11  	"sync/atomic"
    12  	"syscall"
    13  )
    14  
    15  
    16  
    17  
    18  
    19  
    20  
    21  
    22  
    23  
    24  
    25  
    26  var mmapLimit int32 = 1<<31 - 1
    27  
    28  func init() {
    29  	
    30  	if runtime.GOOS == "linux" {
    31  		mmapLimit = 30000
    32  	}
    33  }
    34  
    35  func (r *Reader) sliceOS(length uint64) ([]byte, bool) {
    36  	
    37  	
    38  	const threshold = 16 << 10
    39  	if length < threshold {
    40  		return nil, false
    41  	}
    42  
    43  	
    44  	if atomic.AddInt32(&mmapLimit, -1) < 0 {
    45  		atomic.AddInt32(&mmapLimit, 1)
    46  		return nil, false
    47  	}
    48  
    49  	
    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