Skip to content

Commit

Permalink
Replace mutex with spin-lock
Browse files Browse the repository at this point in the history
  • Loading branch information
panjf2000 committed Sep 27, 2019
1 parent 09973e8 commit e73db1d
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
6 changes: 4 additions & 2 deletions pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type Pool struct {
release int32

// lock for synchronous operation.
lock sync.Mutex
lock sync.Locker

// cond for waiting to get a idle worker.
cond *sync.Cond
Expand Down Expand Up @@ -146,6 +146,7 @@ func NewPool(size int, options ...Option) (*Pool, error) {
nonblocking: opts.Nonblocking,
maxBlockingTasks: int32(opts.MaxBlockingTasks),
panicHandler: opts.PanicHandler,
lock: SpinLock(),
}
} else {
p = &Pool{
Expand All @@ -154,9 +155,10 @@ func NewPool(size int, options ...Option) (*Pool, error) {
nonblocking: opts.Nonblocking,
maxBlockingTasks: int32(opts.MaxBlockingTasks),
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.
go p.periodicallyPurge()
Expand Down
6 changes: 4 additions & 2 deletions pool_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type PoolWithFunc struct {
release int32

// lock for synchronous operation.
lock sync.Mutex
lock sync.Locker

// cond for waiting to get a idle worker.
cond *sync.Cond
Expand Down Expand Up @@ -154,6 +154,7 @@ func NewPoolWithFunc(size int, pf func(interface{}), options ...Option) (*PoolWi
nonblocking: opts.Nonblocking,
maxBlockingTasks: int32(opts.MaxBlockingTasks),
panicHandler: opts.PanicHandler,
lock: SpinLock(),
}
} else {
p = &PoolWithFunc{
Expand All @@ -163,9 +164,10 @@ func NewPoolWithFunc(size int, pf func(interface{}), options ...Option) (*PoolWi
nonblocking: opts.Nonblocking,
maxBlockingTasks: int32(opts.MaxBlockingTasks),
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.
go p.periodicallyPurge()
Expand Down
27 changes: 27 additions & 0 deletions spinlock.go
Original file line number Diff line number Diff line change
@@ -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)
}

0 comments on commit e73db1d

Please sign in to comment.