aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/export_test.go6
-rw-r--r--src/runtime/synctest.go29
-rw-r--r--src/runtime/synctest_test.go12
3 files changed, 39 insertions, 8 deletions
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index a9cc767e30..83cf301be4 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -1911,3 +1911,9 @@ func (b BitCursor) Write(data *byte, cnt uintptr) {
func (b BitCursor) Offset(cnt uintptr) BitCursor {
return BitCursor{b: b.b.offset(cnt)}
}
+
+const (
+ BubbleAssocUnbubbled = bubbleAssocUnbubbled
+ BubbleAssocCurrentBubble = bubbleAssocCurrentBubble
+ BubbleAssocOtherBubble = bubbleAssocOtherBubble
+)
diff --git a/src/runtime/synctest.go b/src/runtime/synctest.go
index 08a0e5d444..16af1209b4 100644
--- a/src/runtime/synctest.go
+++ b/src/runtime/synctest.go
@@ -363,6 +363,13 @@ type specialBubble struct {
bubbleid uint64
}
+// Keep these in sync with internal/synctest.
+const (
+ bubbleAssocUnbubbled = iota // not associated with any bubble
+ bubbleAssocCurrentBubble // associated with the current bubble
+ bubbleAssocOtherBubble // associated with a different bubble
+)
+
// getOrSetBubbleSpecial checks the special record for p's bubble membership.
//
// If add is true and p is not associated with any bubble,
@@ -371,10 +378,12 @@ type specialBubble struct {
// It returns ok==true if p is associated with bubbleid
// (including if a new association was added),
// and ok==false if not.
-func getOrSetBubbleSpecial(p unsafe.Pointer, bubbleid uint64, add bool) (ok bool) {
+func getOrSetBubbleSpecial(p unsafe.Pointer, bubbleid uint64, add bool) (assoc int) {
span := spanOfHeap(uintptr(p))
if span == nil {
- throw("getOrSetBubbleSpecial on invalid pointer")
+ // This is probably a package var.
+ // We can't attach a special to it, so always consider it unbubbled.
+ return bubbleAssocUnbubbled
}
// Ensure that the span is swept.
@@ -393,7 +402,11 @@ func getOrSetBubbleSpecial(p unsafe.Pointer, bubbleid uint64, add bool) (ok bool
// p is already associated with a bubble.
// Return true iff it's the same bubble.
s := (*specialBubble)((unsafe.Pointer)(*iter))
- ok = s.bubbleid == bubbleid
+ if s.bubbleid == bubbleid {
+ assoc = bubbleAssocCurrentBubble
+ } else {
+ assoc = bubbleAssocOtherBubble
+ }
} else if add {
// p is not associated with a bubble,
// and we've been asked to add an association.
@@ -404,23 +417,23 @@ func getOrSetBubbleSpecial(p unsafe.Pointer, bubbleid uint64, add bool) (ok bool
s.special.next = *iter
*iter = (*special)(unsafe.Pointer(s))
spanHasSpecials(span)
- ok = true
+ assoc = bubbleAssocCurrentBubble
} else {
// p is not associated with a bubble.
- ok = false
+ assoc = bubbleAssocUnbubbled
}
unlock(&span.speciallock)
releasem(mp)
- return ok
+ return assoc
}
// synctest_associate associates p with the current bubble.
// It returns false if p is already associated with a different bubble.
//
//go:linkname synctest_associate internal/synctest.associate
-func synctest_associate(p unsafe.Pointer) (ok bool) {
+func synctest_associate(p unsafe.Pointer) int {
return getOrSetBubbleSpecial(p, getg().bubble.id, true)
}
@@ -435,5 +448,5 @@ func synctest_disassociate(p unsafe.Pointer) {
//
//go:linkname synctest_isAssociated internal/synctest.isAssociated
func synctest_isAssociated(p unsafe.Pointer) bool {
- return getOrSetBubbleSpecial(p, getg().bubble.id, false)
+ return getOrSetBubbleSpecial(p, getg().bubble.id, false) == bubbleAssocCurrentBubble
}
diff --git a/src/runtime/synctest_test.go b/src/runtime/synctest_test.go
index 0fdd032fc9..1059d629d3 100644
--- a/src/runtime/synctest_test.go
+++ b/src/runtime/synctest_test.go
@@ -5,6 +5,8 @@
package runtime_test
import (
+ "internal/synctest"
+ "runtime"
"testing"
)
@@ -15,3 +17,13 @@ func TestSynctest(t *testing.T) {
t.Fatalf("output:\n%s\n\nwanted:\n%s", output, want)
}
}
+
+// TestSynctestAssocConsts verifies that constants defined
+// in both runtime and internal/synctest match.
+func TestSynctestAssocConsts(t *testing.T) {
+ if runtime.BubbleAssocUnbubbled != synctest.Unbubbled ||
+ runtime.BubbleAssocCurrentBubble != synctest.CurrentBubble ||
+ runtime.BubbleAssocOtherBubble != synctest.OtherBubble {
+ t.Fatal("mismatch: runtime.BubbleAssoc? != synctest.*")
+ }
+}