Change Notify() to use unix.RawSyscall.
eventfd.Notify() uses unix.Write which will eventually call unix.Syscall which will yield the current go processor resulting in the Go scheduler parking the current goroutine till the syscall returns. But in most cases where Notify() is called there is no reason to yield as the caller probably wants to continue doing something right afterwards. Like in the case of the sharedmem endpoint which may still have more packets to write. PiperOrigin-RevId: 405693801
This commit is contained in:
parent
c8d8354700
commit
2d384f761c
|
@ -6,6 +6,7 @@ go_library(
|
|||
name = "eventfd",
|
||||
srcs = [
|
||||
"eventfd.go",
|
||||
"eventfd_unsafe.go",
|
||||
],
|
||||
visibility = ["//:sandbox"],
|
||||
deps = [
|
||||
|
|
|
@ -74,7 +74,7 @@ func (ev Eventfd) Write(val uint64) error {
|
|||
var buf [sizeofUint64]byte
|
||||
hostarch.ByteOrder.PutUint64(buf[:], val)
|
||||
for {
|
||||
n, err := unix.Write(ev.fd, buf[:])
|
||||
n, err := nonBlockingWrite(ev.fd, buf[:])
|
||||
if err == unix.EINTR {
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2021 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package eventfd
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// nonBlockingWrite writes the given buffer to a file descriptor. It fails if
|
||||
// partial data is written.
|
||||
func nonBlockingWrite(fd int, buf []byte) (int, error) {
|
||||
var ptr unsafe.Pointer
|
||||
if len(buf) > 0 {
|
||||
ptr = unsafe.Pointer(&buf[0])
|
||||
}
|
||||
|
||||
nwritten, _, errno := unix.RawSyscall(unix.SYS_WRITE, uintptr(fd), uintptr(ptr), uintptr(len(buf)))
|
||||
if errno != 0 {
|
||||
return int(nwritten), errno
|
||||
}
|
||||
return int(nwritten), nil
|
||||
}
|
Loading…
Reference in New Issue