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