golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.93k stars 17.52k forks source link

runtime: consider removing osyield call from lock2 #69268

Open rhysh opened 1 week ago

rhysh commented 1 week ago

The current runtime.lock2 implementation does a bit of spinning to try to acquire the runtime.mutex before sleeping. If a thread has gone to sleep within lock2 (via a syscall), it will eventually require another thread (in unlock2) to do another syscall to wake it. The bit of spinning allows us to avoid those syscalls in some cases. Slowing down a bit and trying again, at a high level, seems good; maybe the previous holder has exited the critical section.

The first phase of spinning involves a runtime.procyield call, which asks the processor to pause for a moment (on the scale of tens or hundreds of nanoseconds). There's some uncertainty about what that duration is and what it should be (described in part in #69232) but the idea of using this mechanism to slow down for a bit, again at a high level, seems good.

The second phase of spinning involves a runtime.osyield call. That's a syscall, implemented on Linux as a call to sched_yield(2). The discussion in CL 473656 links to https://www.realworldtech.com/forum/?threadid=189711&curpostid=189752 , which gives a perspective on why that's not a universally good idea.

Maybe we should delete that part of lock2. Or maybe we should replace it with an explicit nanosleep(2) call of some tiny time interval.

I don't see any urgency here. Mostly I'd like a tracking issue to reference in lock2's comments.

CC @golang/runtime

gabyhelp commented 1 week ago

Related Issues and Documentation

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)