golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/trace/resources.go (about) 1 // Copyright 2023 The Go Authors. 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 // Code generated by "gen.bash" from internal/trace/v2; DO NOT EDIT. 6 7 //go:build go1.21 8 9 package trace 10 11 import "fmt" 12 13 // ThreadID is the runtime-internal M structure's ID. This is unique 14 // for each OS thread. 15 type ThreadID int64 16 17 // NoThread indicates that the relevant events don't correspond to any 18 // thread in particular. 19 const NoThread = ThreadID(-1) 20 21 // ProcID is the runtime-internal G structure's id field. This is unique 22 // for each P. 23 type ProcID int64 24 25 // NoProc indicates that the relevant events don't correspond to any 26 // P in particular. 27 const NoProc = ProcID(-1) 28 29 // GoID is the runtime-internal G structure's goid field. This is unique 30 // for each goroutine. 31 type GoID int64 32 33 // NoGoroutine indicates that the relevant events don't correspond to any 34 // goroutine in particular. 35 const NoGoroutine = GoID(-1) 36 37 // GoState represents the state of a goroutine. 38 // 39 // New GoStates may be added in the future. Users of this type must be robust 40 // to that possibility. 41 type GoState uint8 42 43 const ( 44 GoUndetermined GoState = iota // No information is known about the goroutine. 45 GoNotExist // Goroutine does not exist. 46 GoRunnable // Goroutine is runnable but not running. 47 GoRunning // Goroutine is running. 48 GoWaiting // Goroutine is waiting on something to happen. 49 GoSyscall // Goroutine is in a system call. 50 ) 51 52 // Executing returns true if the state indicates that the goroutine is executing 53 // and bound to its thread. 54 func (s GoState) Executing() bool { 55 return s == GoRunning || s == GoSyscall 56 } 57 58 // String returns a human-readable representation of a GoState. 59 // 60 // The format of the returned string is for debugging purposes and is subject to change. 61 func (s GoState) String() string { 62 switch s { 63 case GoUndetermined: 64 return "Undetermined" 65 case GoNotExist: 66 return "NotExist" 67 case GoRunnable: 68 return "Runnable" 69 case GoRunning: 70 return "Running" 71 case GoWaiting: 72 return "Waiting" 73 case GoSyscall: 74 return "Syscall" 75 } 76 return "Bad" 77 } 78 79 // ProcState represents the state of a proc. 80 // 81 // New ProcStates may be added in the future. Users of this type must be robust 82 // to that possibility. 83 type ProcState uint8 84 85 const ( 86 ProcUndetermined ProcState = iota // No information is known about the proc. 87 ProcNotExist // Proc does not exist. 88 ProcRunning // Proc is running. 89 ProcIdle // Proc is idle. 90 ) 91 92 // Executing returns true if the state indicates that the proc is executing 93 // and bound to its thread. 94 func (s ProcState) Executing() bool { 95 return s == ProcRunning 96 } 97 98 // String returns a human-readable representation of a ProcState. 99 // 100 // The format of the returned string is for debugging purposes and is subject to change. 101 func (s ProcState) String() string { 102 switch s { 103 case ProcUndetermined: 104 return "Undetermined" 105 case ProcNotExist: 106 return "NotExist" 107 case ProcRunning: 108 return "Running" 109 case ProcIdle: 110 return "Idle" 111 } 112 return "Bad" 113 } 114 115 // ResourceKind indicates a kind of resource that has a state machine. 116 // 117 // New ResourceKinds may be added in the future. Users of this type must be robust 118 // to that possibility. 119 type ResourceKind uint8 120 121 const ( 122 ResourceNone ResourceKind = iota // No resource. 123 ResourceGoroutine // Goroutine. 124 ResourceProc // Proc. 125 ResourceThread // Thread. 126 ) 127 128 // String returns a human-readable representation of a ResourceKind. 129 // 130 // The format of the returned string is for debugging purposes and is subject to change. 131 func (r ResourceKind) String() string { 132 switch r { 133 case ResourceNone: 134 return "None" 135 case ResourceGoroutine: 136 return "Goroutine" 137 case ResourceProc: 138 return "Proc" 139 case ResourceThread: 140 return "Thread" 141 } 142 return "Bad" 143 } 144 145 // ResourceID represents a generic resource ID. 146 type ResourceID struct { 147 // Kind is the kind of resource this ID is for. 148 Kind ResourceKind 149 id int64 150 } 151 152 // MakeResourceID creates a general resource ID from a specific resource's ID. 153 func MakeResourceID[T interface{ GoID | ProcID | ThreadID }](id T) ResourceID { 154 var rd ResourceID 155 var a any = id 156 switch a.(type) { 157 case GoID: 158 rd.Kind = ResourceGoroutine 159 case ProcID: 160 rd.Kind = ResourceProc 161 case ThreadID: 162 rd.Kind = ResourceThread 163 } 164 rd.id = int64(id) 165 return rd 166 } 167 168 // Goroutine obtains a GoID from the resource ID. 169 // 170 // r.Kind must be ResourceGoroutine or this function will panic. 171 func (r ResourceID) Goroutine() GoID { 172 if r.Kind != ResourceGoroutine { 173 panic(fmt.Sprintf("attempted to get GoID from %s resource ID", r.Kind)) 174 } 175 return GoID(r.id) 176 } 177 178 // Proc obtains a ProcID from the resource ID. 179 // 180 // r.Kind must be ResourceProc or this function will panic. 181 func (r ResourceID) Proc() ProcID { 182 if r.Kind != ResourceProc { 183 panic(fmt.Sprintf("attempted to get ProcID from %s resource ID", r.Kind)) 184 } 185 return ProcID(r.id) 186 } 187 188 // Thread obtains a ThreadID from the resource ID. 189 // 190 // r.Kind must be ResourceThread or this function will panic. 191 func (r ResourceID) Thread() ThreadID { 192 if r.Kind != ResourceThread { 193 panic(fmt.Sprintf("attempted to get ThreadID from %s resource ID", r.Kind)) 194 } 195 return ThreadID(r.id) 196 } 197 198 // String returns a human-readable string representation of the ResourceID. 199 // 200 // This representation is subject to change and is intended primarily for debugging. 201 func (r ResourceID) String() string { 202 if r.Kind == ResourceNone { 203 return r.Kind.String() 204 } 205 return fmt.Sprintf("%s(%d)", r.Kind, r.id) 206 } 207 208 // StateTransition provides details about a StateTransition event. 209 type StateTransition struct { 210 // Resource is the resource this state transition is for. 211 Resource ResourceID 212 213 // Reason is a human-readable reason for the state transition. 214 Reason string 215 216 // Stack is the stack trace of the resource making the state transition. 217 // 218 // This is distinct from the result (Event).Stack because it pertains to 219 // the transitioning resource, not any of the ones executing the event 220 // this StateTransition came from. 221 // 222 // An example of this difference is the NotExist -> Runnable transition for 223 // goroutines, which indicates goroutine creation. In this particular case, 224 // a Stack here would refer to the starting stack of the new goroutine, and 225 // an (Event).Stack would refer to the stack trace of whoever created the 226 // goroutine. 227 Stack Stack 228 229 // The actual transition data. Stored in a neutral form so that 230 // we don't need fields for every kind of resource. 231 id int64 232 oldState uint8 233 newState uint8 234 } 235 236 func goStateTransition(id GoID, from, to GoState) StateTransition { 237 return StateTransition{ 238 Resource: ResourceID{Kind: ResourceGoroutine, id: int64(id)}, 239 oldState: uint8(from), 240 newState: uint8(to), 241 } 242 } 243 244 func procStateTransition(id ProcID, from, to ProcState) StateTransition { 245 return StateTransition{ 246 Resource: ResourceID{Kind: ResourceProc, id: int64(id)}, 247 oldState: uint8(from), 248 newState: uint8(to), 249 } 250 } 251 252 // Goroutine returns the state transition for a goroutine. 253 // 254 // Transitions to and from states that are Executing are special in that 255 // they change the future execution context. In other words, future events 256 // on the same thread will feature the same goroutine until it stops running. 257 // 258 // Panics if d.Resource.Kind is not ResourceGoroutine. 259 func (d StateTransition) Goroutine() (from, to GoState) { 260 if d.Resource.Kind != ResourceGoroutine { 261 panic("Goroutine called on non-Goroutine state transition") 262 } 263 return GoState(d.oldState), GoState(d.newState) 264 } 265 266 // Proc returns the state transition for a proc. 267 // 268 // Transitions to and from states that are Executing are special in that 269 // they change the future execution context. In other words, future events 270 // on the same thread will feature the same goroutine until it stops running. 271 // 272 // Panics if d.Resource.Kind is not ResourceProc. 273 func (d StateTransition) Proc() (from, to ProcState) { 274 if d.Resource.Kind != ResourceProc { 275 panic("Proc called on non-Proc state transition") 276 } 277 return ProcState(d.oldState), ProcState(d.newState) 278 }