Don't acquire contended lock with the OS thread locked.
Fixes #1049 PiperOrigin-RevId: 297175164
This commit is contained in:
parent
53504e29ca
commit
98b693e61b
|
@ -329,10 +329,12 @@ func (m *machine) Destroy() {
|
|||
}
|
||||
|
||||
// Get gets an available vCPU.
|
||||
//
|
||||
// This will return with the OS thread locked.
|
||||
func (m *machine) Get() *vCPU {
|
||||
m.mu.RLock()
|
||||
runtime.LockOSThread()
|
||||
tid := procid.Current()
|
||||
m.mu.RLock()
|
||||
|
||||
// Check for an exact match.
|
||||
if c := m.vCPUs[tid]; c != nil {
|
||||
|
@ -343,8 +345,22 @@ func (m *machine) Get() *vCPU {
|
|||
|
||||
// The happy path failed. We now proceed to acquire an exclusive lock
|
||||
// (because the vCPU map may change), and scan all available vCPUs.
|
||||
// In this case, we first unlock the OS thread. Otherwise, if mu is
|
||||
// not available, the current system thread will be parked and a new
|
||||
// system thread spawned. We avoid this situation by simply refreshing
|
||||
// tid after relocking the system thread.
|
||||
m.mu.RUnlock()
|
||||
runtime.UnlockOSThread()
|
||||
m.mu.Lock()
|
||||
runtime.LockOSThread()
|
||||
tid = procid.Current()
|
||||
|
||||
// Recheck for an exact match.
|
||||
if c := m.vCPUs[tid]; c != nil {
|
||||
c.lock()
|
||||
m.mu.Unlock()
|
||||
return c
|
||||
}
|
||||
|
||||
for {
|
||||
// Scan for an available vCPU.
|
||||
|
|
Loading…
Reference in New Issue