Skip to content

time: Sleep requires ~7 syscalls #25471

Open
@bwesterb

Description

What version of Go are you using (go version)?

go version go1.10.1 linux/amd64

Does this issue reproduce with the latest release?

Yes (1.10.2).

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/bas/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/bas/go"
GORACE=""
GOROOT="/usr/lib/go-1.10"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go-1.10/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build723289083=/tmp/go-build -gno-record-gcc-switches"

What did you do?

The following Go program calls time.Sleep the number of times given as a commandline argument.

package main

import (
	"os"
	"strconv"
	"time"
)

var max int

func main() {
	max, _ = strconv.Atoi(os.Args[1])
	n := 0
	for {
		time.Sleep(time.Second / 100)
		n += 1
		if n >= max {
			return
		}
	}
}

If track the number of sys calls using strace -f -c, we find

bas@fourier2:~/gosleeptest$ strace -c -f ./gosleeptest 1
strace: Process 3115 attached
strace: Process 3114 attached
strace: Process 3116 attached
strace: Process 3117 attached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         8           mmap
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0       114           rt_sigaction
  0.00    0.000000           0        14           rt_sigprocmask
  0.00    0.000000           0         4           clone
  0.00    0.000000           0         1           execve
  0.00    0.000000           0        10           sigaltstack
  0.00    0.000000           0         5           arch_prctl
  0.00    0.000000           0         9           gettid
  0.00    0.000000           0         8         1 futex
  0.00    0.000000           0         1           sched_getaffinity
  0.00    0.000000           0         1           readlinkat
  0.00    0.000000           0        22           pselect6
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                   198         1 total
bas@fourier2:~/gosleeptest$ strace -c -f ./gosleeptest 10
strace: Process 3919 attached
strace: Process 3918 attached
strace: Process 3917 attached
strace: Process 3927 attached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         8           mmap
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0       114           rt_sigaction
  0.00    0.000000           0        14           rt_sigprocmask
  0.00    0.000000           0         2           sched_yield
  0.00    0.000000           0         4           clone
  0.00    0.000000           0         1           execve
  0.00    0.000000           0        10           sigaltstack
  0.00    0.000000           0         5           arch_prctl
  0.00    0.000000           0         9           gettid
  0.00    0.000000           0        74        12 futex
  0.00    0.000000           0         1           sched_getaffinity
  0.00    0.000000           0         1           readlinkat
  0.00    0.000000           0        69           pselect6
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                   313        12 total
bas@fourier2:~/gosleeptest$ strace -c -f ./gosleeptest 100
strace: Process 4491 attached
strace: Process 4490 attached
strace: Process 4489 attached
strace: Process 4532 attached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 89.01    0.043330          82       530       104 futex
  9.76    0.004751          21       228           pselect6
  0.27    0.000131           1       114           rt_sigaction
  0.23    0.000114          23         5           arch_prctl
  0.19    0.000091           9        10           sigaltstack
  0.18    0.000086          10         9           gettid
  0.13    0.000061           4        14           rt_sigprocmask
  0.07    0.000035           4         8           mmap
  0.07    0.000033          33         1           readlinkat
  0.03    0.000017           4         4           clone
  0.03    0.000017          17         1           execve
  0.02    0.000009           9         1           munmap
  0.01    0.000003           3         1           sched_getaffinity
------ ----------- ----------- --------- --------- ----------------
100.00    0.048678                   926       104 total

What did you expect to see?

A single time.Sleep should use approximately one syscall. (Python's time.sleep does only use one syscall, for instance.)

What did you see instead?

Approximately seven sys calls per time.Sleep. As a consequence, the go process also uses quite a bit of CPU time per time.Sleep: 500us (compared to 13us for Python's time.sleep).

Notes

I encountered this issue while debugging unexpectedly high idle CPU usage by wireguard-go.

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Performance

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions