| // Copyright 2023 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Code generated by "gen.bash" from internal/trace; DO NOT EDIT. |
| |
| //go:build go1.21 |
| |
| package trace |
| |
| import "fmt" |
| |
| // ThreadID is the runtime-internal M structure's ID. This is unique |
| // for each OS thread. |
| type ThreadID int64 |
| |
| // NoThread indicates that the relevant events don't correspond to any |
| // thread in particular. |
| const NoThread = ThreadID(-1) |
| |
| // ProcID is the runtime-internal G structure's id field. This is unique |
| // for each P. |
| type ProcID int64 |
| |
| // NoProc indicates that the relevant events don't correspond to any |
| // P in particular. |
| const NoProc = ProcID(-1) |
| |
| // GoID is the runtime-internal G structure's goid field. This is unique |
| // for each goroutine. |
| type GoID int64 |
| |
| // NoGoroutine indicates that the relevant events don't correspond to any |
| // goroutine in particular. |
| const NoGoroutine = GoID(-1) |
| |
| // GoState represents the state of a goroutine. |
| // |
| // New GoStates may be added in the future. Users of this type must be robust |
| // to that possibility. |
| type GoState uint8 |
| |
| const ( |
| GoUndetermined GoState = iota // No information is known about the goroutine. |
| GoNotExist // Goroutine does not exist. |
| GoRunnable // Goroutine is runnable but not running. |
| GoRunning // Goroutine is running. |
| GoWaiting // Goroutine is waiting on something to happen. |
| GoSyscall // Goroutine is in a system call. |
| ) |
| |
| // Executing returns true if the state indicates that the goroutine is executing |
| // and bound to its thread. |
| func (s GoState) Executing() bool { |
| return s == GoRunning || s == GoSyscall |
| } |
| |
| // String returns a human-readable representation of a GoState. |
| // |
| // The format of the returned string is for debugging purposes and is subject to change. |
| func (s GoState) String() string { |
| switch s { |
| case GoUndetermined: |
| return "Undetermined" |
| case GoNotExist: |
| return "NotExist" |
| case GoRunnable: |
| return "Runnable" |
| case GoRunning: |
| return "Running" |
| case GoWaiting: |
| return "Waiting" |
| case GoSyscall: |
| return "Syscall" |
| } |
| return "Bad" |
| } |
| |
| // ProcState represents the state of a proc. |
| // |
| // New ProcStates may be added in the future. Users of this type must be robust |
| // to that possibility. |
| type ProcState uint8 |
| |
| const ( |
| ProcUndetermined ProcState = iota // No information is known about the proc. |
| ProcNotExist // Proc does not exist. |
| ProcRunning // Proc is running. |
| ProcIdle // Proc is idle. |
| ) |
| |
| // Executing returns true if the state indicates that the proc is executing |
| // and bound to its thread. |
| func (s ProcState) Executing() bool { |
| return s == ProcRunning |
| } |
| |
| // String returns a human-readable representation of a ProcState. |
| // |
| // The format of the returned string is for debugging purposes and is subject to change. |
| func (s ProcState) String() string { |
| switch s { |
| case ProcUndetermined: |
| return "Undetermined" |
| case ProcNotExist: |
| return "NotExist" |
| case ProcRunning: |
| return "Running" |
| case ProcIdle: |
| return "Idle" |
| } |
| return "Bad" |
| } |
| |
| // ResourceKind indicates a kind of resource that has a state machine. |
| // |
| // New ResourceKinds may be added in the future. Users of this type must be robust |
| // to that possibility. |
| type ResourceKind uint8 |
| |
| const ( |
| ResourceNone ResourceKind = iota // No resource. |
| ResourceGoroutine // Goroutine. |
| ResourceProc // Proc. |
| ResourceThread // Thread. |
| ) |
| |
| // String returns a human-readable representation of a ResourceKind. |
| // |
| // The format of the returned string is for debugging purposes and is subject to change. |
| func (r ResourceKind) String() string { |
| switch r { |
| case ResourceNone: |
| return "None" |
| case ResourceGoroutine: |
| return "Goroutine" |
| case ResourceProc: |
| return "Proc" |
| case ResourceThread: |
| return "Thread" |
| } |
| return "Bad" |
| } |
| |
| // ResourceID represents a generic resource ID. |
| type ResourceID struct { |
| // Kind is the kind of resource this ID is for. |
| Kind ResourceKind |
| id int64 |
| } |
| |
| // MakeResourceID creates a general resource ID from a specific resource's ID. |
| func MakeResourceID[T interface{ GoID | ProcID | ThreadID }](id T) ResourceID { |
| var rd ResourceID |
| var a any = id |
| switch a.(type) { |
| case GoID: |
| rd.Kind = ResourceGoroutine |
| case ProcID: |
| rd.Kind = ResourceProc |
| case ThreadID: |
| rd.Kind = ResourceThread |
| } |
| rd.id = int64(id) |
| return rd |
| } |
| |
| // Goroutine obtains a GoID from the resource ID. |
| // |
| // r.Kind must be ResourceGoroutine or this function will panic. |
| func (r ResourceID) Goroutine() GoID { |
| if r.Kind != ResourceGoroutine { |
| panic(fmt.Sprintf("attempted to get GoID from %s resource ID", r.Kind)) |
| } |
| return GoID(r.id) |
| } |
| |
| // Proc obtains a ProcID from the resource ID. |
| // |
| // r.Kind must be ResourceProc or this function will panic. |
| func (r ResourceID) Proc() ProcID { |
| if r.Kind != ResourceProc { |
| panic(fmt.Sprintf("attempted to get ProcID from %s resource ID", r.Kind)) |
| } |
| return ProcID(r.id) |
| } |
| |
| // Thread obtains a ThreadID from the resource ID. |
| // |
| // r.Kind must be ResourceThread or this function will panic. |
| func (r ResourceID) Thread() ThreadID { |
| if r.Kind != ResourceThread { |
| panic(fmt.Sprintf("attempted to get ThreadID from %s resource ID", r.Kind)) |
| } |
| return ThreadID(r.id) |
| } |
| |
| // String returns a human-readable string representation of the ResourceID. |
| // |
| // This representation is subject to change and is intended primarily for debugging. |
| func (r ResourceID) String() string { |
| if r.Kind == ResourceNone { |
| return r.Kind.String() |
| } |
| return fmt.Sprintf("%s(%d)", r.Kind, r.id) |
| } |
| |
| // StateTransition provides details about a StateTransition event. |
| type StateTransition struct { |
| // Resource is the resource this state transition is for. |
| Resource ResourceID |
| |
| // Reason is a human-readable reason for the state transition. |
| Reason string |
| |
| // Stack is the stack trace of the resource making the state transition. |
| // |
| // This is distinct from the result (Event).Stack because it pertains to |
| // the transitioning resource, not any of the ones executing the event |
| // this StateTransition came from. |
| // |
| // An example of this difference is the NotExist -> Runnable transition for |
| // goroutines, which indicates goroutine creation. In this particular case, |
| // a Stack here would refer to the starting stack of the new goroutine, and |
| // an (Event).Stack would refer to the stack trace of whoever created the |
| // goroutine. |
| Stack Stack |
| |
| // The actual transition data. Stored in a neutral form so that |
| // we don't need fields for every kind of resource. |
| id int64 |
| oldState uint8 |
| newState uint8 |
| } |
| |
| func goStateTransition(id GoID, from, to GoState) StateTransition { |
| return StateTransition{ |
| Resource: ResourceID{Kind: ResourceGoroutine, id: int64(id)}, |
| oldState: uint8(from), |
| newState: uint8(to), |
| } |
| } |
| |
| func procStateTransition(id ProcID, from, to ProcState) StateTransition { |
| return StateTransition{ |
| Resource: ResourceID{Kind: ResourceProc, id: int64(id)}, |
| oldState: uint8(from), |
| newState: uint8(to), |
| } |
| } |
| |
| // Goroutine returns the state transition for a goroutine. |
| // |
| // Transitions to and from states that are Executing are special in that |
| // they change the future execution context. In other words, future events |
| // on the same thread will feature the same goroutine until it stops running. |
| // |
| // Panics if d.Resource.Kind is not ResourceGoroutine. |
| func (d StateTransition) Goroutine() (from, to GoState) { |
| if d.Resource.Kind != ResourceGoroutine { |
| panic("Goroutine called on non-Goroutine state transition") |
| } |
| return GoState(d.oldState), GoState(d.newState) |
| } |
| |
| // Proc returns the state transition for a proc. |
| // |
| // Transitions to and from states that are Executing are special in that |
| // they change the future execution context. In other words, future events |
| // on the same thread will feature the same goroutine until it stops running. |
| // |
| // Panics if d.Resource.Kind is not ResourceProc. |
| func (d StateTransition) Proc() (from, to ProcState) { |
| if d.Resource.Kind != ResourceProc { |
| panic("Proc called on non-Proc state transition") |
| } |
| return ProcState(d.oldState), ProcState(d.newState) |
| } |