// 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.

package trace

import (
	"fmt"
	"strings"

	"internal/trace/v2/event"
	"internal/trace/v2/event/go122"
	"internal/trace/v2/version"
)

// ordering emulates Go scheduler state for both validation and
// for putting events in the right order.
//
// The interface to ordering consists of two methods: Advance
// and Next. Advance is called to try and advance an event and
// add completed events to the ordering. Next is used to pick
// off events in the ordering.
type ordering struct {
	gStates     map[GoID]*gState
	pStates     map[ProcID]*pState // TODO: The keys are dense, so this can be a slice.
	mStates     map[ThreadID]*mState
	activeTasks map[TaskID]taskState
	gcSeq       uint64
	gcState     gcState
	initialGen  uint64
	queue       queue[Event]
}

// Advance checks if it's valid to proceed with ev which came from thread m.
//
// It assumes the gen value passed to it is monotonically increasing across calls.
//
// If any error is returned, then the trace is broken and trace parsing must cease.
// If it's not valid to advance with ev, but no error was encountered, the caller
// should attempt to advance with other candidate events from other threads. If the
// caller runs out of candidates, the trace is invalid.
//
// If this returns true, Next is guaranteed to return a complete event. However,
// multiple events may be added to the ordering, so the caller should (but is not
// required to) continue to call Next until it is exhausted.
func (o *ordering) Advance(ev *baseEvent, evt *evTable, m ThreadID, gen uint64) (bool, error) {
	if o.initialGen == 0 {
		// Set the initial gen if necessary.
		o.initialGen = gen
	}

	var curCtx, newCtx schedCtx
	curCtx.M = m
	newCtx.M = m

	var ms *mState
	if m == NoThread {
		curCtx.P = NoProc
		curCtx.G = NoGoroutine
		newCtx = curCtx
	} else {
		// Pull out or create the mState for this event.
		var ok bool
		ms, ok = o.mStates[m]
		if !ok {
			ms = &mState{
				g: NoGoroutine,
				p: NoProc,
			}
			o.mStates[m] = ms
		}
		curCtx.P = ms.p
		curCtx.G = ms.g
		newCtx = curCtx
	}

	f := orderingDispatch[ev.typ]
	if f == nil {
		return false, fmt.Errorf("bad event type found while ordering: %v", ev.typ)
	}
	newCtx, ok, err := f(o, ev, evt, m, gen, curCtx)
	if err == nil && ok && ms != nil {
		// Update the mState for this event.
		ms.p = newCtx.P
		ms.g = newCtx.G
	}
	return ok, err
}

type orderingHandleFunc func(o *ordering, ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error)

var orderingDispatch = [256]orderingHandleFunc{
	// Procs.
	go122.EvProcsChange: (*ordering).advanceAnnotation,
	go122.EvProcStart:   (*ordering).advanceProcStart,
	go122.EvProcStop:    (*ordering).advanceProcStop,
	go122.EvProcSteal:   (*ordering).advanceProcSteal,
	go122.EvProcStatus:  (*ordering).advanceProcStatus,

	// Goroutines.
	go122.EvGoCreate:            (*ordering).advanceGoCreate,
	go122.EvGoCreateSyscall:     (*ordering).advanceGoCreateSyscall,
	go122.EvGoStart:             (*ordering).advanceGoStart,
	go122.EvGoDestroy:           (*ordering).advanceGoStopExec,
	go122.EvGoDestroySyscall:    (*ordering).advanceGoDestroySyscall,
	go122.EvGoStop:              (*ordering).advanceGoStopExec,
	go122.EvGoBlock:             (*ordering).advanceGoStopExec,
	go122.EvGoUnblock:           (*ordering).advanceGoUnblock,
	go122.EvGoSyscallBegin:      (*ordering).advanceGoSyscallBegin,
	go122.EvGoSyscallEnd:        (*ordering).advanceGoSyscallEnd,
	go122.EvGoSyscallEndBlocked: (*ordering).advanceGoSyscallEndBlocked,
	go122.EvGoStatus:            (*ordering).advanceGoStatus,

	// STW.
	go122.EvSTWBegin: (*ordering).advanceGoRangeBegin,
	go122.EvSTWEnd:   (*ordering).advanceGoRangeEnd,

	// GC events.
	go122.EvGCActive:           (*ordering).advanceGCActive,
	go122.EvGCBegin:            (*ordering).advanceGCBegin,
	go122.EvGCEnd:              (*ordering).advanceGCEnd,
	go122.EvGCSweepActive:      (*ordering).advanceGCSweepActive,
	go122.EvGCSweepBegin:       (*ordering).advanceGCSweepBegin,
	go122.EvGCSweepEnd:         (*ordering).advanceGCSweepEnd,
	go122.EvGCMarkAssistActive: (*ordering).advanceGoRangeActive,
	go122.EvGCMarkAssistBegin:  (*ordering).advanceGoRangeBegin,
	go122.EvGCMarkAssistEnd:    (*ordering).advanceGoRangeEnd,
	go122.EvHeapAlloc:          (*ordering).advanceHeapMetric,
	go122.EvHeapGoal:           (*ordering).advanceHeapMetric,

	// Annotations.
	go122.EvGoLabel:         (*ordering).advanceAnnotation,
	go122.EvUserTaskBegin:   (*ordering).advanceUserTaskBegin,
	go122.EvUserTaskEnd:     (*ordering).advanceUserTaskEnd,
	go122.EvUserRegionBegin: (*ordering).advanceUserRegionBegin,
	go122.EvUserRegionEnd:   (*ordering).advanceUserRegionEnd,
	go122.EvUserLog:         (*ordering).advanceAnnotation,

	// Coroutines. Added in Go 1.23.
	go122.EvGoSwitch:        (*ordering).advanceGoSwitch,
	go122.EvGoSwitchDestroy: (*ordering).advanceGoSwitch,
	go122.EvGoCreateBlocked: (*ordering).advanceGoCreate,

	// GoStatus event with a stack. Added in Go 1.23.
	go122.EvGoStatusStack: (*ordering).advanceGoStatus,
}

