Help us shape the future of Go! Take the 2026 Go Developer Survey

Source file src/runtime/testdata/testprog/lockosthread_aix.go

     1  // Copyright 2026 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  package main
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"runtime"
    11  )
    12  
    13  func init() {
    14  	registerInit("LockOSThreadExitAIX", func() {
    15  		// Lock the OS thread now so main runs on the main thread.
    16  		runtime.LockOSThread()
    17  	})
    18  	register("LockOSThreadExitAIX", LockOSThreadExitAIX)
    19  }
    20  
    21  // LockOSThreadExitAIX is like LockOSThreadAlt, but AIX has no thread ID
    22  // to check without cgo. Instead, record the threads that exist while n
    23  // goroutines are locked to their threads, and wait for n of them to
    24  // exit. No other thread exits in this program.
    25  func LockOSThreadExitAIX() {
    26  	const n = 10
    27  	ready := make(chan bool)
    28  	done := make(chan bool)
    29  	for range n {
    30  		go func() {
    31  			runtime.LockOSThread()
    32  			ready <- true
    33  			<-done
    34  		}()
    35  	}
    36  	for range n {
    37  		<-ready
    38  	}
    39  	threads := lwps()
    40  	close(done)
    41  	runtime.UnlockOSThread()
    42  
    43  	// If the threads never exit, this loops until the test times out.
    44  	for exited(threads) < n {
    45  		runtime.Gosched()
    46  	}
    47  	println("OK")
    48  }
    49  
    50  // lwps returns the IDs of the kernel threads in the process.
    51  func lwps() map[string]bool {
    52  	entries, err := os.ReadDir(fmt.Sprintf("/proc/%d/lwp", os.Getpid()))
    53  	if err != nil {
    54  		panic(err)
    55  	}
    56  	ids := make(map[string]bool)
    57  	for _, e := range entries {
    58  		ids[e.Name()] = true
    59  	}
    60  	return ids
    61  }
    62  
    63  // exited returns how many of the given threads have exited.
    64  func exited(threads map[string]bool) int {
    65  	now := lwps()
    66  	n := 0
    67  	for id := range threads {
    68  		if !now[id] {
    69  			n++
    70  		}
    71  	}
    72  	return n
    73  }
    74  

View as plain text