diff --git a/tools/tui/loop/api.go b/tools/tui/loop/api.go index ce747e5bd..6fa0bb606 100644 --- a/tools/tui/loop/api.go +++ b/tools/tui/loop/api.go @@ -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 diff --git a/tools/utils/images/utils.go b/tools/utils/images/utils.go index 6ab2631ad..e25f83e53 100644 --- a/tools/utils/images/utils.go +++ b/tools/utils/images/utils.go @@ -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() diff --git a/tools/utils/misc.go b/tools/utils/misc.go index 5f9ed25b8..12470f60f 100644 --- a/tools/utils/misc.go +++ b/tools/utils/misc.go @@ -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 {