151 lines
6.6 KiB
Plaintext
151 lines
6.6 KiB
Plaintext
--:Minify:--
|
|
local kernel=...
|
|
local alpha = 0.85
|
|
local C_target = 0.01
|
|
local Tmin = 0.0005
|
|
local Tmax = 0.5
|
|
local lambda_budget = 0.08
|
|
local lambda_clamp = 0.03
|
|
local lambda_var = 0.02
|
|
local k_min = 0.5
|
|
local k_max = 0.5
|
|
local B = 0.01
|
|
|
|
function kernel.main()
|
|
kernel.log("Starting main loop...")
|
|
kernel.saveLog()
|
|
local stopLog=5
|
|
local logTasks=100
|
|
|
|
while not kernel.exitMain do
|
|
if kernel.config.logTasks then
|
|
if logTasks<0 then
|
|
kernel.log("Active Tasks:")
|
|
for i,v in pairs(kernel.tasks) do
|
|
kernel.log(v.name.." : "..v.status.." : "..tostring(v.pid).." : "..tostring(v.exit))
|
|
end
|
|
kernel.log("[END BLOCK]")
|
|
logTasks=100
|
|
end
|
|
logTasks=logTasks-1
|
|
end
|
|
local N = 0
|
|
local Tmin_hit = 0
|
|
local Tmax_hit = 0
|
|
local totalTaskTime = 0
|
|
local taskTimes = {}
|
|
|
|
for pid, task in pairs(kernel.tasks) do
|
|
if kernel.exitMain then break end
|
|
|
|
for _,list in ipairs(kernel.perTaskHooks) do
|
|
for id,hook in ipairs(list) do
|
|
local ok,err = xpcall(hook, debug.traceback, task, pid)
|
|
if not ok then
|
|
kernel.log("[MAIN HOOK ERR]: "..err, "ERROR", 0xFF0000)
|
|
list[id]=nil
|
|
end
|
|
end
|
|
end
|
|
|
|
if task.status == "R" then
|
|
N = N + 1
|
|
task.timeSlice = math.min(Tmax, math.max(Tmin, B / (N ^ alpha)))
|
|
if task.status == "R" then
|
|
local startTime = kernel.EFI:getEpochMs()
|
|
local ret
|
|
if stopLog > 0 then
|
|
kernel.log("Running task " .. tostring(task.pid) .. " (" .. task.name .. ") with time slice " .. string.format("%.3f", task.timeSlice) .. "s", "DBUG", 0x00FFFF)
|
|
end
|
|
if kernel.config.preempt then
|
|
if not task.debugger then
|
|
ret = { kernel.EFI.resumeWithTimeout(task.coro, task.timeSlice, table.unpack(task.syscallReturn)) }
|
|
else
|
|
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
|
|
end
|
|
else
|
|
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
|
|
end
|
|
|
|
local elapsed = kernel.EFI:getEpochMs() - startTime
|
|
task.lastTime = elapsed
|
|
task.totalTime = (task.totalTime or 0) + elapsed
|
|
task.numRuns = (task.numRuns or 0) + 1
|
|
|
|
taskTimes[#taskTimes+1] = elapsed
|
|
totalTaskTime = totalTaskTime + elapsed
|
|
|
|
if elapsed <= Tmin then Tmin_hit = Tmin_hit + 1 end
|
|
if elapsed >= Tmax then Tmax_hit = Tmax_hit + 1 end
|
|
|
|
if ret[1] == "error" or ret[1] == false then
|
|
kernel.log("processHandlerException: " .. tostring(ret[2]), "ERROR", 0xFF0000)
|
|
task.status = "Z"
|
|
task.exit = "processHandlerException: " .. tostring(ret[2])
|
|
|
|
elseif ret[1] == "timeout" then
|
|
task.ivs = task.ivs + 1
|
|
task.syscallReturn = {}
|
|
|
|
elseif ret[1] == "success" or ret[1] == true then
|
|
task.vs = task.vs + 1
|
|
|
|
if ret[2] == "syscall" then
|
|
local scname = ret[3]
|
|
if kernel.syscalls[scname] then
|
|
if kernel.config.debugSyscalls then
|
|
kernel.log("Task " .. task.pid .. " syscall: " .. scname, "DBUG", 0x00FFFF)
|
|
for i = 4, #ret do
|
|
kernel.log(" inval[" .. (i-3) .. "] = " .. tostring(ret[i]), "DBUG", 0x00FFFF)
|
|
end
|
|
end
|
|
|
|
local sysret = { xpcall(kernel.syscalls[scname], debug.traceback, table.unpack(ret, 4)) }
|
|
|
|
if kernel.config.debugSyscalls then
|
|
if not sysret[1] then
|
|
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " failed: " .. tostring(sysret[2]), "ERROR", 0xFF0000)
|
|
else
|
|
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " ok, " .. (#sysret-1) .. " retvals", "DBUG", 0x00FFFF)
|
|
for i = 2, #sysret do
|
|
local v = type(sysret[i]) == "table" and table.serialize(sysret[i]) or tostring(sysret[i])
|
|
kernel.log(" retval[" .. (i-1) .. "] = " .. v, "DBUG", 0x00FFFF)
|
|
end
|
|
end
|
|
end
|
|
|
|
if not sysret[1] then
|
|
task.syscallReturn = { false, sysret[2] }
|
|
else
|
|
task.syscallReturn = { true, table.unpack(sysret, 2) }
|
|
end
|
|
else
|
|
task.syscallReturn = { false, "Unknown syscall: " .. tostring(scname) }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local T_prev_avg = (N > 0) and (totalTaskTime / N) or 0
|
|
local T_prev_var = 0
|
|
for _, t in ipairs(taskTimes) do
|
|
T_prev_var = T_prev_var + (t - T_prev_avg) ^ 2
|
|
end
|
|
if N > 0 then T_prev_var = T_prev_var / N end
|
|
|
|
if N > 0 then
|
|
local f_clamp = k_min * (Tmin_hit / N) - k_max * (Tmax_hit / N)
|
|
local B_budget = (C_target * (N ^ (alpha - 1))) / math.max(T_prev_avg, 1e-8)
|
|
B = B + lambda_budget * (B_budget - B) + lambda_clamp * f_clamp - lambda_var * T_prev_var
|
|
end
|
|
|
|
kernel.hpv.reapDeadTasks()
|
|
if stopLog > 0 then
|
|
kernel.log("Executed " .. N .. " tasks, avg time: " .. string.format("%.2f", T_prev_avg) .. "ms, var: " .. string.format("%.2f", T_prev_var) .. ", B: " .. string.format("%.5f", B))
|
|
stopLog = stopLog - 1
|
|
kernel.saveLog()
|
|
end
|
|
end
|
|
end |