Skip to content

Commit 94850c6

Browse files
prattmicgopherbot
authored andcommitted
Revert "runtime/cgo: store M for C-created thread in pthread key"
This reverts CL 481061. Reason for revert: When built with C TSAN, x_cgo_getstackbound triggers race detection on `g->stacklo` because the synchronization is in Go, which isn't instrumented. For #51676. For #59294. For #59678. Change-Id: I38afcda9fcffd6537582a39a5214bc23dc147d47 Reviewed-on: https://go-review.googlesource.com/c/go/+/485275 TryBot-Result: Gopher Robot <[email protected]> Auto-Submit: Michael Pratt <[email protected]> Run-TryBot: Michael Pratt <[email protected]> Reviewed-by: Than McIntosh <[email protected]>
1 parent 97e5ca6 commit 94850c6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+67
-944
lines changed

misc/cgo/test/cgo_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ func TestThreadLock(t *testing.T) { testThreadLockFunc(t) }
104104
func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) }
105105
func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) }
106106

107-
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
108-
func BenchmarkGoString(b *testing.B) { benchGoString(b) }
109-
func BenchmarkCGoCallback(b *testing.B) { benchCallback(b) }
110-
func BenchmarkCGoInCThread(b *testing.B) { benchCGoInCthread(b) }
107+
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
108+
func BenchmarkGoString(b *testing.B) { benchGoString(b) }
109+
func BenchmarkCGoCallback(b *testing.B) { benchCallback(b) }

misc/cgo/test/cthread_unix.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,3 @@ doAdd(int max, int nthread)
3232
for(i=0; i<nthread; i++)
3333
pthread_join(thread_id[i], 0);
3434
}
35-
36-
static void*
37-
goDummyCallbackThread(void* p)
38-
{
39-
int i, max;
40-
41-
max = *(int*)p;
42-
for(i=0; i<max; i++)
43-
goDummy();
44-
return NULL;
45-
}
46-
47-
int
48-
callGoInCThread(int max)
49-
{
50-
pthread_t thread;
51-
52-
if (pthread_create(&thread, NULL, goDummyCallbackThread, (void*)(&max)) != 0)
53-
return -1;
54-
if (pthread_join(thread, NULL) != 0)
55-
return -1;
56-
57-
return max;
58-
}

misc/cgo/test/cthread_windows.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,3 @@ doAdd(int max, int nthread)
3535
CloseHandle((HANDLE)thread_id[i]);
3636
}
3737
}
38-
39-
__stdcall
40-
static unsigned int
41-
goDummyCallbackThread(void* p)
42-
{
43-
int i, max;
44-
45-
max = *(int*)p;
46-
for(i=0; i<max; i++)
47-
goDummy();
48-
return 0;
49-
}
50-
51-
int
52-
callGoInCThread(int max)
53-
{
54-
uintptr_t thread_id;
55-
thread_id = _beginthreadex(0, 0, goDummyCallbackThread, &max, 0, 0);
56-
WaitForSingleObject((HANDLE)thread_id, INFINITE);
57-
CloseHandle((HANDLE)thread_id);
58-
return max;
59-
}

