Source file src/cmd/vendor/golang.org/x/sys/unix/readv_unix.go

     1  // Copyright 2026 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  //go:build darwin || linux || openbsd
     6  
     7  package unix
     8  
     9  import "unsafe"
    10  
    11  // minIovec is the size of the small initial allocation used by
    12  // Readv, Writev, etc.
    13  //
    14  // This small allocation gets stack allocated, which lets the
    15  // common use case of len(iovs) <= minIovec avoid more expensive
    16  // heap allocations.
    17  const minIovec = 8
    18  
    19  // appendBytes converts bs to Iovecs and appends them to vecs.
    20  func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
    21  	for _, b := range bs {
    22  		var v Iovec
    23  		v.SetLen(len(b))
    24  		if len(b) > 0 {
    25  			v.Base = &b[0]
    26  		} else {
    27  			v.Base = (*byte)(unsafe.Pointer(&_zero))
    28  		}
    29  		vecs = append(vecs, v)
    30  	}
    31  	return vecs
    32  }
    33  
    34  // writevRaceDetect tells the race detector that the program
    35  // has read the first n bytes stored in iovecs.
    36  func writevRaceDetect(iovecs []Iovec, n int) {
    37  	if !raceenabled {
    38  		return
    39  	}
    40  	for i := 0; n > 0 && i < len(iovecs); i++ {
    41  		m := min(int(iovecs[i].Len), n)
    42  		n -= m
    43  		if m > 0 {
    44  			raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
    45  		}
    46  	}
    47  }
    48  
    49  // readvRaceDetect tells the race detector that the program
    50  // has written to the first n bytes stored in iovecs.
    51  func readvRaceDetect(iovecs []Iovec, n int, err error) {
    52  	if !raceenabled {
    53  		return
    54  	}
    55  	for i := 0; n > 0 && i < len(iovecs); i++ {
    56  		m := min(int(iovecs[i].Len), n)
    57  		n -= m
    58  		if m > 0 {
    59  			raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
    60  		}
    61  	}
    62  	if err == nil {
    63  		raceAcquire(unsafe.Pointer(&ioSync))
    64  	}
    65  }
    66  
    67  func Readv(fd int, iovs [][]byte) (n int, err error) {
    68  	iovecs := make([]Iovec, 0, minIovec)
    69  	iovecs = appendBytes(iovecs, iovs)
    70  	n, err = readv(fd, iovecs)
    71  	readvRaceDetect(iovecs, n, err)
    72  	return n, err
    73  }
    74  
    75  func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
    76  	iovecs := make([]Iovec, 0, minIovec)
    77  	iovecs = appendBytes(iovecs, iovs)
    78  	n, err = preadv(fd, iovecs, offset)
    79  	readvRaceDetect(iovecs, n, err)
    80  	return n, err
    81  }
    82  
    83  func Writev(fd int, iovs [][]byte) (n int, err error) {
    84  	iovecs := make([]Iovec, 0, minIovec)
    85  	iovecs = appendBytes(iovecs, iovs)
    86  	if raceenabled {
    87  		raceReleaseMerge(unsafe.Pointer(&ioSync))
    88  	}
    89  	n, err = writev(fd, iovecs)
    90  	writevRaceDetect(iovecs, n)
    91  	return n, err
    92  }
    93  
    94  func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
    95  	iovecs := make([]Iovec, 0, minIovec)
    96  	iovecs = appendBytes(iovecs, iovs)
    97  	if raceenabled {
    98  		raceReleaseMerge(unsafe.Pointer(&ioSync))
    99  	}
   100  	n, err = pwritev(fd, iovecs, offset)
   101  	writevRaceDetect(iovecs, n)
   102  	return n, err
   103  }
   104  

View as plain text