blob: f5ebc8ee70a3e17dace6e23800a4672324c014d3 [file] [log] [blame]
// 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)
}