Incorrect Machine.ticks values after resuming from suspend state on Linux machine
On Linux, resuming machine from suspend state makes some runnning active objects in A2 hang. One example is active object KernelLogger in KernelLogger.Mod. Another example is active object TrapWriter in TrapWriters.Mod. Maybe there are other such active objects.
Problem is with Unix.Machine.ticks. All these active objects call Unix.Objects.SetTimeout which is using Unix.Machine.ticks.
Because of incorrect handling of Machine.ticks after linux machine resumed from suspend state execution stops in Unix.Objects.Mod in object GetTimerActivity
Execution stops in this object on line: AWAIT( (Machine.ticks >= t.trigger) OR restart ); restart := FALSE; This is because after linux resumes from suspend state Machine.ticks are counted again from zero. Module Unix.Machine.Mod calculates them incorrectly using initial timer0 value which results in Machine.ticks having lower or even negative values. It then takes usually long time for Machine.ticks to reach previous value before machine suspend. As a consequence active objects using this sleeping method are frozen for a long time.
There is simple solution for this problem. Replace procedure UpdateTicks in Unix.Machine.Mod
PROCEDURE UpdateTicks*;
BEGIN
IF timerFrequency # 0 THEN
ticks := SHORT( (GetTimer() - timer0) *1000 DIV (timerFrequency) );
END;
END UpdateTicks;
with following one:
PROCEDURE UpdateTicks*;
VAR nticks: SIGNED32;
BEGIN
IF timerFrequency # 0 THEN
nticks := SHORT( (GetTimer() - timer0) * 1000 DIV (timerFrequency) );
IF nticks < lticks THEN tickdif := lticks - nticks END; (* this is here because timer values start from zero after linux machine resumes from suspend state! *)
ticks := nticks + tickdif;
lticks := nticks;
END;
END UpdateTicks;
and add lticks,tickdif: SIGNED32;
into global variables.
This procedure detects situation when linux machine resumed from suspend state given that new ticks are smaller than last ticks. This should solve the described problem.