Skip to content

Commit 99666ae

Browse files
ianlancetaylorgopherbot
authored andcommitted
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>
1 parent e4444cb commit 99666ae

4 files changed

Lines changed: 32 additions & 106 deletions

File tree

unix/readv_unix.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build darwin || openbsd
5+
//go:build darwin || linux || openbsd
66

77
package unix
88

99
import "unsafe"
1010

11+
// minIovec is the size of the small initial allocation used by
12+
// Readv, Writev, etc.
13+
//
1114
// This small allocation gets stack allocated, which lets the
1215
// common use case of len(iovs) <= minIovec avoid more expensive
1316
// heap allocations.
1417
const minIovec = 8
1518

19+
// appendBytes converts bs to Iovecs and appends them to vecs.
1620
func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
1721
for _, b := range bs {
1822
var v Iovec
@@ -27,7 +31,9 @@ func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
2731
return vecs
2832
}
2933

30-
func writevRacedetect(iovecs []Iovec, n int) {
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) {
3137
if !raceenabled {
3238
return
3339
}
@@ -40,7 +46,9 @@ func writevRacedetect(iovecs []Iovec, n int) {
4046
}
4147
}
4248

43-
func readvRacedetect(iovecs []Iovec, n int, err error) {
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) {
4452
if !raceenabled {
4553
return
4654
}
@@ -60,15 +68,15 @@ func Readv(fd int, iovs [][]byte) (n int, err error) {
6068
iovecs := make([]Iovec, 0, minIovec)
6169
iovecs = appendBytes(iovecs, iovs)
6270
n, err = readv(fd, iovecs)
63-
readvRacedetect(iovecs, n, err)
71+
readvRaceDetect(iovecs, n, err)
6472
return n, err
6573
}
6674

6775
func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
6876
iovecs := make([]Iovec, 0, minIovec)
6977
iovecs = appendBytes(iovecs, iovs)
7078
n, err = preadv(fd, iovecs, offset)
71-
readvRacedetect(iovecs, n, err)
79+
readvRaceDetect(iovecs, n, err)
7280
return n, err
7381
}
7482

@@ -79,7 +87,7 @@ func Writev(fd int, iovs [][]byte) (n int, err error) {
7987
raceReleaseMerge(unsafe.Pointer(&ioSync))
8088
}
8189
n, err = writev(fd, iovecs)
82-
writevRacedetect(iovecs, n)
90+
writevRaceDetect(iovecs, n)
8391
return n, err
8492
}
8593

@@ -90,6 +98,6 @@ func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
9098
raceReleaseMerge(unsafe.Pointer(&ioSync))
9199
}
92100
n, err = pwritev(fd, iovecs, offset)
93-
writevRacedetect(iovecs, n)
101+
writevRaceDetect(iovecs, n)
94102
return n, err
95103
}

unix/readv_unix_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build darwin || openbsd
5+
//go:build darwin || linux || openbsd
66

77
package unix_test
88

unix/syscall_linux.go

Lines changed: 12 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,103 +2150,34 @@ func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
21502150
//sys exitThread(code int) (err error) = SYS_EXIT
21512151
//sys readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV
21522152
//sys writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV
2153-
//sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV
2154-
//sys pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV
2155-
//sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2
2156-
//sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2
2157-
2158-
// minIovec is the size of the small initial allocation used by
2159-
// Readv, Writev, etc.
2160-
//
2161-
// This small allocation gets stack allocated, which lets the
2162-
// common use case of len(iovs) <= minIovs avoid more expensive
2163-
// heap allocations.
2164-
const minIovec = 8
2165-
2166-
// appendBytes converts bs to Iovecs and appends them to vecs.
2167-
func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
2168-
for _, b := range bs {
2169-
var v Iovec
2170-
v.SetLen(len(b))
2171-
if len(b) > 0 {
2172-
v.Base = &b[0]
2173-
} else {
2174-
v.Base = (*byte)(unsafe.Pointer(&_zero))
2175-
}
2176-
vecs = append(vecs, v)
2177-
}
2178-
return vecs
2179-
}
2153+
//sys preadvSyscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV
2154+
//sys pwritevSyscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV
2155+
//sys preadv2Syscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2
2156+
//sys pwritev2Syscall(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2
21802157

