package sim import ( "log" "sync" "time" "git.elyanpoujol.fr/elyan/central-arch/pkg/breakcfg" "git.elyanpoujol.fr/elyan/central-arch/pkg/events" "git.elyanpoujol.fr/elyan/central-arch/pkg/simstep" ) type SchedulerConfig struct { BreakableEventConfig *breakcfg.BreakableEventConfig } type Scheduler struct { config SchedulerConfig cpuBreakpoints map[CpuBreakpoint]bool cpuWatchpoints map[CpuWatchpoint]bool cpuModeTransitionBreakType CpuModeTransitionBreakType stepRequest chan events.SimEvent stepResponse chan bool commandRequest chan Command commandReponse chan bool breakEvent chan *Sim quitEvent <-chan bool } func NewScheduler(config SchedulerConfig, quitEvent <-chan bool) *Scheduler { return &Scheduler{ config: config, cpuBreakpoints: make(map[CpuBreakpoint]bool), cpuWatchpoints: make(map[CpuWatchpoint]bool), // When the scheduler stopped running, we don't want the client to block // when sending to this channel stepRequest: make(chan events.SimEvent, 1), stepResponse: make(chan bool), // When the scheduler stopped running, we don't want the client to block // when sending to this channel commandRequest: make(chan Command, 1), commandReponse: make(chan bool), breakEvent: make(chan *Sim), quitEvent: quitEvent, } } func (s *Scheduler) Run(wg *sync.WaitGroup) { wg.Add(1) defer wg.Done() for { select { case <-s.quitEvent: s.closeSendingChannels() return case req := <-s.stepRequest: s.handleStepRequest(req) case cmd := <-s.commandRequest: s.handleSchedulingCommand(cmd) } } } func (s *Scheduler) closeSendingChannels() { close(s.stepResponse) close(s.commandReponse) close(s.breakEvent) } func (s *Scheduler) Cleanup() { close(s.stepRequest) close(s.commandRequest) } func (s *Scheduler) handleStepRequest(req simstep.SimStepRequest) { // TODO Handle request // TODO Check breakpoints log.Println("step !") time.Sleep(time.Second) s.stepResponse <- true } func (s *Scheduler) handleSchedulingCommand(cmd Command) { // TODO Handle scheduling command } func (s *Scheduler) RequestStep(req simstep.SimStepRequest) error { s.stepRequest <- req // The scheduler always sends true, to receive false means that the channel is closed // and thus, that we must quit doContinue := <-s.stepResponse if !doContinue { return simstep.SimQuitRequest } return nil }