mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-19 01:21:05 +01:00
Add FIFO, implement scheduler timestep
This commit is contained in:
parent
d40b52bea5
commit
3baf1a2f17
2 changed files with 98 additions and 1 deletions
44
mods/CORE/mcl_scheduler/fifo.lua
Normal file
44
mods/CORE/mcl_scheduler/fifo.lua
Normal 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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue