diff options
| -rw-r--r-- | cmd/snapd/main.go | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/cmd/snapd/main.go b/cmd/snapd/main.go index aafabbfe98..6940cf06a4 100644 --- a/cmd/snapd/main.go +++ b/cmd/snapd/main.go @@ -23,6 +23,7 @@ import ( "fmt" "os" "os/signal" + "runtime" "syscall" "time" @@ -53,6 +54,24 @@ func init() { func main() { cmd.ExecInSnapdOrCoreSnap() + // The Go scheduler by default has a single operating system + // thread per processor core, and does its own goroutine + // scheduling inside of that thread. For I/O operations that + // the Go runtime knows about, it has mechanisms to reschedule + // goroutines so the system thread isn't blocked waiting for + // I/O. If a goroutine performs a blocking system call which + // the go runtime doesn't have special optimizations for, the + // system thread can become blocked waiting for the syscall. + // This can dramatically reduce runtime performance, and the + // problem is much worse on single processor systems because + // there is normally only a single system thread. + // + // We workaround by increasing the number of procs to a + // minimum of two. + if runtime.GOMAXPROCS(-1) == 1 { + runtime.GOMAXPROCS(2) + } + ch := make(chan os.Signal, 2) signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) if err := run(ch); err != nil { |
