detect_time_jump.lua 1.29 KB
Newer Older
1 2 3 4 5 6 7 8
-- Module interface
local ffi = require('ffi')

local mod = {}
mod.threshold = 10 * min
local event_id = nil

-- Get time of last cache clear. Compute difference between realtime
9
-- and monotonic time. Compute difference of actual realtime and monotonic
10 11 12
-- time. In ideal case these differences should be almost same.
-- If they differ more than mod.threshold value then clear cache.
local function check_time()
13 14
	local checkpoint = cache.checkpoint()
	local cache_timeshift = checkpoint.walltime.sec * 1000 - checkpoint.monotime
15
	local actual_timeshift = os.time() * 1000 - tonumber(ffi.C.kr_now())
16 17 18
	local jump_backward = cache_timeshift - actual_timeshift
	if jump_backward > mod.threshold then
		log("Detected backwards time jump, clearing cache.\n" ..
19 20 21
		"But what does that mean? It means your future hasn't been written yet."
		)
		cache.clear()
22
	elseif -jump_backward > mod.threshold then
23
		-- On Linux 4.17+ this shouldn't happen anymore: https://lwn.net/Articles/751482/
24 25
		log("Detected forward time jump.  (Suspend-resume, possibly.)")
		cache.checkpoint(true)
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
	end
end

function mod.init()
	if event_id then
		error("Module is already loaded.")
	else
		event_id = event.recurrent(1 * min , check_time)
	end
end

function mod.deinit()
	if event_id then
		event.cancel(event_id)
		event_id = nil
	end
end

return mod