Historically, hosts which have a tick size slower than the tick a simulator
wants to implement can't idle effectively and keep good time.
This change allows simulators which call sim_rtcn_tick_ack() to provide
useful idling behavior while still keeping the passage of wall clock time
to time in the simulator accurate.
Also:
- Added more statistics
- Made sleep measurements more precise
- Correct idle sleep decision logic without regard to host tick size
- Fix calibration setup/teardown when host tick size is large (>10ms)
- Generalized large host tick test capability (MS_MIN_GRANULARITY)
- Fixed Windows sim_os_msec() to always use timeGetTime()
- Fixed coschedule routines (that don't mentoin a tmr) to default to
timer 0 and fallback to the internal timer otherwise.
- Removed dependency on sizeof(tv_sec) in timespec structure for MinGW
Clock devices which call sim_register_clock_unit or sim_register_clock_unit_tmr
are best behaved if they use sim_activate_after to schedule their tick events.
When the timer subsystem hasn't gotten fully initialized, devices may
attempt to coschedule schedule events before the clock has gotten
far enough along to be fully initialized. When this happens we now
make sure to avoid the potential for a zero delay which will may cause
an infinite scheduling loop.
Asynchronous clocks are now built for all simulators which are built with
SIM_ASYNCH_IO defined. The default behavior has asynchronous clocks
disabled since this is still experimental, but it can be enabled with
SET TIMER ASYNC.
Catchup clock ticks are now available, but since they're experimental,
they aren't enabled by default. Catchup ticks are only available if the
simulators clock device calls sim_rtcn_tick_ack to acknowledge processing
of clock ticks. The VAX simulators have been modified to leverage this.
Catchup clock ticks can be enabled with SET TIMER CATCHUP
Additionally, an idle threshold is provided which can be used to
influence when clock calibration may be suppressed. The default is not
to suppress calibration activities.
The various timer behaviors are visible with the SHOW TIMER command.
The state of the operating timer facilities is visible with: SHOW CLOCK
Timer events which are queued are visible with the SHOW QUEUE command.
- Timers that schedule their ticks with sim_activate_after() now operate
consistently without having to be the single timer used by a simulator.
- Simulators which dynamically enable the operation of a clock when one
wasn't previously wasn't enabled will disable the internal calibrated timer.
- Generate reasonable messages when presented with erroneous throttle input.
- Add throttling recalibration logic if only if target rate drift exceeds 5%
Reworked all priority adjustment code to leverage a new
sim_os_set_thread_priority API which is coded to use pthreads or OS
priority adjustment APIs as necessary.
These changes facilitate more robust parameter type checking and helps
to identify unexpected coding errors.
Most simulators can now also be compiled with a C++ compiler without
warnings.
Additionally, these changes have also been configured to facilitate easier
backporting of simulator and device simulation modules to run under the
simh v3.9+ SCP framework.
SET CPU IDLE={OS{:n}} where n is the idle stability delay
which is also the clock calibration delay.
A -D switch on a SHOW -D CPU IDLE command will
display the stability delay as will a SHOW CLOCK command.
In the event that there are no active clock devices, no instruction
rate calibration will be performed. This is more likely on simpler
simulators which don't have a full spectrum of standard devices or
possibly when a clock device exists but its use is optional and thus
sometimes it may be disabled.
Each of the speeds greater than 9600bps deliver a character in less than
1ms. Computing inter-character delays in microseconds therefore can't
be precise enough to be well behaved. Measuring the inter-character
delays in instructions (scalled by the calibrated clock) gets us the needed
precision.
The conversion of time to instructions can overflow an int32 when the
current instructions per second is high and the delay interval is high.
We limit the instruction delay to the maximum value available in an int32,
which for essentially all cases won't matter since the resulting delay is used
for a drop dead timeout and doesn't need to be precise or it will be
canceled before it ever fires anyway.
The goals here being to simplify calling code while getting consistent output delivered everywhere it may be useful.
Modified most places which explicitly used sim_log or merely called printf to now avoid doing that and merely call sim_printf().