fortio.org/log@v1.12.2/goroutine/gid.go (about) 1 // Copyright ©2020 Dan Kortschak. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package goroutine provides a single function that will return the runtime's 6 // ID number for the calling goroutine. 7 // 8 // The implementation is derived from Laevus Dexter's comment in Gophers' Slack #darkarts, 9 // https://gophers.slack.com/archives/C1C1YSQBT/p1593885226448300 post which linked to 10 // this playground snippet https://play.golang.org/p/CSOp9wyzydP. 11 package goroutine 12 13 import ( 14 "reflect" 15 "unsafe" 16 ) 17 18 // ID returns the runtime ID of the calling goroutine. 19 func ID() int64 { 20 return *(*int64)(add(getg(), goidoff)) 21 } 22 23 //go:nosplit 24 func getg() unsafe.Pointer { 25 return *(*unsafe.Pointer)(add(getm(), curgoff)) 26 } 27 28 //go:linkname add runtime.add 29 //go:nosplit 30 func add(p unsafe.Pointer, x uintptr) unsafe.Pointer 31 32 //go:linkname getm runtime.getm 33 //go:nosplit 34 func getm() unsafe.Pointer 35 36 var ( 37 curgoff = offset("*runtime.m", "curg") 38 goidoff = offset("*runtime.g", "goid") 39 ) 40 41 // offset returns the offset into typ for the given field. 42 func offset(typ, field string) uintptr { 43 rt := toType(typesByString(typ)[0]) 44 f, _ := rt.Elem().FieldByName(field) 45 return f.Offset 46 } 47 48 //go:linkname typesByString reflect.typesByString 49 func typesByString(s string) []unsafe.Pointer 50 51 //go:linkname toType reflect.toType 52 func toType(t unsafe.Pointer) reflect.Type