aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/instance/instance.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/instance/instance.go')
-rw-r--r--pkg/instance/instance.go52
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{}{}
+}