From 8591275eb2909615708fd5cbade1b3333d58e117 Mon Sep 17 00:00:00 2001 From: visualfc Date: Sun, 16 Feb 2025 19:53:38 +0800 Subject: [PATCH] runtime: goexit use thread key --- compiler/cl/_testgo/goexit/in.go | 57 +++++++++++++++++++++++++++++++ compiler/cl/_testgo/goexit/out.ll | 1 + runtime/internal/runtime/z_rt.go | 19 ++++++----- 3 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 compiler/cl/_testgo/goexit/in.go create mode 100644 compiler/cl/_testgo/goexit/out.ll diff --git a/compiler/cl/_testgo/goexit/in.go b/compiler/cl/_testgo/goexit/in.go new file mode 100644 index 00000000..5e764b43 --- /dev/null +++ b/compiler/cl/_testgo/goexit/in.go @@ -0,0 +1,57 @@ +package main + +import ( + "runtime" +) + +func main() { + demo1() + demo2() + demo3() +} + +func demo1() { + ch := make(chan bool) + go func() { + defer func() { + ch <- true + }() + runtime.Goexit() + }() + <-ch +} + +func demo2() { + ch := make(chan bool) + go func() { + defer func() { + if r := recover(); r != nil { + panic("must nil") + } + ch <- true + }() + runtime.Goexit() + }() + <-ch +} + +func demo3() { + ch := make(chan bool) + go func() { + defer func() { + r := recover() + if r != "error" { + panic("must error") + } + ch <- true + }() + defer func() { + if r := recover(); r != nil { + panic("must nil") + } + panic("error") + }() + runtime.Goexit() + }() + <-ch +} diff --git a/compiler/cl/_testgo/goexit/out.ll b/compiler/cl/_testgo/goexit/out.ll new file mode 100644 index 00000000..1c8a0e79 --- /dev/null +++ b/compiler/cl/_testgo/goexit/out.ll @@ -0,0 +1 @@ +; \ No newline at end of file diff --git a/runtime/internal/runtime/z_rt.go b/runtime/internal/runtime/z_rt.go index 1b02c237..2b277c7b 100644 --- a/runtime/internal/runtime/z_rt.go +++ b/runtime/internal/runtime/z_rt.go @@ -74,21 +74,29 @@ func Rethrow(link *Defer) { } else { c.Siglongjmp(link.Addr, 1) } + } else if link == nil && goexitKey.Get() != nil { + if pthread.Equal(mainThread, pthread.Self()) != 0 { + fatal("no goroutines (main called runtime.Goexit) - deadlock!") + c.Exit(2) + } + pthread.Exit(nil) } } var ( excepKey pthread.Key + goexitKey pthread.Key mainThread pthread.Thread - goexit struct{} ) func Goexit() { - panic(goexit) + goexitKey.Set(unsafe.Pointer(&goexitKey)) + Rethrow((*Defer)(c.GoDeferData())) } func init() { excepKey.Create(nil) + goexitKey.Create(nil) mainThread = pthread.Self() } @@ -96,13 +104,6 @@ func init() { // 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")