Replace mutex with spin-lock

This commit is contained in:
Andy Pan 2019-09-27 20:51:46 +08:00
parent 09973e8b1b
commit e73db1d7d2
3 changed files with 35 additions and 4 deletions

View File

@ -46,7 +46,7 @@ type Pool struct {
release int32 release int32
// lock for synchronous operation. // lock for synchronous operation.
lock sync.Mutex lock sync.Locker
// cond for waiting to get a idle worker. // cond for waiting to get a idle worker.
cond *sync.Cond cond *sync.Cond
@ -146,6 +146,7 @@ func NewPool(size int, options ...Option) (*Pool, error) {
nonblocking: opts.Nonblocking, nonblocking: opts.Nonblocking,
maxBlockingTasks: int32(opts.MaxBlockingTasks), maxBlockingTasks: int32(opts.MaxBlockingTasks),
panicHandler: opts.PanicHandler, panicHandler: opts.PanicHandler,
lock: SpinLock(),
} }
} else { } else {
p = &Pool{ p = &Pool{
@ -154,9 +155,10 @@ func NewPool(size int, options ...Option) (*Pool, error) {
nonblocking: opts.Nonblocking, nonblocking: opts.Nonblocking,
maxBlockingTasks: int32(opts.MaxBlockingTasks), maxBlockingTasks: int32(opts.MaxBlockingTasks),
panicHandler: opts.PanicHandler, panicHandler: opts.PanicHandler,
lock: SpinLock(),
} }
} }
p.cond = sync.NewCond(&p.lock) p.cond = sync.NewCond(p.lock)
// Start a goroutine to clean up expired workers periodically. // Start a goroutine to clean up expired workers periodically.
go p.periodicallyPurge() go p.periodicallyPurge()

View File

@ -46,7 +46,7 @@ type PoolWithFunc struct {
release int32 release int32
// lock for synchronous operation. // lock for synchronous operation.
lock sync.Mutex lock sync.Locker
// cond for waiting to get a idle worker. // cond for waiting to get a idle worker.
cond *sync.Cond cond *sync.Cond
@ -154,6 +154,7 @@ func NewPoolWithFunc(size int, pf func(interface{}), options ...Option) (*PoolWi
nonblocking: opts.Nonblocking, nonblocking: opts.Nonblocking,
maxBlockingTasks: int32(opts.MaxBlockingTasks), maxBlockingTasks: int32(opts.MaxBlockingTasks),
panicHandler: opts.PanicHandler, panicHandler: opts.PanicHandler,
lock: SpinLock(),
} }
} else { } else {
p = &PoolWithFunc{ p = &PoolWithFunc{
@ -163,9 +164,10 @@ func NewPoolWithFunc(size int, pf func(interface{}), options ...Option) (*PoolWi
nonblocking: opts.Nonblocking, nonblocking: opts.Nonblocking,
maxBlockingTasks: int32(opts.MaxBlockingTasks), maxBlockingTasks: int32(opts.MaxBlockingTasks),
panicHandler: opts.PanicHandler, panicHandler: opts.PanicHandler,
lock: SpinLock(),
} }
} }
p.cond = sync.NewCond(&p.lock) p.cond = sync.NewCond(p.lock)
// Start a goroutine to clean up expired workers periodically. // Start a goroutine to clean up expired workers periodically.
go p.periodicallyPurge() go p.periodicallyPurge()

27
spinlock.go Normal file
View File

@ -0,0 +1,27 @@
// Copyright 2019 Andy Pan. All rights reserved.
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
package ants
import (
"runtime"
"sync"
"sync/atomic"
)
type spinLock uint32
func (sl *spinLock) Lock() {
for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) {
runtime.Gosched()
}
}
func (sl *spinLock) Unlock() {
atomic.StoreUint32((*uint32)(sl), 0)
}
func SpinLock() sync.Locker {
return new(spinLock)
}