central-arch/pkg/sim/scheduler.go

103 lines
2.5 KiB
Go
Raw Normal View History

2024-11-01 10:54:59 +00:00
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
}