github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/testdata/testprogcgo/bindm.go (about) 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. 4 5 //go:build !plan9 && !windows 6 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. 9 10 package main 11 12 /* 13 extern void CheckBindM(); 14 */ 15 import "C" 16 17 import ( 18 "fmt" 19 "os" 20 "runtime" 21 "sync" 22 "sync/atomic" 23 ) 24 25 var ( 26 mutex = sync.Mutex{} 27 cThreadToM = map[uintptr]uintptr{} 28 started = atomic.Uint32{} 29 ) 30 31 // same as CTHREADS in C, make sure all the C threads are actually started. 32 const cThreadNum = 2 33 34 func init() { 35 register("EnsureBindM", EnsureBindM) 36 } 37 38 //export GoCheckBindM 39 func GoCheckBindM(thread uintptr) { 40 // Wait all threads start 41 if started.Load() != cThreadNum { 42 // Only once for each thread, since it will wait all threads start. 43 started.Add(1) 44 for started.Load() < cThreadNum { 45 runtime.Gosched() 46 } 47 } 48 m := runtime_getm_for_test() 49 mutex.Lock() 50 defer mutex.Unlock() 51 if savedM, ok := cThreadToM[thread]; ok && savedM != m { 52 fmt.Printf("m == %x want %x\n", m, savedM) 53 os.Exit(1) 54 } 55 cThreadToM[thread] = m 56 } 57 58 func EnsureBindM() { 59 C.CheckBindM() 60 fmt.Println("OK") 61 }