diff --git a/runtime/internal/clite/pthread/pthread.go b/runtime/internal/clite/pthread/pthread.go index 3664e7d3..70ba63ad 100644 --- a/runtime/internal/clite/pthread/pthread.go +++ b/runtime/internal/clite/pthread/pthread.go @@ -56,6 +56,20 @@ func Exit(retval c.Pointer) //go:linkname Cancel C.pthread_cancel func Cancel(thread Thread) c.Int +// The pthread_self() function returns the ID of the calling thread. +// This is the same value that is returned in *thread in the +// pthread_create(3) call that created this thread. +// +//go:linkname Self C.pthread_self +func Self() Thread + +// The pthread_equal() function compares two thread identifiers. +// If the two thread IDs are equal, pthread_equal() returns a nonzero +// value; otherwise, it returns 0. +// +//go:linkname Equal C.pthread_equal +func Equal(t1, t2 Thread) c.Int + // ----------------------------------------------------------------------------- // Attr represents a POSIX thread attributes. diff --git a/runtime/internal/lib/runtime/runtime.go b/runtime/internal/lib/runtime/runtime.go index 75a292c5..bde2d8e4 100644 --- a/runtime/internal/lib/runtime/runtime.go +++ b/runtime/internal/lib/runtime/runtime.go @@ -31,7 +31,7 @@ import "C" import ( "unsafe" - "github.com/goplus/llgo/runtime/internal/clite/pthread" + "github.com/goplus/llgo/runtime/internal/runtime" ) // llgo:skipall @@ -52,7 +52,7 @@ func GOMAXPROCS(n int) int { } func Goexit() { - pthread.Exit(nil) + runtime.Goexit() } func KeepAlive(x any) { diff --git a/runtime/internal/runtime/z_rt.go b/runtime/internal/runtime/z_rt.go index fca7534d..1b02c237 100644 --- a/runtime/internal/runtime/z_rt.go +++ b/runtime/internal/runtime/z_rt.go @@ -78,17 +78,31 @@ func Rethrow(link *Defer) { } var ( - excepKey pthread.Key + excepKey pthread.Key + mainThread pthread.Thread + goexit struct{} ) +func Goexit() { + panic(goexit) +} + func init() { excepKey.Create(nil) + mainThread = pthread.Self() } // ----------------------------------------------------------------------------- // TracePanic prints panic message. func TracePanic(v any) { + if v == goexit { + if pthread.Equal(mainThread, pthread.Self()) != 0 { + fatal("no goroutines (main called runtime.Goexit) - deadlock!") + c.Exit(2) + } + pthread.Exit(nil) + } print("panic: ") printany(v) println("\n")