forked from VoxeLibre/VoxeLibre
Add FIFO, implement scheduler timestep
This commit is contained in:
parent
2ced3c09aa
commit
e310d10aed
|
@ -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
|
||||
|
|
@ -5,6 +5,7 @@ mcl_scheduler = {}
|
|||
local mod = mcl_scheduler
|
||||
|
||||
dofile(modpath.."/queue.lua")
|
||||
dofile(modpath.."/fifo.lua")
|
||||
|
||||
function mod.test()
|
||||
local t = mod.queue.new()
|
||||
|
@ -35,5 +36,57 @@ function mod.test()
|
|||
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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue