gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/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 //go:build ((linux && amd64) || (linux && arm64)) && go1.18 16 // +build linux,amd64 linux,arm64 17 // +build go1.18 18 19 // //go:linkname directives type-checked by checklinkname. Any other 20 // non-linkname assumptions outside the Go 1 compatibility guarantee should 21 // have an accompanied vet check or version guard build tag. 22 23 package rawfile 24 25 import ( 26 _ "unsafe" // for go:linkname 27 28 "golang.org/x/sys/unix" 29 ) 30 31 // BlockingPoll on amd64/arm64 makes the ppoll() syscall while calling the 32 // version of entersyscall that relinquishes the P so that other Gs can 33 // run. This is meant to be called in cases when the syscall is expected to 34 // block. On non amd64/arm64 platforms it just forwards to the ppoll() system 35 // call. 36 // 37 //go:noescape 38 func BlockingPoll(fds *PollEvent, nfds int, timeout *unix.Timespec) (int, unix.Errno) 39 40 // Use go:linkname to call into the runtime. As of Go 1.13 this has to 41 // be done from Go code so that we make an ABIInternal call to an 42 // ABIInternal function; see https://golang.org/issue/27539. 43 44 // We need to call both entersyscallblock and exitsyscall this way so 45 // that the runtime's check on the stack pointer lines up. 46 47 // Note that calling an unexported function in the runtime package is 48 // unsafe and this hack is likely to break in future Go releases. 49 50 //go:linkname entersyscallblock runtime.entersyscallblock 51 func entersyscallblock() 52 53 //go:linkname exitsyscall runtime.exitsyscall 54 func exitsyscall() 55 56 // These forwarding functions must be nosplit because 1) we must 57 // disallow preemption between entersyscallblock and exitsyscall, and 58 // 2) we have an untyped assembly frame on the stack which can not be 59 // grown or moved. 60 61 //go:nosplit 62 func callEntersyscallblock() { 63 entersyscallblock() 64 } 65 66 //go:nosplit 67 func callExitsyscall() { 68 exitsyscall() 69 }