I just realized that my new Timeout Register implementation is doing a gettimeofday() on every CPU cycle. Ugh. Way too much overhead.
The Timer register is 27 bit register. The contents of the register are decremented at 512KHz; when it passes 0 (underflows), a fault is signaled.
The minimum time is 1.95 uSecs; the maximum is 4.37 minutes.
The timer is used during early boot to detect device timeouts; Multics uses it for the scheduler tick.
Underflow does not interrupt an instruction in progress; the signaled fault should be delivered between instructions.
The LDT instruction sets the value; STT gets the current value. The SCU/RCU instructions save and restore the value.
The approach I used is to have the LDT instruction save the value and the time-of-day. This allows the computation of the value of the TR at later time by getting the current time-of-day, calculates the delta from the saved time-of-day, and returns a value calculated from that delta
The STT instruction returns that calculated value.
The SCU operation saves the calculated value and the RCU instruction calls the LDT logic to reset the value.
The sim_instr() loop performs that calculation every time through the loop; i.e. twice for every instruction executed.
Assuming the original hardware is ~1 MIP, the resolution of the timer would have been about two instructions.
If the timer is being used for the scheduler tick (I don't know this), and the tick is 60Hz (I don't know this). then the resolution doesn't need to be greater then a couple of hundred Hz.)
So the easy way is to only poll the TR for underflow every few thousand instructions.
Another way would be to have a realtime clock signal decrement the TR; but I suspect that a 512Khz signal would be more overhead then the polling.
A slower realtime clock signal could decrement in larger chunks, decreasing the (unneeded) resolution.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I just realized that my new Timeout Register implementation is doing a gettimeofday() on every CPU cycle. Ugh. Way too much overhead.
The Timer register is 27 bit register. The contents of the register are decremented at 512KHz; when it passes 0 (underflows), a fault is signaled.
The minimum time is 1.95 uSecs; the maximum is 4.37 minutes.
The timer is used during early boot to detect device timeouts; Multics uses it for the scheduler tick.
Underflow does not interrupt an instruction in progress; the signaled fault should be delivered between instructions.
The LDT instruction sets the value; STT gets the current value. The SCU/RCU instructions save and restore the value.
The approach I used is to have the LDT instruction save the value and the time-of-day. This allows the computation of the value of the TR at later time by getting the current time-of-day, calculates the delta from the saved time-of-day, and returns a value calculated from that delta
The STT instruction returns that calculated value.
The SCU operation saves the calculated value and the RCU instruction calls the LDT logic to reset the value.
The sim_instr() loop performs that calculation every time through the loop; i.e. twice for every instruction executed.
Assuming the original hardware is ~1 MIP, the resolution of the timer would have been about two instructions.
If the timer is being used for the scheduler tick (I don't know this), and the tick is 60Hz (I don't know this). then the resolution doesn't need to be greater then a couple of hundred Hz.)
So the easy way is to only poll the TR for underflow every few thousand instructions.
Another way would be to have a realtime clock signal decrement the TR; but I suspect that a 512Khz signal would be more overhead then the polling.
A slower realtime clock signal could decrement in larger chunks, decreasing the (unneeded) resolution.