Summary: Can I cause time to (appear to) pass in my script without busywaiting? Using os.execute('sleep 1')
doesn't cut it (and also wastes time).
Details
I have a library that does work after specific intervals. I currently schedule this by injecting a table into a time-sorted list. Roughly:
local delayedWork = {}
function handleLater( data, delaySeconds )
local delayedItem = { data=data, execTime=os.clock() + delaySeconds }
local i=1
for _,existing in ipairs(delayedWork) do
if existing.execTime > delayedItem.execTime then break else i=i+1 end
end
table.insert(delayedWork,i,delayedItem)
end
Later on I periodically check for work to do. Roughly:
function processDelayedWork()
local i,last = 1,#delayedWork
while i<=last do
local delayedItem = delayedWork[i]
if delayedItem.execTime <= os.clock() then
table.remove(delayedWork,i)
-- use delayedItem.data
last = last-1
else
i=i+1
end
end
end
(The fact that this uses CPU time instead of wall time is an issue for a different question. The fact that I repeatedly shift the array during processing instead of one compacting pass is an optimization not relevant here.)
When I am running unit tests of the system I need to cause time to pass, preferably faster than normal. However, calling os.execute('sleep 1')
consumes one wall clock second, but does not cause os.clock()
to increment.
$ lua -e "require 'os' print(os.clock()) os.execute('sleep 1') print(os.clock())"
0.002493
0.002799
I can't use os.time()
because this is only integer seconds (and less than that on systems compiled to use float
instead double
for numbers):
$ lua -e "require 'os' print(os.time()) os.execute('sleep 0.4') print(os.time())"
1397704209
1397704209
Can I force time to pass in my script without just busywaiting?