mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-07 04:23:41 +00:00
runtime: make Goexit exit host threads
The threads scheduler handled runtime.Goexit using the generic deadlock path, which parked the current pthread forever. Add a scheduler-specific goexit hook so it can remove the current task and exit the pthread while ordinary blocking deadlocks still block. Track main goroutine Goexit so the last remaining goroutine reports the expected deadlock instead of letting the process exit successfully. Expand the crash coverage with the Goexit cases covered by Big Go's runtime tests.
This commit is contained in:
@@ -78,7 +78,7 @@ func panicOrGoexit(message interface{}, panicking panicState) {
|
||||
if panicking == panicGoexit {
|
||||
// Call to Goexit() instead of a panic.
|
||||
// Exit the goroutine instead of printing a panic message.
|
||||
deadlock()
|
||||
goexit()
|
||||
}
|
||||
printstring("panic: ")
|
||||
printitf(message)
|
||||
|
||||
@@ -2,9 +2,6 @@ package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//export abort
|
||||
func abort()
|
||||
|
||||
//export exit
|
||||
func libc_exit(code int)
|
||||
|
||||
@@ -132,6 +129,11 @@ func putchar(c byte) {
|
||||
libc_putchar(int(c))
|
||||
}
|
||||
|
||||
func abort() {
|
||||
libc_exit(1)
|
||||
trap()
|
||||
}
|
||||
|
||||
var heapSize uintptr = 128 * 1024 // small amount to start
|
||||
var heapMaxSize uintptr
|
||||
|
||||
|
||||
@@ -54,6 +54,10 @@ func deadlock() {
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func goexit() {
|
||||
task.Exit()
|
||||
}
|
||||
|
||||
// Add this task to the end of the run queue.
|
||||
func scheduleTask(t *task.Task) {
|
||||
runqueue.Push(t)
|
||||
|
||||
@@ -32,6 +32,10 @@ func deadlock() {
|
||||
trap()
|
||||
}
|
||||
|
||||
func goexit() {
|
||||
task.Exit()
|
||||
}
|
||||
|
||||
// Mark the given task as ready to resume.
|
||||
// This is allowed even if the task isn't paused yet, but will pause soon.
|
||||
func scheduleTask(t *task.Task) {
|
||||
|
||||
@@ -42,6 +42,10 @@ func deadlock() {
|
||||
runtimePanic("all goroutines are asleep - deadlock!")
|
||||
}
|
||||
|
||||
func goexit() {
|
||||
deadlock()
|
||||
}
|
||||
|
||||
func scheduleTask(t *task.Task) {
|
||||
// Pause() will panic, so this should not be reachable.
|
||||
}
|
||||
|
||||
@@ -40,10 +40,13 @@ func sleep(duration int64) {
|
||||
}
|
||||
|
||||
func deadlock() {
|
||||
// TODO: exit the thread via pthread_exit.
|
||||
task.Pause()
|
||||
}
|
||||
|
||||
func goexit() {
|
||||
task.Exit()
|
||||
}
|
||||
|
||||
func scheduleTask(t *task.Task) {
|
||||
t.Resume()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user