github.com/cloudwego/runtimex@v0.1.0/runtimex.go (about) 1 // Copyright 2024 CloudWeGo 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 package runtimex 16 17 import ( 18 "errors" 19 "fmt" 20 "runtime" 21 "unsafe" 22 23 "github.com/modern-go/reflect2" 24 ) 25 26 var ( 27 // Runtime internals variables 28 gType reflect2.StructType 29 gidField reflect2.StructField 30 31 ErrNotSupported = errors.New(fmt.Sprintf("%s is not supported", runtime.Version())) 32 ) 33 34 func init() { 35 gType, _ = reflect2.TypeByName("runtime.g").(reflect2.StructType) 36 if gType != nil { 37 gidField = gType.FieldByName("goid") 38 } 39 } 40 41 func getg() unsafe.Pointer 42 43 //go:noescape 44 //go:linkname runtime_procPin runtime.procPin 45 func runtime_procPin() int 46 47 //go:noescape 48 //go:linkname runtime_procUnpin runtime.procUnpin 49 func runtime_procUnpin() 50 51 // GID return current goroutine's ID 52 func GID() (int, error) { 53 if gidField == nil { 54 return 0, ErrNotSupported 55 } 56 gp := getg() 57 gid := *(*int64)(unsafe.Add(gp, gidField.Offset())) 58 return int(gid), nil 59 } 60 61 // PID return current processor's ID 62 // It may not 100% accurate because the scheduler may preempt current goroutine and re-schedule it to another P after the function call return, 63 // so the caller should tolerate the preemption. 64 func PID() (int, error) { 65 id := runtime_procPin() 66 runtime_procUnpin() 67 return id, nil 68 }