1 //
2 // Copyright (c) 2010-2022 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using System.Threading;
10 
11 namespace Antmicro.Renode.Peripherals.CPU
12 {
13     public class Synchronizer
14     {
Synchronizer()15         public Synchronizer()
16         {
17             Guard = new object();
18         }
19 
StepFinished()20         public void StepFinished()
21         {
22             lock(Guard)
23             {
24                 if(counter > 0)
25                 {
26                     counter--;
27                 }
28                 if(counter == 0)
29                 {
30                     Monitor.Pulse(Guard);
31                 }
32             }
33         }
34 
CommandStep(int steps = 1)35         public void CommandStep(int steps = 1)
36         {
37             lock(Guard)
38             {
39                 counter = steps;
40                 Monitor.Pulse(Guard);
41             }
42         }
43 
WaitForStepCommand()44         public bool WaitForStepCommand()
45         {
46             lock(Guard)
47             {
48                 while(enabled && counter == 0)
49                 {
50                     Monitor.Wait(Guard);
51                 }
52                 return enabled;
53             }
54         }
55 
WaitForStepFinished()56         public void WaitForStepFinished()
57         {
58             lock(Guard)
59             {
60                 while(counter > 0)
61                 {
62                     Monitor.Wait(Guard);
63                 }
64             }
65         }
66 
StepInterrupted()67         public void StepInterrupted()
68         {
69             lock(Guard)
70             {
71                 counter = 0;
72                 Monitor.Pulse(Guard);
73             }
74         }
75 
76         public object Guard { get; }
77 
78         public bool Enabled
79         {
80             get
81             {
82                 return enabled;
83             }
84             set
85             {
86                 lock(Guard)
87                 {
88                     enabled = value;
89                     if(!enabled)
90                     {
91                         Monitor.PulseAll(Guard);
92                     }
93                 }
94             }
95         }
96 
97         private bool enabled;
98         private int counter;
99     }
100 }
101 
102