• Ian Lance Taylor's avatar
    runtime: add as many extra M's as needed · 50048a4e
    Ian Lance Taylor authored
    When a non-Go thread calls into Go, the runtime needs an M to run the Go
    code. The runtime keeps a list of extra M's available. When the last
    extra M is allocated, the needextram field is set to tell it to allocate
    a new extra M as soon as it is running in Go. This ensures that an extra
    M will always be available for the next thread.
    
    However, if many threads need an extra M at the same time, this
    serializes them all. One thread will get an extra M with the needextram
    field set. All the other threads will see that there is no M available
    and will go to sleep. The one thread that succeeded will create a new
    extra M. One lucky thread will get it. All the other threads will see
    that there is no M available and will go to sleep. The effect is
    thundering herd, as all the threads looking for an extra M go through
    the process one by one. This seems to have a particularly bad effect on
    the FreeBSD scheduler for some reason.
    
    With this change, we track the number of threads waiting for an M, and
    create all of them as soon as one thread gets through. This still means
    that all the threads will fight for the lock to pick up the next M. But
    at least each thread that gets the lock will succeed, instead of going
    to sleep only to fight again.
    
    This smooths out the performance greatly on FreeBSD, reducing the
    average wall time of `testprogcgo CgoCallbackGC` by 74%.  On GNU/Linux
    the average wall time goes down by 9%.
    
    Fixes #13926
    Fixes #16396
    
    Change-Id: I6dc42a4156085a7ed4e5334c60b39db8f8ef8fea
    Reviewed-on: https://go-review.googlesource.com/25047
    Run-TryBot: Ian Lance Taylor <iant@golang.org>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: 's avatarDmitry Vyukov <dvyukov@google.com>
    50048a4e
proc.go 120 KB