mirror of
https://github.com/criyle/go-judge.git
synced 2025-11-04 14:50:02 +08:00
linuxc: add cached cgroup implementation
This commit is contained in:
parent
ffdf3e3925
commit
8b9b6f33dc
98
env/linuxcontainer/cgroup_cached_pool_linux.go
vendored
Normal file
98
env/linuxcontainer/cgroup_cached_pool_linux.go
vendored
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package linuxcontainer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ CgroupPool = &CachedCgroupPool{}
|
||||||
|
|
||||||
|
// CachedCgroupPool implements cgroup pool but not actually do pool
|
||||||
|
type CachedCgroupPool struct {
|
||||||
|
builder CgroupBuilder
|
||||||
|
cfsPeriod time.Duration
|
||||||
|
|
||||||
|
cache chan Cgroup
|
||||||
|
destroy chan Cgroup
|
||||||
|
done chan struct{}
|
||||||
|
wg sync.WaitGroup
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFakeCgroupPool creates FakeCgroupPool
|
||||||
|
func NewCachedCgroupPool(builder CgroupBuilder, cfsPeriod time.Duration, workerCount int) CgroupPool {
|
||||||
|
p := &CachedCgroupPool{
|
||||||
|
builder: builder,
|
||||||
|
cfsPeriod: cfsPeriod,
|
||||||
|
cache: make(chan Cgroup, 4),
|
||||||
|
destroy: make(chan Cgroup, 4),
|
||||||
|
done: make(chan struct{}),
|
||||||
|
}
|
||||||
|
p.wg.Add(workerCount)
|
||||||
|
for i := 0; i < workerCount; i++ {
|
||||||
|
go p.loop()
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *CachedCgroupPool) loop() {
|
||||||
|
defer p.wg.Done()
|
||||||
|
var cache Cgroup
|
||||||
|
for {
|
||||||
|
if cache == nil {
|
||||||
|
cg, err := p.builder.Random("")
|
||||||
|
if err != nil {
|
||||||
|
p.err = err
|
||||||
|
close(p.done)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cache = &wCgroup{cg: cg, cfsPeriod: p.cfsPeriod}
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-p.done:
|
||||||
|
return
|
||||||
|
|
||||||
|
case c := <-p.destroy:
|
||||||
|
c.Destroy()
|
||||||
|
|
||||||
|
case p.cache <- cache:
|
||||||
|
cache = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets new cgroup
|
||||||
|
func (p *CachedCgroupPool) Get() (Cgroup, error) {
|
||||||
|
select {
|
||||||
|
case <-p.done:
|
||||||
|
if p.err == nil {
|
||||||
|
return nil, os.ErrClosed
|
||||||
|
}
|
||||||
|
return nil, p.err
|
||||||
|
case c := <-p.cache:
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put destroy the cgroup
|
||||||
|
func (p *CachedCgroupPool) Put(c Cgroup) {
|
||||||
|
p.destroy <- c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shutdown noop
|
||||||
|
func (p *CachedCgroupPool) Shutdown() {
|
||||||
|
close(p.done)
|
||||||
|
p.wg.Wait()
|
||||||
|
|
||||||
|
// drain all cgroups
|
||||||
|
close(p.cache)
|
||||||
|
for c := range p.cache {
|
||||||
|
c.Destroy()
|
||||||
|
}
|
||||||
|
close(p.destroy)
|
||||||
|
for c := range p.destroy {
|
||||||
|
c.Destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user