misc/cgo/test/testx.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
/*
2525
// threads
2626
extern void doAdd(int, int);
27-
extern int callGoInCThread(int);
2827
2928
// issue 1328
3029
void IntoC(void);
@@ -147,10 +146,6 @@ func Add(x int) {
147146
*p = 2
148147
}
149148

150-
//export goDummy
151-
func goDummy() {
152-
}
153-
154149
func testCthread(t *testing.T) {
155150
if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && runtime.GOARCH == "arm64" {
156151
t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add")
@@ -164,15 +159,6 @@ func testCthread(t *testing.T) {
164159
}
165160
}
166161

167-
// Benchmark measuring overhead from C to Go in a C thread.
168-
// Create a new C thread and invoke Go function repeatedly in the new C thread.
169-
func benchCGoInCthread(b *testing.B) {
170-
n := C.callGoInCThread(C.int(b.N))
171-
if int(n) != b.N {
172-
b.Fatal("unmatch loop times")
173-
}
174-
}
175-
176162
// issue 1328
177163

178164
//export BackIntoGo

misc/cgo/testcarchive/carchive_test.go

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,57 +1247,3 @@ func TestPreemption(t *testing.T) {
12471247
t.Error(err)
12481248
}
12491249
}
1250-
1251-
// Issue 59294. Test calling Go function from C after using some
1252-
// stack space.
1253-
func TestDeepStack(t *testing.T) {
1254-
t.Parallel()
1255-
1256-
if !testWork {
1257-
defer func() {
1258-
os.Remove("testp9" + exeSuffix)
1259-
os.Remove("libgo9.a")
1260-
os.Remove("libgo9.h")
1261-
}()
1262-
}
1263-
1264-
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo9.a", "./libgo9")
1265-
out, err := cmd.CombinedOutput()
1266-
t.Logf("%v\n%s", cmd.Args, out)
1267-
if err != nil {
1268-
t.Fatal(err)
1269-
}
1270-
checkLineComments(t, "libgo9.h")
1271-
checkArchive(t, "libgo9.a")
1272-
1273-
// build with -O0 so the C compiler won't optimize out the large stack frame
1274-
ccArgs := append(cc, "-O0", "-o", "testp9"+exeSuffix, "main9.c", "libgo9.a")
1275-
out, err = exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput()
1276-
t.Logf("%v\n%s", ccArgs, out)
1277-
if err != nil {
1278-
t.Fatal(err)
1279-
}
1280-
1281-
argv := cmdToRun("./testp9")
1282-
cmd = exec.Command(argv[0], argv[1:]...)
1283-
sb := new(strings.Builder)
1284-
cmd.Stdout = sb
1285-
cmd.Stderr = sb
1286-
if err := cmd.Start(); err != nil {
1287-
t.Fatal(err)
1288-
}
1289-
1290-
timer := time.AfterFunc(time.Minute,
1291-
func() {
1292-
t.Error("test program timed out")
1293-
cmd.Process.Kill()
1294-
},
1295-
)
1296-
defer timer.Stop()
1297-
1298-
err = cmd.Wait()
1299-
t.Logf("%v\n%s", cmd.Args, sb)
1300-
if err != nil {
1301-
t.Error(err)
1302-
}
1303-
}

misc/cgo/testcarchive/testdata/libgo9/a.go

Lines changed: 0 additions & 14 deletions
This file was deleted.

misc/cgo/testcarchive/testdata/main9.c

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/runtime/asm_386.s

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -689,20 +689,7 @@ nosave:
689689
TEXT ·cgocallback(SB),NOSPLIT,$12-12 // Frame size must match commented places below
690690
NO_LOCAL_POINTERS
691691

692-
// Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
693-
// It is used to dropm while thread is exiting.
694-
MOVL fn+0(FP), AX
695-
CMPL AX, $0
696-
JNE loadg
697-
// Restore the g from frame.
698-
get_tls(CX)
699-
MOVL frame+4(FP), BX
700-
MOVL BX, g(CX)
701-
JMP dropm
702-
703-
loadg:
704-
// If g is nil, Go did not create the current thread,
705-
// or if this thread never called into Go on pthread platforms.
692+
// If g is nil, Go did not create the current thread.
706693
// Call needm to obtain one for temporary use.
707694
// In this case, we're running on the thread stack, so there's
708695
// lots of space, but the linker doesn't know. Hide the call from
@@ -720,9 +707,9 @@ loadg:
720707
MOVL BP, savedm-4(SP) // saved copy of oldm
721708
JMP havem
722709
needm:
723-
MOVL $runtime·needAndBindM(SB), AX
710+
MOVL $runtime·needm(SB), AX
724711
CALL AX
725-
MOVL $0, savedm-4(SP)
712+
MOVL $0, savedm-4(SP) // dropm on return
726713
get_tls(CX)
727714
MOVL g(CX), BP
728715
MOVL g_m(BP), BP
@@ -797,29 +784,13 @@ havem:
797784
MOVL 0(SP), AX
798785
MOVL AX, (g_sched+gobuf_sp)(SI)
799786

800-
// If the m on entry was nil, we called needm above to borrow an m,
801-
// 1. for the duration of the call on non-pthread platforms,
802-
// 2. or the duration of the C thread alive on pthread platforms.
803-
// If the m on entry wasn't nil,
804-
// 1. the thread might be a Go thread,
805-
// 2. or it's wasn't the first call from a C thread on pthread platforms,
806-
// since the we skip dropm to resue the m in the first call.
787+
// If the m on entry was nil, we called needm above to borrow an m
788+
// for the duration of the call. Since the call is over, return it with dropm.
807789
MOVL savedm-4(SP), DX
808790
CMPL DX, $0
809-
JNE droppedm
810-
811-
// Skip dropm to reuse it in the next call, when a pthread key has been created.
812-
MOVL _cgo_pthread_key_created(SB), DX
813-
// It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
814-
CMPL DX, $0
815-
JEQ dropm
816-
CMPL (DX), $0
817-
JNE droppedm
818-
819-
dropm:
791+
JNE 3(PC)
820792
MOVL $runtime·dropm(SB), AX
821793
CALL AX
822-
droppedm:
823794

824795
// Done!
825796
RET

src/runtime/asm_amd64.s

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -918,20 +918,7 @@ GLOBL zeroTLS<>(SB),RODATA,$const_tlsSize
918918
TEXT ·cgocallback(SB),NOSPLIT,$24-24
919919
NO_LOCAL_POINTERS
920920

921-
// Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
922-
// It is used to dropm while thread is exiting.
923-
MOVQ fn+0(FP), AX
924-
CMPQ AX, $0
925-
JNE loadg
926-
// Restore the g from frame.
927-
get_tls(CX)
928-
MOVQ frame+8(FP), BX
929-
MOVQ BX, g(CX)
930-
JMP dropm
931-
932-
loadg:
933-
// If g is nil, Go did not create the current thread,
934-
// or if this thread never called into Go on pthread platforms.
921+
// If g is nil, Go did not create the current thread.
935922
// Call needm to obtain one m for temporary use.
936923
// In this case, we're running on the thread stack, so there's
937924
// lots of space, but the linker doesn't know. Hide the call from
@@ -969,9 +956,9 @@ needm:
969956
// a bad value in there, in case needm tries to use it.
970957
XORPS X15, X15
971958
XORQ R14, R14
972-
MOVQ $runtime·needAndBindM<ABIInternal>(SB), AX
959+
MOVQ $runtime·needm<ABIInternal>(SB), AX
973960
CALL AX
974-
MOVQ $0, savedm-8(SP)
961+
MOVQ $0, savedm-8(SP) // dropm on return
975962
get_tls(CX)
976963
MOVQ g(CX), BX
977964
MOVQ g_m(BX), BX
@@ -1060,26 +1047,11 @@ havem:
10601047
MOVQ 0(SP), AX
10611048
MOVQ AX, (g_sched+gobuf_sp)(SI)
10621049

1063-
// If the m on entry was nil, we called needm above to borrow an m,
1064-
// 1. for the duration of the call on non-pthread platforms,
1065-
// 2. or the duration of the C thread alive on pthread platforms.
1066-
// If the m on entry wasn't nil,
1067-
// 1. the thread might be a Go thread,
1068-
// 2. or it's wasn't the first call from a C thread on pthread platforms,
1069-
// since the we skip dropm to resue the m in the first call.
1050+
// If the m on entry was nil, we called needm above to borrow an m
1051+
// for the duration of the call. Since the call is over, return it with dropm.
10701052
MOVQ savedm-8(SP), BX
10711053
CMPQ BX, $0
10721054
JNE done
1073-
1074-
// Skip dropm to reuse it in the next call, when a pthread key has been created.
1075-
MOVQ _cgo_pthread_key_created(SB), AX
1076-
// It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
1077-
CMPQ AX, $0
1078-
JEQ dropm
1079-
CMPQ (AX), $0
1080-
JNE done
1081-
1082-
dropm:
10831055
MOVQ $runtime·dropm(SB), AX
10841056
CALL AX
10851057
#ifdef GOOS_windows

src/runtime/asm_arm.s

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -630,16 +630,6 @@ nosave:
630630
TEXT ·cgocallback(SB),NOSPLIT,$12-12
631631
NO_LOCAL_POINTERS
632632

633-
// Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
634-
// It is used to dropm while thread is exiting.
635-
MOVW fn+0(FP), R1
636-
CMP $0, R1
637-
B.NE loadg
638-
// Restore the g from frame.
639-
MOVW frame+4(FP), g
640-
B dropm
641-
642-
loadg:
643633
// Load m and g from thread-local storage.
644634
#ifdef GOOS_openbsd
645635
BL runtime·load_g(SB)
@@ -649,8 +639,7 @@ loadg:
649639
BL.NE runtime·load_g(SB)
650640
#endif
651641

652-
// If g is nil, Go did not create the current thread,
653-
// or if this thread never called into Go on pthread platforms.
642+
// If g is nil, Go did not create the current thread.
654643
// Call needm to obtain one for temporary use.
655644
// In this case, we're running on the thread stack, so there's
656645
// lots of space, but the linker doesn't know. Hide the call from
@@ -664,7 +653,7 @@ loadg:
664653

665654
needm:
666655
MOVW g, savedm-4(SP) // g is zero, so is m.
667-
MOVW $runtime·needAndBindM(SB), R0
656+
MOVW $runtime·needm(SB), R0
668657
BL (R0)
669658

670659
// Set m->g0->sched.sp = SP, so that if a panic happens
@@ -735,31 +724,14 @@ havem:
735724
MOVW savedsp-12(SP), R4 // must match frame size
736725
MOVW R4, (g_sched+gobuf_sp)(g)
737726

738-
// If the m on entry was nil, we called needm above to borrow an m,
739-
// 1. for the duration of the call on non-pthread platforms,
740-
// 2. or the duration of the C thread alive on pthread platforms.
741-
// If the m on entry wasn't nil,
742-
// 1. the thread might be a Go thread,
743-
// 2. or it's wasn't the first call from a C thread on pthread platforms,
744-
// since the we skip dropm to resue the m in the first call.
727+
// If the m on entry was nil, we called needm above to borrow an m
728+
// for the duration of the call. Since the call is over, return it with dropm.
745729
MOVW savedm-4(SP), R6
746730
CMP $0, R6
747-
B.NE done
748-
749-
// Skip dropm to reuse it in the next call, when a pthread key has been created.
750-
MOVW _cgo_pthread_key_created(SB), R6
751-
// It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
752-
CMP $0, R6
753-
B.EQ dropm
754-
MOVW (R6), R6
755-
CMP $0, R6
756-
B.NE done
757-
758-
dropm:
731+
B.NE 3(PC)
759732
MOVW $runtime·dropm(SB), R0
760733
BL (R0)
761734

762-
done:
763735
// Done!
764736
RET
765737

0 commit comments

Comments
 (0)