--: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 ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) } 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 kernel.EFI:yield() 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