2022-03-08 14:56:53 +03:00
|
|
|
package mutexes
|
|
|
|
|
|
|
|
// pool is a very simply memory pool.
|
|
|
|
type pool struct {
|
2022-11-08 12:35:01 +03:00
|
|
|
current []*rwmutex
|
|
|
|
victim []*rwmutex
|
2022-03-08 14:56:53 +03:00
|
|
|
}
|
|
|
|
|
2022-11-08 12:35:01 +03:00
|
|
|
// Acquire will returns a rwmutex from pool (or alloc new).
|
|
|
|
func (p *pool) Acquire() *rwmutex {
|
2022-03-08 14:56:53 +03:00
|
|
|
// First try the current queue
|
|
|
|
if l := len(p.current) - 1; l >= 0 {
|
2022-11-08 12:35:01 +03:00
|
|
|
mu := p.current[l]
|
2022-03-08 14:56:53 +03:00
|
|
|
p.current = p.current[:l]
|
2022-11-08 12:35:01 +03:00
|
|
|
return mu
|
2022-03-08 14:56:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Next try the victim queue.
|
|
|
|
if l := len(p.victim) - 1; l >= 0 {
|
2022-11-08 12:35:01 +03:00
|
|
|
mu := p.victim[l]
|
2022-03-08 14:56:53 +03:00
|
|
|
p.victim = p.victim[:l]
|
2022-11-08 12:35:01 +03:00
|
|
|
return mu
|
2022-03-08 14:56:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Lastly, alloc new.
|
2022-11-08 12:35:01 +03:00
|
|
|
return &rwmutex{}
|
2022-03-08 14:56:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Release places a sync.RWMutex back in the pool.
|
2022-11-08 12:35:01 +03:00
|
|
|
func (p *pool) Release(mu *rwmutex) {
|
|
|
|
p.current = append(p.current, mu)
|
2022-03-08 14:56:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// GC will clear out unused entries from the pool.
|
|
|
|
func (p *pool) GC() {
|
|
|
|
current := p.current
|
|
|
|
p.current = nil
|
|
|
|
p.victim = current
|
|
|
|
}
|