@@ -246,7 +246,7 @@ func (o *ordering) advanceProcStart(ev *baseEvent, evt *evTable, m ThreadID, gen
246
246
// We can advance this P. Check some invariants.
247
247
//
248
248
// We might have a goroutine if a goroutine is exiting a syscall.
249
- reqs := event. SchedReqs { Thread : event . MustHave , Proc : event . MustNotHave , Goroutine : event . MayHave }
249
+ reqs := schedReqs { M : mustHave , P : mustNotHave , G : mayHave }
250
250
if err := validateCtx (curCtx , reqs ); err != nil {
251
251
return curCtx , false , err
252
252
}
@@ -275,7 +275,7 @@ func (o *ordering) advanceProcStop(ev *baseEvent, evt *evTable, m ThreadID, gen
275
275
if state .status != go122 .ProcRunning && state .status != go122 .ProcSyscall {
276
276
return curCtx , false , fmt .Errorf ("%s event for proc that's not %s or %s" , go122 .EventString (ev .typ ), go122 .ProcRunning , go122 .ProcSyscall )
277
277
}
278
- reqs := event. SchedReqs { Thread : event . MustHave , Proc : event . MustHave , Goroutine : event . MayHave }
278
+ reqs := schedReqs { M : mustHave , P : mustHave , G : mayHave }
279
279
if err := validateCtx (curCtx , reqs ); err != nil {
280
280
return curCtx , false , err
281
281
}
@@ -297,7 +297,7 @@ func (o *ordering) advanceProcSteal(ev *baseEvent, evt *evTable, m ThreadID, gen
297
297
return curCtx , false , nil
298
298
}
299
299
// We can advance this P. Check some invariants.
300
- reqs := event. SchedReqs { Thread : event . MustHave , Proc : event . MayHave , Goroutine : event . MayHave }
300
+ reqs := schedReqs { M : mustHave , P : mayHave , G : mayHave }
301
301
if err := validateCtx (curCtx , reqs ); err != nil {
302
302
return curCtx , false , err
303
303
}
@@ -437,7 +437,7 @@ func (o *ordering) advanceGoStatus(ev *baseEvent, evt *evTable, m ThreadID, gen
437
437
func (o * ordering ) advanceGoCreate (ev * baseEvent , evt * evTable , m ThreadID , gen uint64 , curCtx schedCtx ) (schedCtx , bool , error ) {
438
438
// Goroutines must be created on a running P, but may or may not be created
439
439
// by a running goroutine.
440
- reqs := event. SchedReqs { Thread : event . MustHave , Proc : event . MustHave , Goroutine : event . MayHave }
440
+ reqs := schedReqs { M : mustHave , P : mustHave , G : mayHave }
441
441
if err := validateCtx (curCtx , reqs ); err != nil {
442
442
return curCtx , false , err
443
443
}
@@ -463,7 +463,7 @@ func (o *ordering) advanceGoStopExec(ev *baseEvent, evt *evTable, m ThreadID, ge
463
463
// These are goroutine events that all require an active running
464
464
// goroutine on some thread. They must *always* be advance-able,
465
465
// since running goroutines are bound to their M.
466
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
466
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
467
467
return curCtx , false , err
468
468
}
469
469
state , ok := o .gStates [curCtx .G ]
@@ -505,7 +505,7 @@ func (o *ordering) advanceGoStart(ev *baseEvent, evt *evTable, m ThreadID, gen u
505
505
return curCtx , false , nil
506
506
}
507
507
// We can advance this goroutine. Check some invariants.
508
- reqs := event. SchedReqs { Thread : event . MustHave , Proc : event . MustHave , Goroutine : event . MustNotHave }
508
+ reqs := schedReqs { M : mustHave , P : mustHave , G : mustNotHave }
509
509
if err := validateCtx (curCtx , reqs ); err != nil {
510
510
return curCtx , false , err
511
511
}
@@ -546,7 +546,7 @@ func (o *ordering) advanceGoSwitch(ev *baseEvent, evt *evTable, m ThreadID, gen
546
546
// only advance it if the sequence numbers line up.
547
547
//
548
548
// The current goroutine on the thread must be actively running.
549
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
549
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
550
550
return curCtx , false , err
551
551
}
552
552
curGState , ok := o .gStates [curCtx .G ]
@@ -601,7 +601,7 @@ func (o *ordering) advanceGoSwitch(ev *baseEvent, evt *evTable, m ThreadID, gen
601
601
func (o * ordering ) advanceGoSyscallBegin (ev * baseEvent , evt * evTable , m ThreadID , gen uint64 , curCtx schedCtx ) (schedCtx , bool , error ) {
602
602
// Entering a syscall requires an active running goroutine with a
603
603
// proc on some thread. It is always advancable.
604
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
604
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
605
605
return curCtx , false , err
606
606
}
607
607
state , ok := o .gStates [curCtx .G ]
@@ -642,7 +642,7 @@ func (o *ordering) advanceGoSyscallEnd(ev *baseEvent, evt *evTable, m ThreadID,
642
642
// This event is always advance-able because it happens on the same
643
643
// thread that EvGoSyscallStart happened, and the goroutine can't leave
644
644
// that thread until its done.
645
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
645
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
646
646
return curCtx , false , err
647
647
}
648
648
state , ok := o .gStates [curCtx .G ]
@@ -689,7 +689,7 @@ func (o *ordering) advanceGoSyscallEndBlocked(ev *baseEvent, evt *evTable, m Thr
689
689
}
690
690
// As mentioned above, we may have a P here if we ProcStart
691
691
// before this event.
692
- if err := validateCtx (curCtx , event. SchedReqs { Thread : event . MustHave , Proc : event . MayHave , Goroutine : event . MustHave }); err != nil {
692
+ if err := validateCtx (curCtx , schedReqs { M : mustHave , P : mayHave , G : mustHave }); err != nil {
693
693
return curCtx , false , err
694
694
}
695
695
state , ok := o .gStates [curCtx .G ]
@@ -710,7 +710,7 @@ func (o *ordering) advanceGoCreateSyscall(ev *baseEvent, evt *evTable, m ThreadI
710
710
// This event indicates that a goroutine is effectively
711
711
// being created out of a cgo callback. Such a goroutine
712
712
// is 'created' in the syscall state.
713
- if err := validateCtx (curCtx , event. SchedReqs { Thread : event . MustHave , Proc : event . MayHave , Goroutine : event . MustNotHave }); err != nil {
713
+ if err := validateCtx (curCtx , schedReqs { M : mustHave , P : mayHave , G : mustNotHave }); err != nil {
714
714
return curCtx , false , err
715
715
}
716
716
// This goroutine is effectively being created. Add a state for it.
@@ -743,7 +743,7 @@ func (o *ordering) advanceGoDestroySyscall(ev *baseEvent, evt *evTable, m Thread
743
743
// Note: we might have a P here. The P might not be released
744
744
// eagerly by the runtime, and it might get stolen back later
745
745
// (or never again, if the program is going to exit).
746
- if err := validateCtx (curCtx , event. SchedReqs { Thread : event . MustHave , Proc : event . MayHave , Goroutine : event . MustHave }); err != nil {
746
+ if err := validateCtx (curCtx , schedReqs { M : mustHave , P : mayHave , G : mustHave }); err != nil {
747
747
return curCtx , false , err
748
748
}
749
749
// Check to make sure the goroutine exists in the right state.
@@ -812,7 +812,7 @@ func (o *ordering) advanceUserTaskBegin(ev *baseEvent, evt *evTable, m ThreadID,
812
812
return curCtx , false , fmt .Errorf ("invalid string ID %v for %v event" , nameID , ev .typ )
813
813
}
814
814
o .activeTasks [id ] = taskState {name : name , parentID : parentID }
815
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
815
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
816
816
return curCtx , false , err
817
817
}
818
818
o .queue .push (Event {table : evt , ctx : curCtx , base : * ev })
@@ -833,15 +833,15 @@ func (o *ordering) advanceUserTaskEnd(ev *baseEvent, evt *evTable, m ThreadID, g
833
833
ev .extra (version .Go122 )[0 ] = uint64 (NoTask )
834
834
ev .extra (version .Go122 )[1 ] = uint64 (evt .addExtraString ("" ))
835
835
}
836
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
836
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
837
837
return curCtx , false , err
838
838
}
839
839
o .queue .push (Event {table : evt , ctx : curCtx , base : * ev })
840
840
return curCtx , true , nil
841
841
}
842
842
843
843
func (o * ordering ) advanceUserRegionBegin (ev * baseEvent , evt * evTable , m ThreadID , gen uint64 , curCtx schedCtx ) (schedCtx , bool , error ) {
844
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
844
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
845
845
return curCtx , false , err
846
846
}
847
847
tid := TaskID (ev .args [0 ])
@@ -862,7 +862,7 @@ func (o *ordering) advanceUserRegionBegin(ev *baseEvent, evt *evTable, m ThreadI
862
862
}
863
863
864
864
func (o * ordering ) advanceUserRegionEnd (ev * baseEvent , evt * evTable , m ThreadID , gen uint64 , curCtx schedCtx ) (schedCtx , bool , error ) {
865
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
865
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
866
866
return curCtx , false , err
867
867
}
868
868
tid := TaskID (ev .args [0 ])
@@ -908,7 +908,7 @@ func (o *ordering) advanceGCActive(ev *baseEvent, evt *evTable, m ThreadID, gen
908
908
return curCtx , false , fmt .Errorf ("encountered GCActive while GC was not in progress" )
909
909
}
910
910
o .gcSeq = seq
911
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
911
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
912
912
return curCtx , false , err
913
913
}
914
914
o .queue .push (Event {table : evt , ctx : curCtx , base : * ev })
@@ -932,7 +932,7 @@ func (o *ordering) advanceGCBegin(ev *baseEvent, evt *evTable, m ThreadID, gen u
932
932
}
933
933
o .gcSeq = seq
934
934
o .gcState = gcRunning
935
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
935
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
936
936
return curCtx , false , err
937
937
}
938
938
o .queue .push (Event {table : evt , ctx : curCtx , base : * ev })
@@ -953,7 +953,7 @@ func (o *ordering) advanceGCEnd(ev *baseEvent, evt *evTable, m ThreadID, gen uin
953
953
}
954
954
o .gcSeq = seq
955
955
o .gcState = gcNotRunning
956
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
956
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
957
957
return curCtx , false , err
958
958
}
959
959
o .queue .push (Event {table : evt , ctx : curCtx , base : * ev })
@@ -962,7 +962,7 @@ func (o *ordering) advanceGCEnd(ev *baseEvent, evt *evTable, m ThreadID, gen uin
962
962
963
963
func (o * ordering ) advanceAnnotation (ev * baseEvent , evt * evTable , m ThreadID , gen uint64 , curCtx schedCtx ) (schedCtx , bool , error ) {
964
964
// Handle simple instantaneous events that require a G.
965
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
965
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
966
966
return curCtx , false , err
967
967
}
968
968
o .queue .push (Event {table : evt , ctx : curCtx , base : * ev })
@@ -971,7 +971,7 @@ func (o *ordering) advanceAnnotation(ev *baseEvent, evt *evTable, m ThreadID, ge
971
971
972
972
func (o * ordering ) advanceHeapMetric (ev * baseEvent , evt * evTable , m ThreadID , gen uint64 , curCtx schedCtx ) (schedCtx , bool , error ) {
973
973
// Handle allocation metrics, which don't require a G.
974
- if err := validateCtx (curCtx , event. SchedReqs { Thread : event . MustHave , Proc : event . MustHave , Goroutine : event . MayHave }); err != nil {
974
+ if err := validateCtx (curCtx , schedReqs { M : mustHave , P : mustHave , G : mayHave }); err != nil {
975
975
return curCtx , false , err
976
976
}
977
977
o .queue .push (Event {table : evt , ctx : curCtx , base : * ev })
@@ -980,7 +980,7 @@ func (o *ordering) advanceHeapMetric(ev *baseEvent, evt *evTable, m ThreadID, ge
980
980
981
981
func (o * ordering ) advanceGCSweepBegin (ev * baseEvent , evt * evTable , m ThreadID , gen uint64 , curCtx schedCtx ) (schedCtx , bool , error ) {
982
982
// Handle sweep, which is bound to a P and doesn't require a G.
983
- if err := validateCtx (curCtx , event. SchedReqs { Thread : event . MustHave , Proc : event . MustHave , Goroutine : event . MayHave }); err != nil {
983
+ if err := validateCtx (curCtx , schedReqs { M : mustHave , P : mustHave , G : mayHave }); err != nil {
984
984
return curCtx , false , err
985
985
}
986
986
if err := o .pStates [curCtx .P ].beginRange (makeRangeType (ev .typ , 0 )); err != nil {
@@ -1008,7 +1008,7 @@ func (o *ordering) advanceGCSweepActive(ev *baseEvent, evt *evTable, m ThreadID,
1008
1008
}
1009
1009
1010
1010
func (o * ordering ) advanceGCSweepEnd (ev * baseEvent , evt * evTable , m ThreadID , gen uint64 , curCtx schedCtx ) (schedCtx , bool , error ) {
1011
- if err := validateCtx (curCtx , event. SchedReqs { Thread : event . MustHave , Proc : event . MustHave , Goroutine : event . MayHave }); err != nil {
1011
+ if err := validateCtx (curCtx , schedReqs { M : mustHave , P : mustHave , G : mayHave }); err != nil {
1012
1012
return curCtx , false , err
1013
1013
}
1014
1014
_ , err := o .pStates [curCtx .P ].endRange (ev .typ )
@@ -1021,7 +1021,7 @@ func (o *ordering) advanceGCSweepEnd(ev *baseEvent, evt *evTable, m ThreadID, ge
1021
1021
1022
1022
func (o * ordering ) advanceGoRangeBegin (ev * baseEvent , evt * evTable , m ThreadID , gen uint64 , curCtx schedCtx ) (schedCtx , bool , error ) {
1023
1023
// Handle special goroutine-bound event ranges.
1024
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
1024
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
1025
1025
return curCtx , false , err
1026
1026
}
1027
1027
desc := stringID (0 )
@@ -1056,7 +1056,7 @@ func (o *ordering) advanceGoRangeActive(ev *baseEvent, evt *evTable, m ThreadID,
1056
1056
}
1057
1057
1058
1058
func (o * ordering ) advanceGoRangeEnd (ev * baseEvent , evt * evTable , m ThreadID , gen uint64 , curCtx schedCtx ) (schedCtx , bool , error ) {
1059
- if err := validateCtx (curCtx , event . UserGoReqs ); err != nil {
1059
+ if err := validateCtx (curCtx , userGoReqs ); err != nil {
1060
1060
return curCtx , false , err
1061
1061
}
1062
1062
gState , ok := o .gStates [curCtx .G ]
@@ -1078,7 +1078,7 @@ func (o *ordering) advanceGoRangeEnd(ev *baseEvent, evt *evTable, m ThreadID, ge
1078
1078
1079
1079
func (o * ordering ) advanceAllocFree (ev * baseEvent , evt * evTable , m ThreadID , gen uint64 , curCtx schedCtx ) (schedCtx , bool , error ) {
1080
1080
// Handle simple instantaneous events that may or may not have a P.
1081
- if err := validateCtx (curCtx , event. SchedReqs { Thread : event . MustHave , Proc : event . MayHave , Goroutine : event . MayHave }); err != nil {
1081
+ if err := validateCtx (curCtx , schedReqs { M : mustHave , P : mayHave , G : mayHave }); err != nil {
1082
1082
return curCtx , false , err
1083
1083
}
1084
1084
o .queue .push (Event {table : evt , ctx : curCtx , base : * ev })
@@ -1099,25 +1099,25 @@ type schedCtx struct {
1099
1099
1100
1100
// validateCtx ensures that ctx conforms to some reqs, returning an error if
1101
1101
// it doesn't.
1102
- func validateCtx (ctx schedCtx , reqs event. SchedReqs ) error {
1102
+ func validateCtx (ctx schedCtx , reqs schedReqs ) error {
1103
1103
// Check thread requirements.
1104
- if reqs .Thread == event . MustHave && ctx .M == NoThread {
1104
+ if reqs .M == mustHave && ctx .M == NoThread {
1105
1105
return fmt .Errorf ("expected a thread but didn't have one" )
1106
- } else if reqs .Thread == event . MustNotHave && ctx .M != NoThread {
1106
+ } else if reqs .M == mustNotHave && ctx .M != NoThread {
1107
1107
return fmt .Errorf ("expected no thread but had one" )
1108
1108
}
1109
1109
1110
1110
// Check proc requirements.
1111
- if reqs .Proc == event . MustHave && ctx .P == NoProc {
1111
+ if reqs .P == mustHave && ctx .P == NoProc {
1112
1112
return fmt .Errorf ("expected a proc but didn't have one" )
1113
- } else if reqs .Proc == event . MustNotHave && ctx .P != NoProc {
1113
+ } else if reqs .P == mustNotHave && ctx .P != NoProc {
1114
1114
return fmt .Errorf ("expected no proc but had one" )
1115
1115
}
1116
1116
1117
1117
// Check goroutine requirements.
1118
- if reqs .Goroutine == event . MustHave && ctx .G == NoGoroutine {
1118
+ if reqs .G == mustHave && ctx .G == NoGoroutine {
1119
1119
return fmt .Errorf ("expected a goroutine but didn't have one" )
1120
- } else if reqs .Goroutine == event . MustNotHave && ctx .G != NoGoroutine {
1120
+ } else if reqs .G == mustNotHave && ctx .G != NoGoroutine {
1121
1121
return fmt .Errorf ("expected no goroutine but had one" )
1122
1122
}
1123
1123
return nil
@@ -1393,3 +1393,24 @@ func makeEvent(table *evTable, ctx schedCtx, typ event.Type, time Time, args ...
1393
1393
copy (ev .base .args [:], args )
1394
1394
return ev
1395
1395
}
1396
+
1397
+ // schedReqs is a set of constraints on what the scheduling
1398
+ // context must look like.
1399
+ type schedReqs struct {
1400
+ M constraint
1401
+ P constraint
1402
+ G constraint
1403
+ }
1404
+
1405
+ // constraint represents a various presence requirements.
1406
+ type constraint uint8
1407
+
1408
+ const (
1409
+ mustNotHave constraint = iota
1410
+ mayHave
1411
+ mustHave
1412
+ )
1413
+
1414
+ // userGoReqs is a common requirement among events that are running
1415
+ // or are close to running user code.
1416
+ var userGoReqs = schedReqs {M : mustHave , P : mustHave , G : mustHave }
0 commit comments