From 8d5aa26b7811b56f199dbf39764b9cdaf5b7e0ef Mon Sep 17 00:00:00 2001 From: Terence Boldt Date: Tue, 31 Oct 2023 23:04:15 -0400 Subject: [PATCH] Add backoff to reduce CPU usage (fixes #141) (#151) * Add backoff to reduce CPU usage * Update driver version for CPU fix --- RaspberryPi/apple2driver/a2io/gpio.go | 28 ++++++++++++++++++++++++ RaspberryPi/apple2driver/driver.go | 5 +---- RaspberryPi/apple2driver/info/version.go | 2 +- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/RaspberryPi/apple2driver/a2io/gpio.go b/RaspberryPi/apple2driver/a2io/gpio.go index f1e8974..c8a3fe5 100644 --- a/RaspberryPi/apple2driver/a2io/gpio.go +++ b/RaspberryPi/apple2driver/a2io/gpio.go @@ -160,11 +160,18 @@ func (a2 A2Gpio) ReadByte() (byte, error) { // wait for the Apple II to write startTime := time.Now() + lastSleepTime := time.Now() + sleepDuration := 10 for inWrite.Read() == 1 { if time.Since(startTime) > edgeTimeout { outRead.High() return 0, errors.New("timed out reading byte -- write stuck high") } + if time.Since(lastSleepTime) > edgeTimeout/10 { + sleepDuration *= 3; + time.Sleep(time.Millisecond * time.Duration(sleepDuration)); + lastSleepTime = time.Now() + } } // get a nibble of data @@ -211,10 +218,17 @@ func (a2 A2Gpio) ReadByte() (byte, error) { // wait for the Apple II to finish writing //fmt.Printf("wait for the Apple II to finish writing\n") startTime = time.Now() + lastSleepTime = time.Now() + sleepDuration = 10 for inWrite.Read() == 0 { if time.Since(startTime) > edgeTimeout { return 0, errors.New("timed out reading byte -- write stuck low") } + if time.Since(lastSleepTime) > edgeTimeout/10 { + sleepDuration *= 3; + time.Sleep(time.Millisecond * time.Duration(sleepDuration)); + lastSleepTime = time.Now() + } } return data, nil @@ -230,11 +244,18 @@ func (a2 A2Gpio) WriteByte(data byte) error { // wait for the Apple II to be ready to read startTime := time.Now() + lastSleepTime := time.Now() + sleepDuration := 10 for inRead.Read() == 1 { if time.Since(startTime) > edgeTimeout { outWrite.High() return errors.New("timed out writing byte -- read stuck high") } + if time.Since(lastSleepTime) > edgeTimeout/10 { + sleepDuration *= 3; + time.Sleep(time.Millisecond * time.Duration(sleepDuration)); + lastSleepTime = time.Now() + } } if ((data & 128) >> 7) == 1 { @@ -291,11 +312,18 @@ func (a2 A2Gpio) WriteByte(data byte) error { // wait for the Apple II to finsih reading //fmt.Printf("wait for the Apple II to finsih reading\n") startTime = time.Now() + lastSleepTime = time.Now() + sleepDuration = 10 for inRead.Read() == 0 { if time.Since(startTime) > edgeTimeout { outWrite.High() return errors.New("timed out writing byte -- read stuck low") } + if time.Since(lastSleepTime) > edgeTimeout/10 { + sleepDuration *= 3; + time.Sleep(time.Millisecond * time.Duration(sleepDuration)); + lastSleepTime = time.Now() + } } // let the Apple II know we are done writing diff --git a/RaspberryPi/apple2driver/driver.go b/RaspberryPi/apple2driver/driver.go index e70421f..d36ed12 100644 --- a/RaspberryPi/apple2driver/driver.go +++ b/RaspberryPi/apple2driver/driver.go @@ -49,15 +49,12 @@ func main() { handlers.SetCommunication(comm) comm.Init() - lastCommandTime := time.Now() - // In case Apple II is waiting, send 0 byte to start comm.WriteByte(0) for { command, err := comm.ReadByte() if err == nil { - lastCommandTime = time.Now() switch command { case resetCommand: handlers.ResetCommand() @@ -77,7 +74,7 @@ func main() { handlers.ShellCommand() } // temporary workaround for busy wait loop heating up the RPi - } else if time.Since(lastCommandTime) > time.Millisecond*100 { + } else { time.Sleep(time.Millisecond * 100) } } diff --git a/RaspberryPi/apple2driver/info/version.go b/RaspberryPi/apple2driver/info/version.go index 1e58632..e71e0bb 100644 --- a/RaspberryPi/apple2driver/info/version.go +++ b/RaspberryPi/apple2driver/info/version.go @@ -8,4 +8,4 @@ package info // Version is the hexadecimal version number that // should be incremented with each driver update -const Version = "0029" +const Version = "002A"