| | |
| | |
| | |
| |
|
| | |
| | |
| |
|
| | package main |
| |
|
| | import ( |
| | "os" |
| | "runtime" |
| | "sync/atomic" |
| | "time" |
| | "unsafe" |
| | ) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | import "C" |
| |
|
| | var mainThread C.pthread_t |
| |
|
| | func init() { |
| | registerInit("LockOSThreadMain", func() { |
| | |
| | mainThread = C.pthread_self() |
| | }) |
| | register("LockOSThreadMain", LockOSThreadMain) |
| |
|
| | registerInit("LockOSThreadAlt", func() { |
| | |
| | runtime.LockOSThread() |
| | }) |
| | register("LockOSThreadAlt", LockOSThreadAlt) |
| | } |
| |
|
| | func LockOSThreadMain() { |
| | |
| | |
| | if runtime.GOMAXPROCS(-1) != 1 { |
| | println("requires GOMAXPROCS=1") |
| | os.Exit(1) |
| | } |
| |
|
| | ready := make(chan bool, 1) |
| | go func() { |
| | |
| | |
| | runtime.LockOSThread() |
| | self := C.pthread_self() |
| | if C.pthread_equal(mainThread, self) == 0 { |
| | println("failed to start goroutine on main thread") |
| | os.Exit(1) |
| | } |
| | |
| | |
| | ready <- true |
| | }() |
| | <-ready |
| | time.Sleep(1 * time.Millisecond) |
| | |
| | |
| | self := C.pthread_self() |
| | if C.pthread_equal(mainThread, self) != 0 { |
| | println("goroutine migrated to locked thread") |
| | os.Exit(1) |
| | } |
| | println("OK") |
| | } |
| |
|
| | func LockOSThreadAlt() { |
| | |
| |
|
| | var subThread C.pthread_t |
| | ready := make(chan bool, 1) |
| | C.threadExited = 0 |
| | go func() { |
| | |
| | runtime.LockOSThread() |
| | subThread = C.pthread_self() |
| | |
| | |
| | var key C.pthread_key_t |
| | C.pthread_key_create(&key, (*[0]byte)(unsafe.Pointer(C.setExited))) |
| | C.pthread_setspecific(key, unsafe.Pointer(new(int))) |
| | ready <- true |
| | |
| | }() |
| | <-ready |
| | for { |
| | time.Sleep(1 * time.Millisecond) |
| | |
| | self := C.pthread_self() |
| | if C.pthread_equal(subThread, self) != 0 { |
| | println("locked thread reused") |
| | os.Exit(1) |
| | } |
| | if atomic.LoadUint32((*uint32)(&C.threadExited)) != 0 { |
| | println("OK") |
| | return |
| | } |
| | } |
| | } |
| |
|