mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-01 06:46:44 -04:00
unix: merge Linux readv/writev implementation with Darwin/OpenBSD
This reduces some code duplication. Change-Id: Ib648f90a26960d0bc25d2fe27e9b3fb1419ac02d Reviewed-on: https://go-review.googlesource.com/c/sys/+/777161 Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Auto-Submit: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
committed by
Gopher Robot
parent
e4444cbaaa
commit
99666ae32e
+15
-7
@@ -2,17 +2,21 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build darwin || openbsd
|
//go:build darwin || linux || openbsd
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
|
// minIovec is the size of the small initial allocation used by
|
||||||
|
// Readv, Writev, etc.
|
||||||
|
//
|
||||||
// This small allocation gets stack allocated, which lets the
|
// This small allocation gets stack allocated, which lets the
|
||||||
// common use case of len(iovs) <= minIovec avoid more expensive
|
// common use case of len(iovs) <= minIovec avoid more expensive
|
||||||
// heap allocations.
|
// heap allocations.
|
||||||
const minIovec = 8
|
const minIovec = 8
|
||||||
|
|
||||||
|
// appendBytes converts bs to Iovecs and appends them to vecs.
|
||||||
func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
|
func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
|
||||||
for _, b := range bs {
|
for _, b := range bs {
|
||||||
var v Iovec
|
var v Iovec
|
||||||
@@ -27,7 +31,9 @@ func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
|
|||||||
return vecs
|
return vecs
|
||||||
}
|
}
|
||||||
|
|
||||||
func writevRacedetect(iovecs []Iovec, n int) {
|
// writevRaceDetect tells the race detector that the program
|
||||||
|
// has read the first n bytes stored in iovecs.
|
||||||
|
func writevRaceDetect(iovecs []Iovec, n int) {
|
||||||
if !raceenabled {
|
if !raceenabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -40,7 +46,9 @@ func writevRacedetect(iovecs []Iovec, n int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readvRacedetect(iovecs []Iovec, n int, err error) {
|
// readvRaceDetect tells the race detector that the program
|
||||||
|
// has written to the first n bytes stored in iovecs.
|
||||||
|
func readvRaceDetect(iovecs []Iovec, n int, err error) {
|
||||||
if !raceenabled {
|
if !raceenabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -60,7 +68,7 @@ func Readv(fd int, iovs [][]byte) (n int, err error) {
|
|||||||
iovecs := make([]Iovec, 0, minIovec)
|
iovecs := make([]Iovec, 0, minIovec)
|
||||||
iovecs = appendBytes(iovecs, iovs)
|
iovecs = appendBytes(iovecs, iovs)
|
||||||
n, err = readv(fd, iovecs)
|
n, err = readv(fd, iovecs)
|
||||||
readvRacedetect(iovecs, n, err)
|
readvRaceDetect(iovecs, n, err)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +76,7 @@ func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
|
|||||||
iovecs := make([]Iovec, 0, minIovec)
|
iovecs := make([]Iovec, 0, minIovec)
|
||||||
iovecs = appendBytes(iovecs, iovs)
|
iovecs = appendBytes(iovecs, iovs)
|
||||||
n, err = preadv(fd, iovecs, offset)
|
n, err = preadv(fd, iovecs, offset)
|
||||||
readvRacedetect(iovecs, n, err)
|
readvRaceDetect(iovecs, n, err)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +87,7 @@ func Writev(fd int, iovs [][]byte) (n int, err error) {
|
|||||||
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
||||||
}
|
}
|
||||||
n, err = writev(fd, iovecs)
|
n, err = writev(fd, iovecs)
|
||||||
writevRacedetect(iovecs, n)
|
writevRaceDetect(iovecs, n)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +98,6 @@ func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
|
|||||||
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
||||||
}
|
}
|
||||||
n, err = pwritev(fd, iovecs, offset)
|
n, err = pwritev(fd, iovecs, offset)
|
||||||
writevRacedetect(iovecs, n)
|
writevRaceDetect(iovecs, n)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build darwin || openbsd
|
//go:build darwin || linux || openbsd
|
||||||
|
|
||||||
package unix_test
|
package unix_test
|
||||||
|
|
||||||
|
|||||||
+12
-94
@@ -2150,33 +2150,10 @@ func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
|
|||||||
//sys exitThread(code int) (err error) = SYS_EXIT
|
//sys exitThread(code int) (err error) = SYS_EXIT
|
||||||
//sys readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV
|
//sys readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV
|
||||||
//sys writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV
|
//sys writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV
|
||||||
//sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV
|
//sys preadvSyscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV
|
||||||
//sys pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV
|
//sys pwritevSyscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV
|
||||||
//sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2
|
//sys preadv2Syscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2
|
||||||
//sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2
|
//sys pwritev2Syscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2
|
||||||
|
|
||||||
// minIovec is the size of the small initial allocation used by
|
|
||||||
// Readv, Writev, etc.
|
|
||||||
//
|
|
||||||
// This small allocation gets stack allocated, which lets the
|
|
||||||
// common use case of len(iovs) <= minIovs avoid more expensive
|
|
||||||
// heap allocations.
|
|
||||||
const minIovec = 8
|
|
||||||
|
|
||||||
// appendBytes converts bs to Iovecs and appends them to vecs.
|
|
||||||
func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
|
|
||||||
for _, b := range bs {
|
|
||||||
var v Iovec
|
|
||||||
v.SetLen(len(b))
|
|
||||||
if len(b) > 0 {
|
|
||||||
v.Base = &b[0]
|
|
||||||
} else {
|
|
||||||
v.Base = (*byte)(unsafe.Pointer(&_zero))
|
|
||||||
}
|
|
||||||
vecs = append(vecs, v)
|
|
||||||
}
|
|
||||||
return vecs
|
|
||||||
}
|
|
||||||
|
|
||||||
// offs2lohi splits offs into its low and high order bits.
|
// offs2lohi splits offs into its low and high order bits.
|
||||||
func offs2lohi(offs int64) (lo, hi uintptr) {
|
func offs2lohi(offs int64) (lo, hi uintptr) {
|
||||||
@@ -2184,69 +2161,23 @@ func offs2lohi(offs int64) (lo, hi uintptr) {
|
|||||||
return uintptr(offs), uintptr(uint64(offs) >> (longBits - 1) >> 1) // two shifts to avoid false positive in vet
|
return uintptr(offs), uintptr(uint64(offs) >> (longBits - 1) >> 1) // two shifts to avoid false positive in vet
|
||||||
}
|
}
|
||||||
|
|
||||||
func Readv(fd int, iovs [][]byte) (n int, err error) {
|
func preadv(fd int, iovecs []Iovec, offset int64) (n int, err error) {
|
||||||
iovecs := make([]Iovec, 0, minIovec)
|
|
||||||
iovecs = appendBytes(iovecs, iovs)
|
|
||||||
n, err = readv(fd, iovecs)
|
|
||||||
readvRacedetect(iovecs, n, err)
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
|
|
||||||
iovecs := make([]Iovec, 0, minIovec)
|
|
||||||
iovecs = appendBytes(iovecs, iovs)
|
|
||||||
lo, hi := offs2lohi(offset)
|
lo, hi := offs2lohi(offset)
|
||||||
n, err = preadv(fd, iovecs, lo, hi)
|
return preadvSyscall(fd, iovecs, lo, hi)
|
||||||
readvRacedetect(iovecs, n, err)
|
|
||||||
return n, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
|
func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
|
||||||
iovecs := make([]Iovec, 0, minIovec)
|
iovecs := make([]Iovec, 0, minIovec)
|
||||||
iovecs = appendBytes(iovecs, iovs)
|
iovecs = appendBytes(iovecs, iovs)
|
||||||
lo, hi := offs2lohi(offset)
|
lo, hi := offs2lohi(offset)
|
||||||
n, err = preadv2(fd, iovecs, lo, hi, flags)
|
n, err = preadv2Syscall(fd, iovecs, lo, hi, flags)
|
||||||
readvRacedetect(iovecs, n, err)
|
readvRaceDetect(iovecs, n, err)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func readvRacedetect(iovecs []Iovec, n int, err error) {
|
func pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error) {
|
||||||
if !raceenabled {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; n > 0 && i < len(iovecs); i++ {
|
|
||||||
m := min(int(iovecs[i].Len), n)
|
|
||||||
n -= m
|
|
||||||
if m > 0 {
|
|
||||||
raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
raceAcquire(unsafe.Pointer(&ioSync))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Writev(fd int, iovs [][]byte) (n int, err error) {
|
|
||||||
iovecs := make([]Iovec, 0, minIovec)
|
|
||||||
iovecs = appendBytes(iovecs, iovs)
|
|
||||||
if raceenabled {
|
|
||||||
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
|
||||||
}
|
|
||||||
n, err = writev(fd, iovecs)
|
|
||||||
writevRacedetect(iovecs, n)
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
|
|
||||||
iovecs := make([]Iovec, 0, minIovec)
|
|
||||||
iovecs = appendBytes(iovecs, iovs)
|
|
||||||
if raceenabled {
|
|
||||||
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
|
||||||
}
|
|
||||||
lo, hi := offs2lohi(offset)
|
lo, hi := offs2lohi(offset)
|
||||||
n, err = pwritev(fd, iovecs, lo, hi)
|
return pwritevSyscall(fd, iovecs, lo, hi)
|
||||||
writevRacedetect(iovecs, n)
|
|
||||||
return n, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
|
func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
|
||||||
@@ -2256,24 +2187,11 @@ func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error)
|
|||||||
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
||||||
}
|
}
|
||||||
lo, hi := offs2lohi(offset)
|
lo, hi := offs2lohi(offset)
|
||||||
n, err = pwritev2(fd, iovecs, lo, hi, flags)
|
n, err = pwritev2Syscall(fd, iovecs, lo, hi, flags)
|
||||||
writevRacedetect(iovecs, n)
|
writevRaceDetect(iovecs, n)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func writevRacedetect(iovecs []Iovec, n int) {
|
|
||||||
if !raceenabled {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; n > 0 && i < len(iovecs); i++ {
|
|
||||||
m := min(int(iovecs[i].Len), n)
|
|
||||||
n -= m
|
|
||||||
if m > 0 {
|
|
||||||
raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mmap varies by architecture; see syscall_linux_*.go.
|
// mmap varies by architecture; see syscall_linux_*.go.
|
||||||
//sys munmap(addr uintptr, length uintptr) (err error)
|
//sys munmap(addr uintptr, length uintptr) (err error)
|
||||||
//sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
|
//sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
|
||||||
|
|||||||
@@ -1785,7 +1785,7 @@ func writev(fd int, iovs []Iovec) (n int, err error) {
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) {
|
func preadvSyscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) {
|
||||||
var _p0 unsafe.Pointer
|
var _p0 unsafe.Pointer
|
||||||
if len(iovs) > 0 {
|
if len(iovs) > 0 {
|
||||||
_p0 = unsafe.Pointer(&iovs[0])
|
_p0 = unsafe.Pointer(&iovs[0])
|
||||||
@@ -1802,7 +1802,7 @@ func preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err er
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) {
|
func pwritevSyscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) {
|
||||||
var _p0 unsafe.Pointer
|
var _p0 unsafe.Pointer
|
||||||
if len(iovs) > 0 {
|
if len(iovs) > 0 {
|
||||||
_p0 = unsafe.Pointer(&iovs[0])
|
_p0 = unsafe.Pointer(&iovs[0])
|
||||||
@@ -1819,7 +1819,7 @@ func pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err e
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) {
|
func preadv2Syscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) {
|
||||||
var _p0 unsafe.Pointer
|
var _p0 unsafe.Pointer
|
||||||
if len(iovs) > 0 {
|
if len(iovs) > 0 {
|
||||||
_p0 = unsafe.Pointer(&iovs[0])
|
_p0 = unsafe.Pointer(&iovs[0])
|
||||||
@@ -1836,7 +1836,7 @@ func preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) {
|
func pwritev2Syscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) {
|
||||||
var _p0 unsafe.Pointer
|
var _p0 unsafe.Pointer
|
||||||
if len(iovs) > 0 {
|
if len(iovs) > 0 {
|
||||||
_p0 = unsafe.Pointer(&iovs[0])
|
_p0 = unsafe.Pointer(&iovs[0])
|
||||||
|
|||||||
Reference in New Issue
Block a user