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  }