1 // Copyright 2023 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 //go:build !plan9 && !windows
7 // Test that callbacks from C to Go in the same C-thread always get the same m.
8 // Make sure the extra M bind to the C-thread.
17 extern void GoCheckBindM();
20 #define CHECKCALLS 100
22 static void* checkBindMThread(void* thread) {
24 for (i = 0; i < CHECKCALLS; i++) {
25 GoCheckBindM((uintptr_t)thread);
31 static void CheckBindM() {
33 pthread_t s[CTHREADS];
35 for (i = 0; i < CTHREADS; i++) {
36 pthread_create(&s[i], NULL, checkBindMThread, &s[i]);
38 for (i = 0; i < CTHREADS; i++) {
39 pthread_join(s[i], NULL);
55 cThreadToM = map[uintptr]uintptr{}
56 started = atomic.Uint32{}
59 // same as CTHREADS in C, make sure all the C threads are actually started.
63 register("EnsureBindM", EnsureBindM)
67 func GoCheckBindM(thread uintptr) {
68 // Wait all threads start
69 if started.Load() != cThreadNum {
70 // Only once for each thread, since it will wait all threads start.
72 for started.Load() < cThreadNum {
76 m := runtime_getm_for_test()
79 if savedM, ok := cThreadToM[thread]; ok && savedM != m {
80 fmt.Printf("m == %x want %x\n", m, savedM)
83 cThreadToM[thread] = m