1 using System;
 2 using System.Threading;
 3 
 4 namespace cmsx.machine
 5 {
 6     public class ClockDriver
 7     {
 8         public ClockDriver(Clock& clock_) : clock(clock_)
 9         {
10             clock.Start();
11         }
12         public ~ClockDriver()
13         {
14             clock.Stop();
15         }
16         private Clock& clock;
17     }
18 
19     public class Clock
20     {
21         public const long tick = 50;
22 
23         static Clock() : instance(new Clock())
24         {
25         }
26         public static Clock& Instance()
27         {
28             return *instance;
29         }
30         private Clock() : machine(GetMachine())started(false)stopping(false)
31         {
32         }
33         public void Start()
34         {
35             ThreadStartMethod tickMethod = Tick;
36             thread = Thread.StartMethod(tickMethod);
37             started = true;
38         }
39         public void Stop()
40         {
41             if (!started) return;
42             stopping = true;
43             stop.NotifyOne();
44             thread.Join();
45         }
46         private void Tick()
47         {
48             try
49             {
50                 while (!stopping)
51                 {
52                     ConditionVariableStatus status = stop.WaitFor(mtxDuration.FromMilliseconds(tick));
53                     if (status == ConditionVariableStatus.timeout)
54                     {
55                         machine.GetRegisters().SetInterrupt(CLOCK_BIT);
56                     }
57                 }
58             }
59             catch (const Exception& ex)
60             {
61                 Console.Error() << "clock: " << ex.ToString() << endl();
62             }
63         }
64         private static UniquePtr<Clock> instance;
65         private Machine& machine;
66         private RecursiveMutex mtx;
67         private ConditionVariable stop;
68         private Thread thread;
69         private bool started;
70         private bool stopping;
71     }
72 }