mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 14:18:26 +02:00
DRYer
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"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) {
|
func (self *Loop) Run() (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
var text string
|
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())
|
is_terminal := tty.IsTerminal(os.Stderr.Fd())
|
||||||
if is_terminal {
|
if is_terminal {
|
||||||
os.Stderr.WriteString("\x1b]\x1b\\\x1bc\x1b[H\x1b[2J") // reset terminal
|
os.Stderr.WriteString("\x1b]\x1b\\\x1bc\x1b[H\x1b[2J") // reset terminal
|
||||||
@@ -600,7 +578,7 @@ type SizedText struct {
|
|||||||
|
|
||||||
func (self *Loop) RecoverFromPanicInGoRoutine() {
|
func (self *Loop) RecoverFromPanicInGoRoutine() {
|
||||||
if r := recover(); r != nil {
|
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)
|
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
|
// print to kitty stdout as multiple go routines might panic but only
|
||||||
// one panic is reported by the main loop panic_channel
|
// one panic is reported by the main loop panic_channel
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ func (self *Context) NumberOfThreads() int {
|
|||||||
return int(self.num_of_threads.Load())
|
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.
|
// parallel processes the data in separate goroutines.
|
||||||
func (self *Context) Parallel(start, stop int, fn func(<-chan int)) {
|
func (self *Context) Parallel(start, stop int, fn func(<-chan int)) {
|
||||||
count := stop - start
|
count := stop - start
|
||||||
@@ -30,14 +38,7 @@ func (self *Context) Parallel(start, stop int, fn func(<-chan int)) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
procs := self.NumberOfThreads()
|
procs := min(self.EffectiveNumberOfThreads(), count)
|
||||||
if procs <= 0 {
|
|
||||||
procs = runtime.NumCPU()
|
|
||||||
}
|
|
||||||
if procs > count {
|
|
||||||
procs = count
|
|
||||||
}
|
|
||||||
|
|
||||||
c := make(chan int, count)
|
c := make(chan int, count)
|
||||||
for i := start; i < stop; i++ {
|
for i := start; i < stop; i++ {
|
||||||
c <- i
|
c <- i
|
||||||
@@ -45,7 +46,7 @@ func (self *Context) Parallel(start, stop int, fn func(<-chan int)) {
|
|||||||
close(c)
|
close(c)
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for i := 0; i < procs; i++ {
|
for range procs {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/exp/constraints"
|
"golang.org/x/exp/constraints"
|
||||||
)
|
)
|
||||||
@@ -64,6 +65,27 @@ func Filter[T any](s []T, f func(x T) bool) []T {
|
|||||||
return ans
|
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 {
|
func Map[T any, O any](f func(x T) O, s []T) []O {
|
||||||
ans := make([]O, 0, len(s))
|
ans := make([]O, 0, len(s))
|
||||||
for _, x := range s {
|
for _, x := range s {
|
||||||
|
|||||||
Reference in New Issue
Block a user