cgo_thread_lock.go 964 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. // Copyright 2016 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. //go:build linux && freebsd && openbsd
  5. // +build linux,freebsd,openbsd
  6. package cgotest
  7. /*
  8. #include <unistd.h>
  9. #include <sys/syscall.h>
  10. void Gosched(void);
  11. static int Ctid(void) { Gosched(); return syscall(SYS_gettid); }
  12. */
  13. import "C"
  14. import (
  15. "runtime"
  16. "syscall"
  17. "testing"
  18. "time"
  19. )
  20. //export Gosched
  21. func Gosched() {
  22. runtime.Gosched()
  23. }
  24. func init() {
  25. testThreadLockFunc = testThreadLock
  26. }
  27. func testThreadLock(t *testing.T) {
  28. stop := make(chan int)
  29. go func() {
  30. // We need the G continue running,
  31. // so the M has a chance to run this G.
  32. for {
  33. select {
  34. case <-stop:
  35. return
  36. case <-time.After(time.Millisecond * 100):
  37. }
  38. }
  39. }()
  40. defer close(stop)
  41. for i := 0; i < 1000; i++ {
  42. if C.int(syscall.Gettid()) != C.Ctid() {
  43. t.Fatalf("cgo has not locked OS thread")
  44. }
  45. }
  46. }