Add vl_scheduler.after() that acts like after() except it takes a priority as param 2, add tests for background tests, fix appending to existing list for next timestep

This commit is contained in:
teknomunk
2024-11-24 19:10:59 -06:00
parent 83904e1c80
commit 599be9ac95
2 changed files with 85 additions and 6 deletions
mods/CORE/vl_scheduler

@ -144,11 +144,13 @@ local function globalstep(dtime)
-- Launch asynchronous tasks that may be issued any time (background-async)
local next_background_async_task = run_queue[3]
local last_background_async_task = next_background_async_task and next_background_async_task.last
while next_background_async_task and (core.get_us_time() - start) < BUDGET do
local now = core.get_us_time()
while next_background_async_task and (now - start) < BUDGET do
next_background_async_task:func()
local task = next_background_async_task
next_background_async_task = next_background_async_task.next
free_task(task)
now = core.get_us_time()
end
if next_background_async_task then
next_background_async_task.last = last_background_async_task
@ -158,11 +160,13 @@ local function globalstep(dtime)
-- Run tasks that may be run on any timestep (background-main)
local next_background_task = run_queue[4]
local last_background_task = next_background_task and next_background_task.last
while next_background_task and (core.get_us_time() - start) < BUDGET do
local now = core.get_us_time()
while next_background_task and (now - start) < BUDGET do
next_background_task:func()
local task = next_background_task
next_background_task = next_background_task.next
free_task(task)
now = core.get_us_time()
end
if next_background_task then
next_background_task.last = last_background_task
@ -191,6 +195,7 @@ local function queue_task(when, priority, task)
task.next = nil
if queue then
queue.last.next = task
queue.last = task
else
task.last = task
run_queue[priority] = task
@ -215,15 +220,20 @@ local function queue_task(when, priority, task)
end
vl_scheduler.queue_task = queue_task
-- Hijack core.after and redirect to this scheduler
function core.after(time, func, ...)
local function vl_scheduler_after(time, priority, func, ...)
local task = new_task()
task.args = {...}
task.next = nil
task.real_func = func
task.func = function(task) task.real_func(unpack(task.args)) end
local timesteps = math.round(time / 0.05)
queue_task(timesteps, 2, task)
queue_task(timesteps, priority, task)
end
vl_scheduler.after = vl_scheduler_after
-- Hijack core.after and redirect to this scheduler
function core.after(time, func, ...)
vl_scheduler_after(time, 2, func, ...)
end
return vl_scheduler

@ -1,6 +1,8 @@
local posix = require 'posix'
_G.core = {}
_G.dump = dump
dofile("../../../tests/lib/misc_helpers.lua")
local mod_paths = {
vl_scheduler = "./",
}
@ -8,6 +10,11 @@ local mod_paths = {
local on_mods_loaded
local globalsteps = 0
local last_fake_globalstep_dtime
local time_offset = 0
local function fastforward(amount)
time_offset = time_offset + amount
end
local function init_core()
return {
@ -22,7 +29,7 @@ local function init_core()
register_on_mods_loaded = function(func) on_mods_loaded = func end,
get_us_time = function()
local sec, nsec = posix.clock_gettime(0)
return sec * 1e6 + nsec // 1000
return sec * 1e6 + nsec // 1000 + time_offset
end,
}
end
@ -121,5 +128,67 @@ describe('vl_scheduler',function()
call_globalstep(0.05)
assert.is_same(20, num_run)
end)
it('will not run background tasks if over budget with priority = 3',function()
local num_run = 0
local vl_scheduler = _G.vl_scheduler
vl_scheduler.after(0, 2, function()
fastforward(40000)
end)
for i = 1,50 do
vl_scheduler.after(0, 3, function()
fastforward(1000)
num_run = num_run + 1
end)
end
call_globalstep(0.05)
assert.is_same(10, num_run)
while(num_run < 50) do
call_globalstep(0.05)
end
end)
it('will not run background tasks if over budget with priority = 4',function()
local num_run = 0
local vl_scheduler = _G.vl_scheduler
vl_scheduler.after(0, 2, function()
fastforward(40000)
end)
for i = 1,50 do
vl_scheduler.after(0, 4, function()
fastforward(1000)
num_run = num_run + 1
end)
end
call_globalstep(0.05)
assert.is_same(10, num_run)
while(num_run < 50) do
call_globalstep(0.05)
end
end)
it('will not run background tasks if over budget with mixed priority',function()
local num_3_run = 0
local num_4_run = 0
local vl_scheduler = _G.vl_scheduler
vl_scheduler.after(0, 2, function()
fastforward(40000)
end)
for i = 1,10 do
vl_scheduler.after(0, 3, function()
fastforward(500)
num_3_run = num_3_run + 1
end)
end
for i = 1,20 do
vl_scheduler.after(0, 4, function()
fastforward(500)
num_4_run = num_4_run + 1
end)
end
call_globalstep(0.05)
assert.is_same(10, num_3_run)
assert.is_same(10, num_4_run)
while(num_4_run < 20) do
call_globalstep(0.05)
end
end)
end)