func (o *ordering) advanceProcStatus(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	pid := ProcID(ev.args[0])
	status := go122.ProcStatus(ev.args[1])
	if int(status) >= len(go122ProcStatus2ProcState) {
		return curCtx, false, fmt.Errorf("invalid status for proc %d: %d", pid, status)
	}
	oldState := go122ProcStatus2ProcState[status]
	if s, ok := o.pStates[pid]; ok {
		if status == go122.ProcSyscallAbandoned && s.status == go122.ProcSyscall {
			// ProcSyscallAbandoned is a special case of ProcSyscall. It indicates a
			// potential loss of information, but if we're already in ProcSyscall,
			// we haven't lost the relevant information. Promote the status and advance.
			oldState = ProcRunning
			ev.args[1] = uint64(go122.ProcSyscall)
		} else if status == go122.ProcSyscallAbandoned && s.status == go122.ProcSyscallAbandoned {
			// If we're passing through ProcSyscallAbandoned, then there's no promotion
			// to do. We've lost the M that this P is associated with. However it got there,
			// it's going to appear as idle in the API, so pass through as idle.
			oldState = ProcIdle
			ev.args[1] = uint64(go122.ProcSyscallAbandoned)
		} else if s.status != status {
			return curCtx, false, fmt.Errorf("inconsistent status for proc %d: old %v vs. new %v", pid, s.status, status)
		}
		s.seq = makeSeq(gen, 0) // Reset seq.
	} else {
		o.pStates[pid] = &pState{id: pid, status: status, seq: makeSeq(gen, 0)}
		if gen == o.initialGen {
			oldState = ProcUndetermined
		} else {
			oldState = ProcNotExist
		}
	}
	ev.extra(version.Go122)[0] = uint64(oldState) // Smuggle in the old state for StateTransition.

	// Bind the proc to the new context, if it's running.
	newCtx := curCtx
	if status == go122.ProcRunning || status == go122.ProcSyscall {
		newCtx.P = pid
	}
	// If we're advancing through ProcSyscallAbandoned *but* oldState is running then we've
	// promoted it to ProcSyscall. However, because it's ProcSyscallAbandoned, we know this
	// P is about to get stolen and its status very likely isn't being emitted by the same
	// thread it was bound to. Since this status is Running -> Running and Running is binding,
	// we need to make sure we emit it in the right context: the context to which it is bound.
	// Find it, and set our current context to it.
	if status == go122.ProcSyscallAbandoned && oldState == ProcRunning {
		// N.B. This is slow but it should be fairly rare.
		found := false
		for mid, ms := range o.mStates {
			if ms.p == pid {
				curCtx.M = mid
				curCtx.P = pid
				curCtx.G = ms.g
				found = true
			}
		}
		if !found {
			return curCtx, false, fmt.Errorf("failed to find sched context for proc %d that's about to be stolen", pid)
		}
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return newCtx, true, nil
}

func (o *ordering) advanceProcStart(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	pid := ProcID(ev.args[0])
	seq := makeSeq(gen, ev.args[1])

	// Try to advance. We might fail here due to sequencing, because the P hasn't
	// had a status emitted, or because we already have a P and we're in a syscall,
	// and we haven't observed that it was stolen from us yet.
	state, ok := o.pStates[pid]
	if !ok || state.status != go122.ProcIdle || !seq.succeeds(state.seq) || curCtx.P != NoProc {
		// We can't make an inference as to whether this is bad. We could just be seeing
		// a ProcStart on a different M before the proc's state was emitted, or before we
		// got to the right point in the trace.
		//
		// Note that we also don't advance here if we have a P and we're in a syscall.
		return curCtx, false, nil
	}
	// We can advance this P. Check some invariants.
	//
	// We might have a goroutine if a goroutine is exiting a syscall.
	reqs := event.SchedReqs{Thread: event.MustHave, Proc: event.MustNotHave, Goroutine: event.MayHave}
	if err := validateCtx(curCtx, reqs); err != nil {
		return curCtx, false, err
	}
	state.status = go122.ProcRunning
	state.seq = seq
	newCtx := curCtx
	newCtx.P = pid
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return newCtx, true, nil
}

func (o *ordering) advanceProcStop(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// We must be able to advance this P.
	//
	// There are 2 ways a P can stop: ProcStop and ProcSteal. ProcStop is used when the P
	// is stopped by the same M that started it, while ProcSteal is used when another M
	// steals the P by stopping it from a distance.
	//
	// Since a P is bound to an M, and we're stopping on the same M we started, it must
	// always be possible to advance the current M's P from a ProcStop. This is also why
	// ProcStop doesn't need a sequence number.
	state, ok := o.pStates[curCtx.P]
	if !ok {
		return curCtx, false, fmt.Errorf("event %s for proc (%v) that doesn't exist", go122.EventString(ev.typ), curCtx.P)
	}
	if state.status != go122.ProcRunning && state.status != go122.ProcSyscall {
		return curCtx, false, fmt.Errorf("%s event for proc that's not %s or %s", go122.EventString(ev.typ), go122.ProcRunning, go122.ProcSyscall)
	}
	reqs := event.SchedReqs{Thread: event.MustHave, Proc: event.MustHave, Goroutine: event.MayHave}
	if err := validateCtx(curCtx, reqs); err != nil {
		return curCtx, false, err
	}
	state.status = go122.ProcIdle
	newCtx := curCtx
	newCtx.P = NoProc
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return newCtx, true, nil
}

func (o *ordering) advanceProcSteal(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	pid := ProcID(ev.args[0])
	seq := makeSeq(gen, ev.args[1])
	state, ok := o.pStates[pid]
	if !ok || (state.status != go122.ProcSyscall && state.status != go122.ProcSyscallAbandoned) || !seq.succeeds(state.seq) {
		// We can't make an inference as to whether this is bad. We could just be seeing
		// a ProcStart on a different M before the proc's state was emitted, or before we
		// got to the right point in the trace.
		return curCtx, false, nil
	}
	// We can advance this P. Check some invariants.
	reqs := event.SchedReqs{Thread: event.MustHave, Proc: event.MayHave, Goroutine: event.MayHave}
	if err := validateCtx(curCtx, reqs); err != nil {
		return curCtx, false, err
	}
	// Smuggle in the P state that let us advance so we can surface information to the event.
	// Specifically, we need to make sure that the event is interpreted not as a transition of
	// ProcRunning -> ProcIdle but ProcIdle -> ProcIdle instead.
	//
	// ProcRunning is binding, but we may be running with a P on the current M and we can't
	// bind another P. This P is about to go ProcIdle anyway.
	oldStatus := state.status
	ev.extra(version.Go122)[0] = uint64(oldStatus)

	// Update the P's status and sequence number.
	state.status = go122.ProcIdle
	state.seq = seq

	// If we've lost information then don't try to do anything with the M.
	// It may have moved on and we can't be sure.
	if oldStatus == go122.ProcSyscallAbandoned {
		o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
		return curCtx, true, nil
	}

	// Validate that the M we're stealing from is what we expect.
	mid := ThreadID(ev.args[2]) // The M we're stealing from.

	newCtx := curCtx
	if mid == curCtx.M {
		// We're stealing from ourselves. This behaves like a ProcStop.
		if curCtx.P != pid {
			return curCtx, false, fmt.Errorf("tried to self-steal proc %d (thread %d), but got proc %d instead", pid, mid, curCtx.P)
		}
		newCtx.P = NoProc
		o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
		return newCtx, true, nil
	}

	// We're stealing from some other M.
	mState, ok := o.mStates[mid]
	if !ok {
		return curCtx, false, fmt.Errorf("stole proc from non-existent thread %d", mid)
	}

	// Make sure we're actually stealing the right P.
	if mState.p != pid {
		return curCtx, false, fmt.Errorf("tried to steal proc %d from thread %d, but got proc %d instead", pid, mid, mState.p)
	}

	// Tell the M it has no P so it can proceed.
	//
	// This is safe because we know the P was in a syscall and
	// the other M must be trying to get out of the syscall.
	// GoSyscallEndBlocked cannot advance until the corresponding
	// M loses its P.
	mState.p = NoProc
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return newCtx, true, nil
}

func (o *ordering) advanceGoStatus(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	gid := GoID(ev.args[0])
	mid := ThreadID(ev.args[1])
	status := go122.GoStatus(ev.args[2])

	if int(status) >= len(go122GoStatus2GoState) {
		return curCtx, false, fmt.Errorf("invalid status for goroutine %d: %d", gid, status)
	}
	oldState := go122GoStatus2GoState[status]
	if s, ok := o.gStates[gid]; ok {
		if s.status != status {
			return curCtx, false, fmt.Errorf("inconsistent status for goroutine %d: old %v vs. new %v", gid, s.status, status)
		}
		s.seq = makeSeq(gen, 0) // Reset seq.
	} else if gen == o.initialGen {
		// Set the state.
		o.gStates[gid] = &gState{id: gid, status: status, seq: makeSeq(gen, 0)}
		oldState = GoUndetermined
	} else {
		return curCtx, false, fmt.Errorf("found goroutine status for new goroutine after the first generation: id=%v status=%v", gid, status)
	}
	ev.extra(version.Go122)[0] = uint64(oldState) // Smuggle in the old state for StateTransition.

	newCtx := curCtx
	switch status {
	case go122.GoRunning:
		// Bind the goroutine to the new context, since it's running.
		newCtx.G = gid
	case go122.GoSyscall:
		if mid == NoThread {
			return curCtx, false, fmt.Errorf("found goroutine %d in syscall without a thread", gid)
		}
		// Is the syscall on this thread? If so, bind it to the context.
		// Otherwise, we're talking about a G sitting in a syscall on an M.
		// Validate the named M.
		if mid == curCtx.M {
			if gen != o.initialGen && curCtx.G != gid {
				// If this isn't the first generation, we *must* have seen this
				// binding occur already. Even if the G was blocked in a syscall
				// for multiple generations since trace start, we would have seen
				// a previous GoStatus event that bound the goroutine to an M.
				return curCtx, false, fmt.Errorf("inconsistent thread for syscalling goroutine %d: thread has goroutine %d", gid, curCtx.G)
			}
			newCtx.G = gid
			break
		}
		// Now we're talking about a thread and goroutine that have been
		// blocked on a syscall for the entire generation. This case must
		// not have a P; the runtime makes sure that all Ps are traced at
		// the beginning of a generation, which involves taking a P back
		// from every thread.
		ms, ok := o.mStates[mid]
		if ok {
			// This M has been seen. That means we must have seen this
			// goroutine go into a syscall on this thread at some point.
			if ms.g != gid {
				// But the G on the M doesn't match. Something's wrong.
				return curCtx, false, fmt.Errorf("inconsistent thread for syscalling goroutine %d: thread has goroutine %d", gid, ms.g)
			}
			// This case is just a Syscall->Syscall event, which needs to
			// appear as having the G currently bound to this M.
			curCtx.G = ms.g
		} else if !ok {
			// The M hasn't been seen yet. That means this goroutine
			// has just been sitting in a syscall on this M. Create
			// a state for it.
			o.mStates[mid] = &mState{g: gid, p: NoProc}
			// Don't set curCtx.G in this case because this event is the
			// binding event (and curCtx represents the "before" state).
		}
		// Update the current context to the M we're talking about.
		curCtx.M = mid
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return newCtx, true, nil
}

func (o *ordering) advanceGoCreate(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// Goroutines must be created on a running P, but may or may not be created
	// by a running goroutine.
	reqs := event.SchedReqs{Thread: event.MustHave, Proc: event.MustHave, Goroutine: event.MayHave}
	if err := validateCtx(curCtx, reqs); err != nil {
		return curCtx, false, err
	}
	// If we have a goroutine, it must be running.
	if state, ok := o.gStates[curCtx.G]; ok && state.status != go122.GoRunning {
		return curCtx, false, fmt.Errorf("%s event for goroutine that's not %s", go122.EventString(ev.typ), GoRunning)
	}
	// This goroutine created another. Add a state for it.
	newgid := GoID(ev.args[0])
	if _, ok := o.gStates[newgid]; ok {
		return curCtx, false, fmt.Errorf("tried to create goroutine (%v) that already exists", newgid)
	}
	status := go122.GoRunnable
	if ev.typ == go122.EvGoCreateBlocked {
		status = go122.GoWaiting
	}
	o.gStates[newgid] = &gState{id: newgid, status: status, seq: makeSeq(gen, 0)}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGoStopExec(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// These are goroutine events that all require an active running
	// goroutine on some thread. They must *always* be advance-able,
	// since running goroutines are bound to their M.
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	state, ok := o.gStates[curCtx.G]
	if !ok {
		return curCtx, false, fmt.Errorf("event %s for goroutine (%v) that doesn't exist", go122.EventString(ev.typ), curCtx.G)
	}
	if state.status != go122.GoRunning {
		return curCtx, false, fmt.Errorf("%s event for goroutine that's not %s", go122.EventString(ev.typ), GoRunning)
	}
	// Handle each case slightly differently; we just group them together
	// because they have shared preconditions.
	newCtx := curCtx
	switch ev.typ {
	case go122.EvGoDestroy:
		// This goroutine is exiting itself.
		delete(o.gStates, curCtx.G)
		newCtx.G = NoGoroutine
	case go122.EvGoStop:
		// Goroutine stopped (yielded). It's runnable but not running on this M.
		state.status = go122.GoRunnable
		newCtx.G = NoGoroutine
	case go122.EvGoBlock:
		// Goroutine blocked. It's waiting now and not running on this M.
		state.status = go122.GoWaiting
		newCtx.G = NoGoroutine
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return newCtx, true, nil
}

func (o *ordering) advanceGoStart(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	gid := GoID(ev.args[0])
	seq := makeSeq(gen, ev.args[1])
	state, ok := o.gStates[gid]
	if !ok || state.status != go122.GoRunnable || !seq.succeeds(state.seq) {
		// We can't make an inference as to whether this is bad. We could just be seeing
		// a GoStart on a different M before the goroutine was created, before it had its
		// state emitted, or before we got to the right point in the trace yet.
		return curCtx, false, nil
	}
	// We can advance this goroutine. Check some invariants.
	reqs := event.SchedReqs{Thread: event.MustHave, Proc: event.MustHave, Goroutine: event.MustNotHave}
	if err := validateCtx(curCtx, reqs); err != nil {
		return curCtx, false, err
	}
	state.status = go122.GoRunning
	state.seq = seq
	newCtx := curCtx
	newCtx.G = gid
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return newCtx, true, nil
}

func (o *ordering) advanceGoUnblock(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// N.B. These both reference the goroutine to unblock, not the current goroutine.
	gid := GoID(ev.args[0])
	seq := makeSeq(gen, ev.args[1])
	state, ok := o.gStates[gid]
	if !ok || state.status != go122.GoWaiting || !seq.succeeds(state.seq) {
		// We can't make an inference as to whether this is bad. We could just be seeing
		// a GoUnblock on a different M before the goroutine was created and blocked itself,
		// before it had its state emitted, or before we got to the right point in the trace yet.
		return curCtx, false, nil
	}
	state.status = go122.GoRunnable
	state.seq = seq
	// N.B. No context to validate. Basically anything can unblock
	// a goroutine (e.g. sysmon).
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGoSwitch(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// GoSwitch and GoSwitchDestroy represent a trio of events:
	// - Unblock of the goroutine to switch to.
	// - Block or destroy of the current goroutine.
	// - Start executing the next goroutine.
	//
	// Because it acts like a GoStart for the next goroutine, we can
	// only advance it if the sequence numbers line up.
	//
	// The current goroutine on the thread must be actively running.
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	curGState, ok := o.gStates[curCtx.G]
	if !ok {
		return curCtx, false, fmt.Errorf("event %s for goroutine (%v) that doesn't exist", go122.EventString(ev.typ), curCtx.G)
	}
	if curGState.status != go122.GoRunning {
		return curCtx, false, fmt.Errorf("%s event for goroutine that's not %s", go122.EventString(ev.typ), GoRunning)
	}
	nextg := GoID(ev.args[0])
	seq := makeSeq(gen, ev.args[1]) // seq is for nextg, not curCtx.G.
	nextGState, ok := o.gStates[nextg]
	if !ok || nextGState.status != go122.GoWaiting || !seq.succeeds(nextGState.seq) {
		// We can't make an inference as to whether this is bad. We could just be seeing
		// a GoSwitch on a different M before the goroutine was created, before it had its
		// state emitted, or before we got to the right point in the trace yet.
		return curCtx, false, nil
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})

	// Update the state of the executing goroutine and emit an event for it
	// (GoSwitch and GoSwitchDestroy will be interpreted as GoUnblock events
	// for nextg).
	switch ev.typ {
	case go122.EvGoSwitch:
		// Goroutine blocked. It's waiting now and not running on this M.
		curGState.status = go122.GoWaiting

		// Emit a GoBlock event.
		// TODO(mknyszek): Emit a reason.
		o.queue.push(makeEvent(evt, curCtx, go122.EvGoBlock, ev.time, 0 /* no reason */, 0 /* no stack */))
	case go122.EvGoSwitchDestroy:
		// This goroutine is exiting itself.
		delete(o.gStates, curCtx.G)

		// Emit a GoDestroy event.
		o.queue.push(makeEvent(evt, curCtx, go122.EvGoDestroy, ev.time))
	}
	// Update the state of the next goroutine.
	nextGState.status = go122.GoRunning
	nextGState.seq = seq
	newCtx := curCtx
	newCtx.G = nextg

	// Queue an event for the next goroutine starting to run.
	startCtx := curCtx
	startCtx.G = NoGoroutine
	o.queue.push(makeEvent(evt, startCtx, go122.EvGoStart, ev.time, uint64(nextg), ev.args[1]))
	return newCtx, true, nil
}

func (o *ordering) advanceGoSyscallBegin(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// Entering a syscall requires an active running goroutine with a
	// proc on some thread. It is always advancable.
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	state, ok := o.gStates[curCtx.G]
	if !ok {
		return curCtx, false, fmt.Errorf("event %s for goroutine (%v) that doesn't exist", go122.EventString(ev.typ), curCtx.G)
	}
	if state.status != go122.GoRunning {
		return curCtx, false, fmt.Errorf("%s event for goroutine that's not %s", go122.EventString(ev.typ), GoRunning)
	}
	// Goroutine entered a syscall. It's still running on this P and M.
	state.status = go122.GoSyscall
	pState, ok := o.pStates[curCtx.P]
	if !ok {
		return curCtx, false, fmt.Errorf("uninitialized proc %d found during %s", curCtx.P, go122.EventString(ev.typ))
	}
	pState.status = go122.ProcSyscall
	// Validate the P sequence number on the event and advance it.
	//
	// We have a P sequence number for what is supposed to be a goroutine event
	// so that we can correctly model P stealing. Without this sequence number here,
	// the syscall from which a ProcSteal event is stealing can be ambiguous in the
	// face of broken timestamps. See the go122-syscall-steal-proc-ambiguous test for
	// more details.
	//
	// Note that because this sequence number only exists as a tool for disambiguation,
	// we can enforce that we have the right sequence number at this point; we don't need
	// to back off and see if any other events will advance. This is a running P.
	pSeq := makeSeq(gen, ev.args[0])
	if !pSeq.succeeds(pState.seq) {
		return curCtx, false, fmt.Errorf("failed to advance %s: can't make sequence: %s -> %s", go122.EventString(ev.typ), pState.seq, pSeq)
	}
	pState.seq = pSeq
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGoSyscallEnd(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// This event is always advance-able because it happens on the same
	// thread that EvGoSyscallStart happened, and the goroutine can't leave
	// that thread until its done.
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	state, ok := o.gStates[curCtx.G]
	if !ok {
		return curCtx, false, fmt.Errorf("event %s for goroutine (%v) that doesn't exist", go122.EventString(ev.typ), curCtx.G)
	}
	if state.status != go122.GoSyscall {
		return curCtx, false, fmt.Errorf("%s event for goroutine that's not %s", go122.EventString(ev.typ), GoRunning)
	}
	state.status = go122.GoRunning

	// Transfer the P back to running from syscall.
	pState, ok := o.pStates[curCtx.P]
	if !ok {
		return curCtx, false, fmt.Errorf("uninitialized proc %d found during %s", curCtx.P, go122.EventString(ev.typ))
	}
	if pState.status != go122.ProcSyscall {
		return curCtx, false, fmt.Errorf("expected proc %d in state %v, but got %v instead", curCtx.P, go122.ProcSyscall, pState.status)
	}
	pState.status = go122.ProcRunning
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGoSyscallEndBlocked(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// This event becomes advanceable when its P is not in a syscall state
	// (lack of a P altogether is also acceptable for advancing).
	// The transfer out of ProcSyscall can happen either voluntarily via
	// ProcStop or involuntarily via ProcSteal. We may also acquire a new P
	// before we get here (after the transfer out) but that's OK: that new
	// P won't be in the ProcSyscall state anymore.
	//
	// Basically: while we have a preemptible P, don't advance, because we
	// *know* from the event that we're going to lose it at some point during
	// the syscall. We shouldn't advance until that happens.
	if curCtx.P != NoProc {
		pState, ok := o.pStates[curCtx.P]
		if !ok {
			return curCtx, false, fmt.Errorf("uninitialized proc %d found during %s", curCtx.P, go122.EventString(ev.typ))
		}
		if pState.status == go122.ProcSyscall {
			return curCtx, false, nil
		}
	}
	// As mentioned above, we may have a P here if we ProcStart
	// before this event.
	if err := validateCtx(curCtx, event.SchedReqs{Thread: event.MustHave, Proc: event.MayHave, Goroutine: event.MustHave}); err != nil {
		return curCtx, false, err
	}
	state, ok := o.gStates[curCtx.G]
	if !ok {
		return curCtx, false, fmt.Errorf("event %s for goroutine (%v) that doesn't exist", go122.EventString(ev.typ), curCtx.G)
	}
	if state.status != go122.GoSyscall {
		return curCtx, false, fmt.Errorf("%s event for goroutine that's not %s", go122.EventString(ev.typ), GoRunning)
	}
	newCtx := curCtx
	newCtx.G = NoGoroutine
	state.status = go122.GoRunnable
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return newCtx, true, nil
}

func (o *ordering) advanceGoCreateSyscall(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// This event indicates that a goroutine is effectively
	// being created out of a cgo callback. Such a goroutine
	// is 'created' in the syscall state.
	if err := validateCtx(curCtx, event.SchedReqs{Thread: event.MustHave, Proc: event.MayHave, Goroutine: event.MustNotHave}); err != nil {
		return curCtx, false, err
	}
	// This goroutine is effectively being created. Add a state for it.
	newgid := GoID(ev.args[0])
	if _, ok := o.gStates[newgid]; ok {
		return curCtx, false, fmt.Errorf("tried to create goroutine (%v) in syscall that already exists", newgid)
	}
	o.gStates[newgid] = &gState{id: newgid, status: go122.GoSyscall, seq: makeSeq(gen, 0)}
	// Goroutine is executing. Bind it to the context.
	newCtx := curCtx
	newCtx.G = newgid
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return newCtx, true, nil
}

func (o *ordering) advanceGoDestroySyscall(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// This event indicates that a goroutine created for a
	// cgo callback is disappearing, either because the callback
	// ending or the C thread that called it is being destroyed.
	//
	// Also, treat this as if we lost our P too.
	// The thread ID may be reused by the platform and we'll get
	// really confused if we try to steal the P is this is running
	// with later. The new M with the same ID could even try to
	// steal back this P from itself!
	//
	// The runtime is careful to make sure that any GoCreateSyscall
	// event will enter the runtime emitting events for reacquiring a P.
	//
	// Note: we might have a P here. The P might not be released
	// eagerly by the runtime, and it might get stolen back later
	// (or never again, if the program is going to exit).
	if err := validateCtx(curCtx, event.SchedReqs{Thread: event.MustHave, Proc: event.MayHave, Goroutine: event.MustHave}); err != nil {
		return curCtx, false, err
	}
	// Check to make sure the goroutine exists in the right state.
	state, ok := o.gStates[curCtx.G]
	if !ok {
		return curCtx, false, fmt.Errorf("event %s for goroutine (%v) that doesn't exist", go122.EventString(ev.typ), curCtx.G)
	}
	if state.status != go122.GoSyscall {
		return curCtx, false, fmt.Errorf("%s event for goroutine that's not %v", go122.EventString(ev.typ), GoSyscall)
	}
	// This goroutine is exiting itself.
	delete(o.gStates, curCtx.G)
	newCtx := curCtx
	newCtx.G = NoGoroutine

	// If we have a proc, then we're dissociating from it now. See the comment at the top of the case.
	if curCtx.P != NoProc {
		pState, ok := o.pStates[curCtx.P]
		if !ok {
			return curCtx, false, fmt.Errorf("found invalid proc %d during %s", curCtx.P, go122.EventString(ev.typ))
		}
		if pState.status != go122.ProcSyscall {
			return curCtx, false, fmt.Errorf("proc %d in unexpected state %s during %s", curCtx.P, pState.status, go122.EventString(ev.typ))
		}
		// See the go122-create-syscall-reuse-thread-id test case for more details.
		pState.status = go122.ProcSyscallAbandoned
		newCtx.P = NoProc

		// Queue an extra self-ProcSteal event.
		extra := makeEvent(evt, curCtx, go122.EvProcSteal, ev.time, uint64(curCtx.P))
		extra.base.extra(version.Go122)[0] = uint64(go122.ProcSyscall)
		o.queue.push(extra)
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return newCtx, true, nil
}

func (o *ordering) advanceUserTaskBegin(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// Handle tasks. Tasks are interesting because:
	// - There's no Begin event required to reference a task.
	// - End for a particular task ID can appear multiple times.
	// As a result, there's very little to validate. The only
	// thing we have to be sure of is that a task didn't begin
	// after it had already begun. Task IDs are allowed to be
	// reused, so we don't care about a Begin after an End.
	id := TaskID(ev.args[0])
	if _, ok := o.activeTasks[id]; ok {
		return curCtx, false, fmt.Errorf("task ID conflict: %d", id)
	}
	// Get the parent ID, but don't validate it. There's no guarantee
	// we actually have information on whether it's active.
	parentID := TaskID(ev.args[1])
	if parentID == BackgroundTask {
		// Note: a value of 0 here actually means no parent, *not* the
		// background task. Automatic background task attachment only
		// applies to regions.
		parentID = NoTask
		ev.args[1] = uint64(NoTask)
	}

	// Validate the name and record it. We'll need to pass it through to
	// EvUserTaskEnd.
	nameID := stringID(ev.args[2])
	name, ok := evt.strings.get(nameID)
	if !ok {
		return curCtx, false, fmt.Errorf("invalid string ID %v for %v event", nameID, ev.typ)
	}
	o.activeTasks[id] = taskState{name: name, parentID: parentID}
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceUserTaskEnd(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	id := TaskID(ev.args[0])
	if ts, ok := o.activeTasks[id]; ok {
		// Smuggle the task info. This may happen in a different generation,
		// which may not have the name in its string table. Add it to the extra
		// strings table so we can look it up later.
		ev.extra(version.Go122)[0] = uint64(ts.parentID)
		ev.extra(version.Go122)[1] = uint64(evt.addExtraString(ts.name))
		delete(o.activeTasks, id)
	} else {
		// Explicitly clear the task info.
		ev.extra(version.Go122)[0] = uint64(NoTask)
		ev.extra(version.Go122)[1] = uint64(evt.addExtraString(""))
	}
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceUserRegionBegin(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	tid := TaskID(ev.args[0])
	nameID := stringID(ev.args[1])
	name, ok := evt.strings.get(nameID)
	if !ok {
		return curCtx, false, fmt.Errorf("invalid string ID %v for %v event", nameID, ev.typ)
	}
	gState, ok := o.gStates[curCtx.G]
	if !ok {
		return curCtx, false, fmt.Errorf("encountered EvUserRegionBegin without known state for current goroutine %d", curCtx.G)
	}
	if err := gState.beginRegion(userRegion{tid, name}); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceUserRegionEnd(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	tid := TaskID(ev.args[0])
	nameID := stringID(ev.args[1])
	name, ok := evt.strings.get(nameID)
	if !ok {
		return curCtx, false, fmt.Errorf("invalid string ID %v for %v event", nameID, ev.typ)
	}
	gState, ok := o.gStates[curCtx.G]
	if !ok {
		return curCtx, false, fmt.Errorf("encountered EvUserRegionEnd without known state for current goroutine %d", curCtx.G)
	}
	if err := gState.endRegion(userRegion{tid, name}); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

// Handle the GC mark phase.
//
// We have sequence numbers for both start and end because they
// can happen on completely different threads. We want an explicit
// partial order edge between start and end here, otherwise we're
// relying entirely on timestamps to make sure we don't advance a
// GCEnd for a _different_ GC cycle if timestamps are wildly broken.
func (o *ordering) advanceGCActive(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	seq := ev.args[0]
	if gen == o.initialGen {
		if o.gcState != gcUndetermined {
			return curCtx, false, fmt.Errorf("GCActive in the first generation isn't first GC event")
		}
		o.gcSeq = seq
		o.gcState = gcRunning
		o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
		return curCtx, true, nil
	}
	if seq != o.gcSeq+1 {
		// This is not the right GC cycle.
		return curCtx, false, nil
	}
	if o.gcState != gcRunning {
		return curCtx, false, fmt.Errorf("encountered GCActive while GC was not in progress")
	}
	o.gcSeq = seq
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGCBegin(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	seq := ev.args[0]
	if o.gcState == gcUndetermined {
		o.gcSeq = seq
		o.gcState = gcRunning
		o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
		return curCtx, true, nil
	}
	if seq != o.gcSeq+1 {
		// This is not the right GC cycle.
		return curCtx, false, nil
	}
	if o.gcState == gcRunning {
		return curCtx, false, fmt.Errorf("encountered GCBegin while GC was already in progress")
	}
	o.gcSeq = seq
	o.gcState = gcRunning
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGCEnd(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	seq := ev.args[0]
	if seq != o.gcSeq+1 {
		// This is not the right GC cycle.
		return curCtx, false, nil
	}
	if o.gcState == gcNotRunning {
		return curCtx, false, fmt.Errorf("encountered GCEnd when GC was not in progress")
	}
	if o.gcState == gcUndetermined {
		return curCtx, false, fmt.Errorf("encountered GCEnd when GC was in an undetermined state")
	}
	o.gcSeq = seq
	o.gcState = gcNotRunning
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceAnnotation(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// Handle simple instantaneous events that require a G.
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceHeapMetric(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// Handle allocation metrics, which don't require a G.
	if err := validateCtx(curCtx, event.SchedReqs{Thread: event.MustHave, Proc: event.MustHave, Goroutine: event.MayHave}); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGCSweepBegin(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// Handle sweep, which is bound to a P and doesn't require a G.
	if err := validateCtx(curCtx, event.SchedReqs{Thread: event.MustHave, Proc: event.MustHave, Goroutine: event.MayHave}); err != nil {
		return curCtx, false, err
	}
	if err := o.pStates[curCtx.P].beginRange(makeRangeType(ev.typ, 0)); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGCSweepActive(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	pid := ProcID(ev.args[0])
	// N.B. In practice Ps can't block while they're sweeping, so this can only
	// ever reference curCtx.P. However, be lenient about this like we are with
	// GCMarkAssistActive; there's no reason the runtime couldn't change to block
	// in the middle of a sweep.
	pState, ok := o.pStates[pid]
	if !ok {
		return curCtx, false, fmt.Errorf("encountered GCSweepActive for unknown proc %d", pid)
	}
	if err := pState.activeRange(makeRangeType(ev.typ, 0), gen == o.initialGen); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGCSweepEnd(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	if err := validateCtx(curCtx, event.SchedReqs{Thread: event.MustHave, Proc: event.MustHave, Goroutine: event.MayHave}); err != nil {
		return curCtx, false, err
	}
	_, err := o.pStates[curCtx.P].endRange(ev.typ)
	if err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGoRangeBegin(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	// Handle special goroutine-bound event ranges.
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	desc := stringID(0)
	if ev.typ == go122.EvSTWBegin {
		desc = stringID(ev.args[0])
	}
	gState, ok := o.gStates[curCtx.G]
	if !ok {
		return curCtx, false, fmt.Errorf("encountered event of type %d without known state for current goroutine %d", ev.typ, curCtx.G)
	}
	if err := gState.beginRange(makeRangeType(ev.typ, desc)); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGoRangeActive(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	gid := GoID(ev.args[0])
	// N.B. Like GoStatus, this can happen at any time, because it can
	// reference a non-running goroutine. Don't check anything about the
	// current scheduler context.
	gState, ok := o.gStates[gid]
	if !ok {
		return curCtx, false, fmt.Errorf("uninitialized goroutine %d found during %s", gid, go122.EventString(ev.typ))
	}
	if err := gState.activeRange(makeRangeType(ev.typ, 0), gen == o.initialGen); err != nil {
		return curCtx, false, err
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

func (o *ordering) advanceGoRangeEnd(ev *baseEvent, evt *evTable, m ThreadID, gen uint64, curCtx schedCtx) (schedCtx, bool, error) {
	if err := validateCtx(curCtx, event.UserGoReqs); err != nil {
		return curCtx, false, err
	}
	gState, ok := o.gStates[curCtx.G]
	if !ok {
		return curCtx, false, fmt.Errorf("encountered event of type %d without known state for current goroutine %d", ev.typ, curCtx.G)
	}
	desc, err := gState.endRange(ev.typ)
	if err != nil {
		return curCtx, false, err
	}
	if ev.typ == go122.EvSTWEnd {
		// Smuggle the kind into the event.
		// Don't use ev.extra here so we have symmetry with STWBegin.
		ev.args[0] = uint64(desc)
	}
	o.queue.push(Event{table: evt, ctx: curCtx, base: *ev})
	return curCtx, true, nil
}

// Next returns the next event in the ordering.
func (o *ordering) Next() (Event, bool) {
	return o.queue.pop()
}

// schedCtx represents the scheduling resources associated with an event.
type schedCtx struct {
	G GoID
	P ProcID
	M ThreadID
}

// validateCtx ensures that ctx conforms to some reqs, returning an error if
// it doesn't.
func validateCtx(ctx schedCtx, reqs event.SchedReqs) error {
	// Check thread requirements.
	if reqs.Thread == event.MustHave && ctx.M == NoThread {
		return fmt.Errorf("expected a thread but didn't have one")
	} else if reqs.Thread == event.MustNotHave && ctx.M != NoThread {
		return fmt.Errorf("expected no thread but had one")
	}

	// Check proc requirements.
	if reqs.Proc == event.MustHave && ctx.P == NoProc {
		return fmt.Errorf("expected a proc but didn't have one")
	} else if reqs.Proc == event.MustNotHave && ctx.P != NoProc {
		return fmt.Errorf("expected no proc but had one")
	}

	// Check goroutine requirements.
	if reqs.Goroutine == event.MustHave && ctx.G == NoGoroutine {
		return fmt.Errorf("expected a goroutine but didn't have one")
	} else if reqs.Goroutine == event.MustNotHave && ctx.G != NoGoroutine {
		return fmt.Errorf("expected no goroutine but had one")
	}
	return nil
}

// gcState is a trinary variable for the current state of the GC.
//
// The third state besides "enabled" and "disabled" is "undetermined."
type gcState uint8

const (
	gcUndetermined gcState = iota
	gcNotRunning
	gcRunning
)

// String returns a human-readable string for the GC state.
func (s gcState) String() string {
	switch s {
	case gcUndetermined:
		return "Undetermined"
	case gcNotRunning:
		return "NotRunning"
	case gcRunning:
		return "Running"
	}
	return "Bad"
}

// userRegion represents a unique user region when attached to some gState.
type userRegion struct {
	// name must be a resolved string because the string ID for the same
	// string may change across generations, but we care about checking
	// the value itself.
	taskID TaskID
	name   string
}

// rangeType is a way to classify special ranges of time.
//
// These typically correspond 1:1 with "Begin" events, but
// they may have an optional subtype that describes the range
// in more detail.
type rangeType struct {
	typ  event.Type // "Begin" event.
	desc stringID   // Optional subtype.
}

// makeRangeType constructs a new rangeType.
func makeRangeType(typ event.Type, desc stringID) rangeType {
	if styp := go122.Specs()[typ].StartEv; styp != go122.EvNone {
		typ = styp
	}
	return rangeType{typ, desc}
}

// gState is the state of a goroutine at a point in the trace.
type gState struct {
	id     GoID
	status go122.GoStatus
	seq    seqCounter

	// regions are the active user regions for this goroutine.
	regions []userRegion

	// rangeState is the state of special time ranges bound to this goroutine.
	rangeState
}

// beginRegion starts a user region on the goroutine.
func (s *gState) beginRegion(r userRegion) error {
	s.regions = append(s.regions, r)
	return nil
}

// endRegion ends a user region on the goroutine.
func (s *gState) endRegion(r userRegion) error {
	if len(s.regions) == 0 {
		// We do not know about regions that began before tracing started.
		return nil
	}
	if next := s.regions[len(s.regions)-1]; next != r {
		return fmt.Errorf("misuse of region in goroutine %v: region end %v when the inner-most active region start event is %v", s.id, r, next)
	}
	s.regions = s.regions[:len(s.regions)-1]
	return nil
}

// pState is the state of a proc at a point in the trace.
type pState struct {
	id     ProcID
	status go122.ProcStatus
	seq    seqCounter

	// rangeState is the state of special time ranges bound to this proc.
	rangeState
}

// mState is the state of a thread at a point in the trace.
type mState struct {
	g GoID   // Goroutine bound to this M. (The goroutine's state is Executing.)
	p ProcID // Proc bound to this M. (The proc's state is Executing.)
}

// rangeState represents the state of special time ranges.
type rangeState struct {
	// inFlight contains the rangeTypes of any ranges bound to a resource.
	inFlight []rangeType
}

// beginRange begins a special range in time on the goroutine.
//
// Returns an error if the range is already in progress.
func (s *rangeState) beginRange(typ rangeType) error {
	if s.hasRange(typ) {
		return fmt.Errorf("discovered event already in-flight for when starting event %v", go122.Specs()[typ.typ].Name)
	}
	s.inFlight = append(s.inFlight, typ)
	return nil
}

// activeRange marks special range in time on the goroutine as active in the
// initial generation, or confirms that it is indeed active in later generations.
func (s *rangeState) activeRange(typ rangeType, isInitialGen bool) error {
	if isInitialGen {
		if s.hasRange(typ) {
			return fmt.Errorf("found named active range already in first gen: %v", typ)
		}
		s.inFlight = append(s.inFlight, typ)
	} else if !s.hasRange(typ) {
		return fmt.Errorf("resource is missing active range: %v %v", go122.Specs()[typ.typ].Name, s.inFlight)
	}
	return nil
}

// hasRange returns true if a special time range on the goroutine as in progress.
func (s *rangeState) hasRange(typ rangeType) bool {
	for _, ftyp := range s.inFlight {
		if ftyp == typ {
			return true
		}
	}
	return false
}

// endsRange ends a special range in time on the goroutine.
//
// This must line up with the start event type  of the range the goroutine is currently in.
func (s *rangeState) endRange(typ event.Type) (stringID, error) {
	st := go122.Specs()[typ].StartEv
	idx := -1
	for i, r := range s.inFlight {
		if r.typ == st {
			idx = i
			break
		}
	}
	if idx < 0 {
		return 0, fmt.Errorf("tried to end event %v, but not in-flight", go122.Specs()[st].Name)
	}
	// Swap remove.
	desc := s.inFlight[idx].desc
	s.inFlight[idx], s.inFlight[len(s.inFlight)-1] = s.inFlight[len(s.inFlight)-1], s.inFlight[idx]
	s.inFlight = s.inFlight[:len(s.inFlight)-1]
	return desc, nil
}

// seqCounter represents a global sequence counter for a resource.
type seqCounter struct {
	gen uint64 // The generation for the local sequence counter seq.
	seq uint64 // The sequence number local to the generation.
}

// makeSeq creates a new seqCounter.
func makeSeq(gen, seq uint64) seqCounter {
	return seqCounter{gen: gen, seq: seq}
}

// succeeds returns true if a is the immediate successor of b.
func (a seqCounter) succeeds(b seqCounter) bool {
	return a.gen == b.gen && a.seq == b.seq+1
}

// String returns a debug string representation of the seqCounter.
func (c seqCounter) String() string {
	return fmt.Sprintf("%d (gen=%d)", c.seq, c.gen)
}

func dumpOrdering(order *ordering) string {
	var sb strings.Builder
	for id, state := range order.gStates {
		fmt.Fprintf(&sb, "G %d [status=%s seq=%s]\n", id, state.status, state.seq)
	}
	fmt.Fprintln(&sb)
	for id, state := range order.pStates {
		fmt.Fprintf(&sb, "P %d [status=%s seq=%s]\n", id, state.status, state.seq)
	}
	fmt.Fprintln(&sb)
	for id, state := range order.mStates {
		fmt.Fprintf(&sb, "M %d [g=%d p=%d]\n", id, state.g, state.p)
	}
	fmt.Fprintln(&sb)
	fmt.Fprintf(&sb, "GC %d %s\n", order.gcSeq, order.gcState)
	return sb.String()
}

// taskState represents an active task.
type taskState struct {
	// name is the type of the active task.
	name string

	// parentID is the parent ID of the active task.
	parentID TaskID
}

// queue implements a growable ring buffer with a queue API.
type queue[T any] struct {
	start, end int
	buf        []T
}

// push adds a new event to the back of the queue.
func (q *queue[T]) push(value T) {
	if q.end-q.start == len(q.buf) {
		q.grow()
	}
	q.buf[q.end%len(q.buf)] = value
	q.end++
}

// grow increases the size of the queue.
func (q *queue[T]) grow() {
	if len(q.buf) == 0 {
		q.buf = make([]T, 2)
		return
	}

	// Create new buf and copy data over.
	newBuf := make([]T, len(q.buf)*2)
	pivot := q.start % len(q.buf)
	first, last := q.buf[pivot:], q.buf[:pivot]
	copy(newBuf[:len(first)], first)
	copy(newBuf[len(first):], last)

	// Update the queue state.
	q.start = 0
	q.end = len(q.buf)
	q.buf = newBuf
}

// pop removes an event from the front of the queue. If the
// queue is empty, it returns an EventBad event.
func (q *queue[T]) pop() (T, bool) {
	if q.end-q.start == 0 {
		return *new(T), false
	}
	elem := &q.buf[q.start%len(q.buf)]
	value := *elem
	*elem = *new(T) // Clear the entry before returning, so we don't hold onto old tables.
	q.start++
	return value, true
}

// makeEvent creates an Event from the provided information.
//
// It's just a convenience function; it's always OK to construct
// an Event manually if this isn't quite the right way to express
// the contents of the event.
func makeEvent(table *evTable, ctx schedCtx, typ event.Type, time Time, args ...uint64) Event {
	ev := Event{
		table: table,
		ctx:   ctx,
		base: baseEvent{
			typ:  typ,
			time: time,
		},
	}
	copy(ev.base.args[:], args)
	return ev
}
