github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/tcpip/link/rawfile/blockingpoll_yield_unsafe.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build linux,amd64 linux,arm64 16 // +build go1.12 17 // +build !go1.18 18 19 // Check go:linkname function signatures when updating Go version. 20 21 package rawfile 22 23 import ( 24 _ "unsafe" // for go:linkname 25 26 "golang.org/x/sys/unix" 27 ) 28 29 // BlockingPoll on amd64/arm64 makes the ppoll() syscall while calling the 30 // version of entersyscall that relinquishes the P so that other Gs can 31 // run. This is meant to be called in cases when the syscall is expected to 32 // block. On non amd64/arm64 platforms it just forwards to the ppoll() system 33 // call. 34 // 35 //go:noescape 36 func BlockingPoll(fds *PollEvent, nfds int, timeout *unix.Timespec) (int, unix.Errno) 37 38 // Use go:linkname to call into the runtime. As of Go 1.12 this has to 39 // be done from Go code so that we make an ABIInternal call to an 40 // ABIInternal function; see https://golang.org/issue/27539. 41 42 // We need to call both entersyscallblock and exitsyscall this way so 43 // that the runtime's check on the stack pointer lines up. 44 45 // Note that calling an unexported function in the runtime package is 46 // unsafe and this hack is likely to break in future Go releases. 47 48 //go:linkname entersyscallblock runtime.entersyscallblock 49 func entersyscallblock() 50 51 //go:linkname exitsyscall runtime.exitsyscall 52 func exitsyscall() 53 54 // These forwarding functions must be nosplit because 1) we must 55 // disallow preemption between entersyscallblock and exitsyscall, and 56 // 2) we have an untyped assembly frame on the stack which can not be 57 // grown or moved. 58 59 //go:nosplit 60 func callEntersyscallblock() { 61 entersyscallblock() 62 } 63 64 //go:nosplit 65 func callExitsyscall() { 66 exitsyscall() 67 }