diff options
Diffstat (limited to 'pkg/instance/instance.go')
| -rw-r--r-- | pkg/instance/instance.go | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go index b393991d0..1a504fdd7 100644 --- a/pkg/instance/instance.go +++ b/pkg/instance/instance.go @@ -36,6 +36,7 @@ type Env interface { type env struct { cfg *mgrconfig.Config optionalFlags bool + buildSem *Semaphore } type BuildKernelConfig struct { @@ -48,7 +49,7 @@ type BuildKernelConfig struct { KernelConfig []byte } -func NewEnv(cfg *mgrconfig.Config) (Env, error) { +func NewEnv(cfg *mgrconfig.Config, buildSem *Semaphore) (Env, error) { if !vm.AllowsOvercommit(cfg.Type) { return nil, fmt.Errorf("test instances are not supported for %v VMs", cfg.Type) } @@ -67,11 +68,16 @@ func NewEnv(cfg *mgrconfig.Config) (Env, error) { env := &env{ cfg: cfg, optionalFlags: true, + buildSem: buildSem, } return env, nil } func (env *env) BuildSyzkaller(repoURL, commit string) (string, error) { + if env.buildSem != nil { + env.buildSem.Wait() + defer env.buildSem.Signal() + } cfg := env.cfg srcIndex := strings.LastIndex(cfg.Syzkaller, "/src/") if srcIndex == -1 { @@ -126,6 +132,10 @@ func (env *env) BuildSyzkaller(repoURL, commit string) (string, error) { func (env *env) BuildKernel(buildCfg *BuildKernelConfig) ( string, build.ImageDetails, error) { + if env.buildSem != nil { + env.buildSem.Wait() + defer env.buildSem.Signal() + } imageDir := filepath.Join(env.cfg.Workdir, "image") params := build.Params{ TargetOS: env.cfg.TargetOS, @@ -536,3 +546,43 @@ func RunnerCmd(prog, fwdAddr, os, arch string, poolIdx, vmIdx int, threaded, new return fmt.Sprintf("%s -addr=%s -os=%s -arch=%s -pool=%d -vm=%d "+ "-threaded=%t -new-env=%t", prog, fwdAddr, os, arch, poolIdx, vmIdx, threaded, newEnv) } + +type Semaphore struct { + ch chan struct{} +} + +func NewSemaphore(count int) *Semaphore { + s := &Semaphore{ + ch: make(chan struct{}, count), + } + for i := 0; i < count; i++ { + s.Signal() + } + return s +} + +func (s *Semaphore) Wait() { + <-s.ch +} + +func (s *Semaphore) WaitAll() { + for i := 0; i < cap(s.ch); i++ { + s.Wait() + } +} + +func (s *Semaphore) WaitC() <-chan struct{} { + return s.ch +} + +func (s *Semaphore) Available() int { + return len(s.ch) +} + +func (s *Semaphore) Signal() { + if av := s.Available(); av == cap(s.ch) { + // Not super reliable, but let it be here just in case. + panic(fmt.Sprintf("semaphore capacity (%d) is exceeded (%d)", cap(s.ch), av)) + } + s.ch <- struct{}{} +} |
