Przeglądaj źródła

Supress glitches by adding read mutexes

Alexey Edelev 5 lat temu
rodzic
commit
1e00ac28bb
1 zmienionych plików z 18 dodań i 0 usunięć
  1. 18 0
      neuralnetwork/snakesimulator/snakesimulator.go

+ 18 - 0
neuralnetwork/snakesimulator/snakesimulator.go

@@ -7,6 +7,7 @@ import (
 	"math/rand"
 	"net"
 	"sort"
+	"sync"
 	"time"
 
 	"gonum.org/v1/gonum/mat"
@@ -28,6 +29,9 @@ type SnakeSimulator struct {
 	snakeUpdateQueue chan bool
 	statsUpdateQueue chan bool
 	speedQueue       chan uint32
+
+	snakeReadMutex sync.Mutex
+	fieldReadMutex sync.Mutex
 }
 
 // Initializes new snake population with maximum number of verification steps
@@ -86,7 +90,9 @@ func (s *SnakeSimulator) Verify(population *genetic.Population) (fitnesses []*ge
 	})
 
 	//Best snake showtime!
+	s.fieldReadMutex.Lock()
 	s.field.GenerateNextFood()
+	s.fieldReadMutex.Unlock()
 	s.fieldUpdateQueue <- true
 	prevSpeed := s.speed
 	s.speed = 5
@@ -96,12 +102,14 @@ func (s *SnakeSimulator) Verify(population *genetic.Population) (fitnesses []*ge
 }
 
 func (s *SnakeSimulator) runSnake(inidividual *neuralnetwork.NeuralNetwork, randomStart bool) {
+	s.snakeReadMutex.Lock()
 	if randomStart {
 		rand.Seed(time.Now().UnixNano())
 		s.snake = NewSnake(Direction(rand.Uint32()%4), *s.field)
 	} else {
 		s.snake = NewSnake(Direction_Left, *s.field)
 	}
+	s.snakeReadMutex.Unlock()
 
 	s.stats.Move = 0
 	for i := 0; i < s.maxVerificationSteps; i++ {
@@ -134,13 +142,19 @@ func (s *SnakeSimulator) runSnake(inidividual *neuralnetwork.NeuralNetwork, rand
 			break
 		} else if foodCollision(newHead, s.field.Food) {
 			i = 0
+			s.snakeReadMutex.Lock()
 			s.snake.Feed(newHead)
+			s.snakeReadMutex.Unlock()
+			s.fieldReadMutex.Lock()
 			s.field.GenerateNextFood()
+			s.fieldReadMutex.Unlock()
 			if s.speed > 0 {
 				s.fieldUpdateQueue <- true
 			}
 		} else {
+			s.snakeReadMutex.Lock()
 			s.snake.Move(newHead)
+			s.snakeReadMutex.Unlock()
 		}
 		s.stats.Move++
 	}
@@ -358,7 +372,9 @@ func (s *SnakeSimulator) Field(_ *None, srv SnakeSimulator_FieldServer) error {
 			return ctx.Err()
 		default:
 		}
+		s.snakeReadMutex.Lock()
 		srv.Send(s.field)
+		s.snakeReadMutex.Unlock()
 		<-s.fieldUpdateQueue
 	}
 }
@@ -386,7 +402,9 @@ func (s *SnakeSimulator) Stats(_ *None, srv SnakeSimulator_StatsServer) error {
 			return ctx.Err()
 		default:
 		}
+		s.fieldReadMutex.Lock()
 		srv.Send(s.stats)
+		s.fieldReadMutex.Unlock()
 		<-s.statsUpdateQueue
 	}
 }