21812158
// offs2lohi splits offs into its low and high order bits.
21822159
func offs2lohi(offs int64) (lo, hi uintptr) {
21832160
const longBits = SizeofLong * 8
21842161
return uintptr(offs), uintptr(uint64(offs) >> (longBits - 1) >> 1) // two shifts to avoid false positive in vet
21852162
}
21862163

2187-
func Readv(fd int, iovs [][]byte) (n int, err error) {
2188-
iovecs := make([]Iovec, 0, minIovec)
2189-
iovecs = appendBytes(iovecs, iovs)
2190-
n, err = readv(fd, iovecs)
2191-
readvRacedetect(iovecs, n, err)
2192-
return n, err
2193-
}
2194-
2195-
func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
2196-
iovecs := make([]Iovec, 0, minIovec)
2197-
iovecs = appendBytes(iovecs, iovs)
2164+
func preadv(fd int, iovecs []Iovec, offset int64) (n int, err error) {
21982165
lo, hi := offs2lohi(offset)
2199-
n, err = preadv(fd, iovecs, lo, hi)
2200-
readvRacedetect(iovecs, n, err)
2201-
return n, err
2166+
return preadvSyscall(fd, iovecs, lo, hi)
22022167
}
22032168

22042169
func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
22052170
iovecs := make([]Iovec, 0, minIovec)
22062171
iovecs = appendBytes(iovecs, iovs)
22072172
lo, hi := offs2lohi(offset)
2208-
n, err = preadv2(fd, iovecs, lo, hi, flags)
2209-
readvRacedetect(iovecs, n, err)
2210-
return n, err
2211-
}
2212-
2213-
func readvRacedetect(iovecs []Iovec, n int, err error) {
2214-
if !raceenabled {
2215-
return
2216-
}
2217-
for i := 0; n > 0 && i < len(iovecs); i++ {
2218-
m := min(int(iovecs[i].Len), n)
2219-
n -= m
2220-
if m > 0 {
2221-
raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
2222-
}
2223-
}
2224-
if err == nil {
2225-
raceAcquire(unsafe.Pointer(&ioSync))
2226-
}
2227-
}
2228-
2229-
func Writev(fd int, iovs [][]byte) (n int, err error) {
2230-
iovecs := make([]Iovec, 0, minIovec)
2231-
iovecs = appendBytes(iovecs, iovs)
2232-
if raceenabled {
2233-
raceReleaseMerge(unsafe.Pointer(&ioSync))
2234-
}
2235-
n, err = writev(fd, iovecs)
2236-
writevRacedetect(iovecs, n)
2173+
n, err = preadv2Syscall(fd, iovecs, lo, hi, flags)
2174+
readvRaceDetect(iovecs, n, err)
22372175
return n, err
22382176
}
22392177

2240-
func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
2241-
iovecs := make([]Iovec, 0, minIovec)
2242-
iovecs = appendBytes(iovecs, iovs)
2243-
if raceenabled {
2244-
raceReleaseMerge(unsafe.Pointer(&ioSync))
2245-
}
2178+
func pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error) {
22462179
lo, hi := offs2lohi(offset)
2247-
n, err = pwritev(fd, iovecs, lo, hi)
2248-
writevRacedetect(iovecs, n)
2249-
return n, err
2180+
return pwritevSyscall(fd, iovecs, lo, hi)
22502181
}
22512182

22522183
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)
22562187
raceReleaseMerge(unsafe.Pointer(&ioSync))
22572188
}
22582189
lo, hi := offs2lohi(offset)
2259-
n, err = pwritev2(fd, iovecs, lo, hi, flags)
2260-
writevRacedetect(iovecs, n)
2190+
n, err = pwritev2Syscall(fd, iovecs, lo, hi, flags)
2191+
writevRaceDetect(iovecs, n)
22612192
return n, err
22622193
}
22632194

2264-
func writevRacedetect(iovecs []Iovec, n int) {
2265-
if !raceenabled {
2266-
return
2267-
}
2268-
for i := 0; n > 0 && i < len(iovecs); i++ {
2269-
m := min(int(iovecs[i].Len), n)
2270-
n -= m
2271-
if m > 0 {
2272-
raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
2273-
}
2274-
}
2275-
}
2276-
22772195
// mmap varies by architecture; see syscall_linux_*.go.
22782196
//sys munmap(addr uintptr, length uintptr) (err error)
22792197
//sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)

unix/zsyscall_linux.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)