1970 //sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV |
1971 //sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV |
1971 //sys pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV |
1972 //sys pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV |
1972 //sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2 |
1973 //sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2 |
1973 //sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2 |
1974 //sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2 |
1974 |
1975 |
1975 func bytes2iovec(bs [][]byte) []Iovec { |
1976 // minIovec is the size of the small initial allocation used by |
1976 iovecs := make([]Iovec, len(bs)) |
1977 // Readv, Writev, etc. |
1977 for i, b := range bs { |
1978 // |
1978 iovecs[i].SetLen(len(b)) |
1979 // This small allocation gets stack allocated, which lets the |
|
1980 // common use case of len(iovs) <= minIovs avoid more expensive |
|
1981 // heap allocations. |
|
1982 const minIovec = 8 |
|
1983 |
|
1984 // appendBytes converts bs to Iovecs and appends them to vecs. |
|
1985 func appendBytes(vecs []Iovec, bs [][]byte) []Iovec { |
|
1986 for _, b := range bs { |
|
1987 var v Iovec |
|
1988 v.SetLen(len(b)) |
1979 if len(b) > 0 { |
1989 if len(b) > 0 { |
1980 iovecs[i].Base = &b[0] |
1990 v.Base = &b[0] |
1981 } else { |
1991 } else { |
1982 iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero)) |
1992 v.Base = (*byte)(unsafe.Pointer(&_zero)) |
1983 } |
1993 } |
1984 } |
1994 vecs = append(vecs, v) |
1985 return iovecs |
1995 } |
1986 } |
1996 return vecs |
1987 |
1997 } |
1988 // offs2lohi splits offs into its lower and upper unsigned long. On 64-bit |
1998 |
1989 // systems, hi will always be 0. On 32-bit systems, offs will be split in half. |
1999 // offs2lohi splits offs into its low and high order bits. |
1990 // preadv/pwritev chose this calling convention so they don't need to add a |
|
1991 // padding-register for alignment on ARM. |
|
1992 func offs2lohi(offs int64) (lo, hi uintptr) { |
2000 func offs2lohi(offs int64) (lo, hi uintptr) { |
1993 return uintptr(offs), uintptr(uint64(offs) >> SizeofLong) |
2001 const longBits = SizeofLong * 8 |
|
2002 return uintptr(offs), uintptr(uint64(offs) >> longBits) |
1994 } |
2003 } |
1995 |
2004 |
1996 func Readv(fd int, iovs [][]byte) (n int, err error) { |
2005 func Readv(fd int, iovs [][]byte) (n int, err error) { |
1997 iovecs := bytes2iovec(iovs) |
2006 iovecs := make([]Iovec, 0, minIovec) |
|
2007 iovecs = appendBytes(iovecs, iovs) |
1998 n, err = readv(fd, iovecs) |
2008 n, err = readv(fd, iovecs) |
1999 readvRacedetect(iovecs, n, err) |
2009 readvRacedetect(iovecs, n, err) |
2000 return n, err |
2010 return n, err |
2001 } |
2011 } |
2002 |
2012 |
2003 func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { |
2013 func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { |
2004 iovecs := bytes2iovec(iovs) |
2014 iovecs := make([]Iovec, 0, minIovec) |
|
2015 iovecs = appendBytes(iovecs, iovs) |
2005 lo, hi := offs2lohi(offset) |
2016 lo, hi := offs2lohi(offset) |
2006 n, err = preadv(fd, iovecs, lo, hi) |
2017 n, err = preadv(fd, iovecs, lo, hi) |
2007 readvRacedetect(iovecs, n, err) |
2018 readvRacedetect(iovecs, n, err) |
2008 return n, err |
2019 return n, err |
2009 } |
2020 } |
2010 |
2021 |
2011 func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { |
2022 func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { |
2012 iovecs := bytes2iovec(iovs) |
2023 iovecs := make([]Iovec, 0, minIovec) |
|
2024 iovecs = appendBytes(iovecs, iovs) |
2013 lo, hi := offs2lohi(offset) |
2025 lo, hi := offs2lohi(offset) |
2014 n, err = preadv2(fd, iovecs, lo, hi, flags) |
2026 n, err = preadv2(fd, iovecs, lo, hi, flags) |
2015 readvRacedetect(iovecs, n, err) |
2027 readvRacedetect(iovecs, n, err) |
2016 return n, err |
2028 return n, err |
2017 } |
2029 } |
2034 raceAcquire(unsafe.Pointer(&ioSync)) |
2046 raceAcquire(unsafe.Pointer(&ioSync)) |
2035 } |
2047 } |
2036 } |
2048 } |
2037 |
2049 |
2038 func Writev(fd int, iovs [][]byte) (n int, err error) { |
2050 func Writev(fd int, iovs [][]byte) (n int, err error) { |
2039 iovecs := bytes2iovec(iovs) |
2051 iovecs := make([]Iovec, 0, minIovec) |
|
2052 iovecs = appendBytes(iovecs, iovs) |
2040 if raceenabled { |
2053 if raceenabled { |
2041 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
2054 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
2042 } |
2055 } |
2043 n, err = writev(fd, iovecs) |
2056 n, err = writev(fd, iovecs) |
2044 writevRacedetect(iovecs, n) |
2057 writevRacedetect(iovecs, n) |
2045 return n, err |
2058 return n, err |
2046 } |
2059 } |
2047 |
2060 |
2048 func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { |
2061 func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { |
2049 iovecs := bytes2iovec(iovs) |
2062 iovecs := make([]Iovec, 0, minIovec) |
|
2063 iovecs = appendBytes(iovecs, iovs) |
2050 if raceenabled { |
2064 if raceenabled { |
2051 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
2065 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
2052 } |
2066 } |
2053 lo, hi := offs2lohi(offset) |
2067 lo, hi := offs2lohi(offset) |
2054 n, err = pwritev(fd, iovecs, lo, hi) |
2068 n, err = pwritev(fd, iovecs, lo, hi) |
2055 writevRacedetect(iovecs, n) |
2069 writevRacedetect(iovecs, n) |
2056 return n, err |
2070 return n, err |
2057 } |
2071 } |
2058 |
2072 |
2059 func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { |
2073 func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { |
2060 iovecs := bytes2iovec(iovs) |
2074 iovecs := make([]Iovec, 0, minIovec) |
|
2075 iovecs = appendBytes(iovecs, iovs) |
2061 if raceenabled { |
2076 if raceenabled { |
2062 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
2077 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
2063 } |
2078 } |
2064 lo, hi := offs2lohi(offset) |
2079 lo, hi := offs2lohi(offset) |
2065 n, err = pwritev2(fd, iovecs, lo, hi, flags) |
2080 n, err = pwritev2(fd, iovecs, lo, hi, flags) |