aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/runtime2.go
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2024-06-11 11:02:18 -0700
committerDamien Neil <dneil@google.com>2024-11-19 19:40:40 +0000
commitd90ce588eac7b9105c0ca556a7c6e975fd5c1eca (patch)
tree4692a7f87738058c89bba874fe6d53b82786c44a /src/runtime/runtime2.go
parent944df9a7516021f0405cd8adb1e6894ae9872cb5 (diff)
downloadgo-d90ce588eac7b9105c0ca556a7c6e975fd5c1eca.tar.xz
internal/synctest: new package for testing concurrent code
Add an internal (for now) implementation of testing/synctest. The synctest.Run function executes a tree of goroutines in an isolated environment using a fake clock. The synctest.Wait function allows a test to wait for all other goroutines within the test to reach a blocking point. For #67434 For #69687 Change-Id: Icb39e54c54cece96517e58ef9cfb18bf68506cfc Reviewed-on: https://go-review.googlesource.com/c/go/+/591997 Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/runtime/runtime2.go')
-rw-r--r--src/runtime/runtime2.go35
1 files changed, 34 insertions, 1 deletions
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 03798d5699..e837c28af8 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -489,7 +489,8 @@ type g struct {
// current in-progress goroutine profile
goroutineProfiled goroutineProfileStateHolder
- coroarg *coro // argument during coroutine transfers
+ coroarg *coro // argument during coroutine transfers
+ syncGroup *synctestGroup
// Per-G tracer state.
trace gTraceState
@@ -1064,6 +1065,7 @@ const (
waitReasonSyncMutexLock // "sync.Mutex.Lock"
waitReasonSyncRWMutexRLock // "sync.RWMutex.RLock"
waitReasonSyncRWMutexLock // "sync.RWMutex.Lock"
+ waitReasonSyncWaitGroupWait // "sync.WaitGroup.Wait"
waitReasonTraceReaderBlocked // "trace reader (blocked)"
waitReasonWaitForGCCycle // "wait for GC cycle"
waitReasonGCWorkerIdle // "GC worker (idle)"
@@ -1078,6 +1080,11 @@ const (
waitReasonPageTraceFlush // "page trace flush"
waitReasonCoroutine // "coroutine"
waitReasonGCWeakToStrongWait // "GC weak to strong wait"
+ waitReasonSynctestRun // "synctest.Run"
+ waitReasonSynctestWait // "synctest.Wait"
+ waitReasonSynctestChanReceive // "chan receive (synctest)"
+ waitReasonSynctestChanSend // "chan send (synctest)"
+ waitReasonSynctestSelect // "select (synctest)"
)
var waitReasonStrings = [...]string{
@@ -1105,6 +1112,7 @@ var waitReasonStrings = [...]string{
waitReasonSyncMutexLock: "sync.Mutex.Lock",
waitReasonSyncRWMutexRLock: "sync.RWMutex.RLock",
waitReasonSyncRWMutexLock: "sync.RWMutex.Lock",
+ waitReasonSyncWaitGroupWait: "sync.WaitGroup.Wait",
waitReasonTraceReaderBlocked: "trace reader (blocked)",
waitReasonWaitForGCCycle: "wait for GC cycle",
waitReasonGCWorkerIdle: "GC worker (idle)",
@@ -1119,6 +1127,11 @@ var waitReasonStrings = [...]string{
waitReasonPageTraceFlush: "page trace flush",
waitReasonCoroutine: "coroutine",
waitReasonGCWeakToStrongWait: "GC weak to strong wait",
+ waitReasonSynctestRun: "synctest.Run",
+ waitReasonSynctestWait: "synctest.Wait",
+ waitReasonSynctestChanReceive: "chan receive (synctest)",
+ waitReasonSynctestChanSend: "chan send (synctest)",
+ waitReasonSynctestSelect: "select (synctest)",
}
func (w waitReason) String() string {
@@ -1157,6 +1170,26 @@ var isWaitingForGC = [len(waitReasonStrings)]bool{
waitReasonFlushProcCaches: true,
}
+func (w waitReason) isIdleInSynctest() bool {
+ return isIdleInSynctest[w]
+}
+
+// isIdleInSynctest indicates that a goroutine is considered idle by synctest.Wait.
+var isIdleInSynctest = [len(waitReasonStrings)]bool{
+ waitReasonChanReceiveNilChan: true,
+ waitReasonChanSendNilChan: true,
+ waitReasonSelectNoCases: true,
+ waitReasonSleep: true,
+ waitReasonSyncCondWait: true,
+ waitReasonSyncWaitGroupWait: true,
+ waitReasonCoroutine: true,
+ waitReasonSynctestRun: true,
+ waitReasonSynctestWait: true,
+ waitReasonSynctestChanReceive: true,
+ waitReasonSynctestChanSend: true,
+ waitReasonSynctestSelect: true,
+}
+
var (
allm *m
gomaxprocs int32