Add FIFO, implement scheduler timestep

This commit is contained in:
teknomunk 2024-04-08 08:45:53 +00:00
parent d40b52bea5
commit 3baf1a2f17
2 changed files with 98 additions and 1 deletions

View file

@ -0,0 +1,44 @@
local mod = mcl_scheduler
function Class()
local cls = {}
cls.mt = { __index = cls }
function cls:new(...)
local inst = setmetatable({}, cls.mt)
local construct = inst.construct
if construct then inst:construct(...) end
return inst
end
return cls
end
-- Amoritized O(1) insert/delete functional First In, First Out (FIFO) queue
local fifo = Class()
mod.fifo = fifo
function fifo.insert(node)
node.next = fifo.inbox
fifo.inbox = node.next
end
function fifo.get()
if not fifo.outbox then
-- reverse inbox
local iter = fifo.inbox
fifo.inbox = nil
while iter do
local i = iter
iter = iter.next
i.next = fifo.outbox
fifo.outbox = i
end
end
local res = fifo.outbox
if res then
fifo.outbox = res.next
res.next = nil
end
return res
end

View file

@ -5,6 +5,7 @@ mcl_scheduler = {}
local mod = mcl_scheduler local mod = mcl_scheduler
dofile(modpath.."/queue.lua") dofile(modpath.."/queue.lua")
dofile(modpath.."/fifo.lua")
function mod.test() function mod.test()
local t = mod.queue.new() local t = mod.queue.new()
@ -35,5 +36,57 @@ function mod.test()
end end
end end
mod.test() local run_queues = {}
for i = 1,4 do
run_queues[i] = mod.fifo:new()
end
local time = 0
local priority_queue = mod.queue:new()
local functions = {}
print(dump(run_queues))
minetest.register_globalstep(function(dtime)
local start_time = minetest.get_us_time()
time = time + dtime
local limit = 4
while time > 0.05 and limit > 0 do
-- Add tasks to the run queues
local iter = priority_queue:tick()
while iter do
local task = iter
iter = iter.next
local priority = task.priority or 3
run_queues[priority]:insert(task)
end
-- Run tasks until we run out of timeslice
local i = 1
while i < 4 and (minetest.get_us_time() - start_time) < 50000 do
local task = run_queues[i]:get()
if task then
print("Running task "..dump(task))
local func = functions[task.fid]
local cancel = false
if func then
local err
cancel,err = pcall(func, task.dtime, table.unpack(task.args))
if err then
minetest.log("error","Error while running task: err")
end
end
-- Add
if task.period and not cancel then
task.time = task.period
priority_queue:add_task(task)
end
end
end
time = time - 0.05
limit = limit - 1
end
end)