This commit is contained in:
Kovid Goyal 2025-06-05 20:59:09 +05:30
parent a783d4932e
commit 3feea5b279
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
3 changed files with 34 additions and 33 deletions

View file

@ -7,7 +7,6 @@ import (
"encoding/hex"
"fmt"
"os"
"runtime"
"strings"
"time"
@ -309,32 +308,11 @@ func (self *Loop) DebugPrintln(args ...any) {
}
}
func format_stacktrace_on_panic(r any) (text string, err error) {
pcs := make([]uintptr, 512)
n := runtime.Callers(3, pcs)
lines := []string{}
frames := runtime.CallersFrames(pcs[:n])
err = fmt.Errorf("Panicked: %s", r)
lines = append(lines, fmt.Sprintf("\r\nPanicked with error: %s\r\nStacktrace (most recent call first):\r\n", r))
found_first_frame := false
for frame, more := frames.Next(); more; frame, more = frames.Next() {
if !found_first_frame {
if strings.HasPrefix(frame.Function, "runtime.") {
continue
}
found_first_frame = true
}
lines = append(lines, fmt.Sprintf("%s\r\n\t%s:%d\r\n", frame.Function, frame.File, frame.Line))
}
text = strings.Join(lines, "")
return strings.TrimSpace(text), err
}
func (self *Loop) Run() (err error) {
defer func() {
if r := recover(); r != nil {
var text string
text, err = format_stacktrace_on_panic(r)
text, err = utils.Format_stacktrace_on_panic(r)
is_terminal := tty.IsTerminal(os.Stderr.Fd())
if is_terminal {
os.Stderr.WriteString("\x1b]\x1b\\\x1bc\x1b[H\x1b[2J") // reset terminal
@ -600,7 +578,7 @@ type SizedText struct {
func (self *Loop) RecoverFromPanicInGoRoutine() {
if r := recover(); r != nil {
text, err := format_stacktrace_on_panic(r)
text, err := utils.Format_stacktrace_on_panic(r)
err = fmt.Errorf("Panicked in non-main go routine\n%s\n%w", text, err)
// print to kitty stdout as multiple go routines might panic but only
// one panic is reported by the main loop panic_channel

View file

@ -23,6 +23,14 @@ func (self *Context) NumberOfThreads() int {
return int(self.num_of_threads.Load())
}
func (self *Context) EffectiveNumberOfThreads() int {
ans := int(self.num_of_threads.Load())
if ans <= 0 {
ans = max(1, runtime.NumCPU())
}
return ans
}
// parallel processes the data in separate goroutines.
func (self *Context) Parallel(start, stop int, fn func(<-chan int)) {
count := stop - start
@ -30,14 +38,7 @@ func (self *Context) Parallel(start, stop int, fn func(<-chan int)) {
return
}
procs := self.NumberOfThreads()
if procs <= 0 {
procs = runtime.NumCPU()
}
if procs > count {
procs = count
}
procs := min(self.EffectiveNumberOfThreads(), count)
c := make(chan int, count)
for i := start; i < stop; i++ {
c <- i
@ -45,7 +46,7 @@ func (self *Context) Parallel(start, stop int, fn func(<-chan int)) {
close(c)
var wg sync.WaitGroup
for i := 0; i < procs; i++ {
for range procs {
wg.Add(1)
go func() {
defer wg.Done()

View file

@ -11,6 +11,7 @@ import (
"runtime"
"slices"
"strconv"
"strings"
"golang.org/x/exp/constraints"
)
@ -64,6 +65,27 @@ func Filter[T any](s []T, f func(x T) bool) []T {
return ans
}
func Format_stacktrace_on_panic(r any) (text string, err error) {
pcs := make([]uintptr, 512)
n := runtime.Callers(3, pcs)
lines := []string{}
frames := runtime.CallersFrames(pcs[:n])
err = fmt.Errorf("Panicked: %s", r)
lines = append(lines, fmt.Sprintf("\r\nPanicked with error: %s\r\nStacktrace (most recent call first):\r\n", r))
found_first_frame := false
for frame, more := frames.Next(); more; frame, more = frames.Next() {
if !found_first_frame {
if strings.HasPrefix(frame.Function, "runtime.") {
continue
}
found_first_frame = true
}
lines = append(lines, fmt.Sprintf("%s\r\n\t%s:%d\r\n", frame.Function, frame.File, frame.Line))
}
text = strings.Join(lines, "")
return strings.TrimSpace(text), err
}
func Map[T any, O any](f func(x T) O, s []T) []O {
ans := make([]O, 0, len(s))
for _, x := range s {