]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/testdata/testprogcgo/bindm.go
c2003c2093150af5455912316a94b14381477480
[gostls13.git] / src / runtime / testdata / testprogcgo / bindm.go
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 }