1
0
mirror of https://github.com/20kdc/OC-KittenOS.git synced 2024-11-27 04:48:05 +11:00

Add memory benchmark tool to repository, perform more memopt!

This commit is contained in:
20kdc 2018-04-26 16:13:42 +01:00
parent f6a13c4038
commit 51c417b55c
9 changed files with 266 additions and 215 deletions

View File

@ -8,18 +8,13 @@ local donkonitSPProvider = neo.requireAccess("r.neo.sys.manage", "creating NEO c
local donkonitRDProvider = neo.requireAccess("r.neo.sys.screens", "creating NEO core APIs") local donkonitRDProvider = neo.requireAccess("r.neo.sys.screens", "creating NEO core APIs")
local glacierDCProvider = neo.requireAccess("r.neo.pub.globals", "creating NEO core APIs") local glacierDCProvider = neo.requireAccess("r.neo.pub.globals", "creating NEO core APIs")
local computer = neo.requireAccess("k.computer", "shutting down") local shutdownFin = neo.requireAccess("k.computer", "shutting down").shutdown
local fs = neo.requireAccess("c.filesystem", "settings I/O") local primary = neo.requireAccess("c.filesystem", "settings I/O").primary
local gpus = neo.requireAccess("c.gpu", "screen control") local gpus = neo.requireAccess("c.gpu", "screen control").list
local screens = neo.requireAccess("c.screen", "screen control") local screens = neo.requireAccess("c.screen", "screen control").list
neo.requireAccess("s.h.component_added", "HW management") neo.requireAccess("s.h.component_added", "HW management")
neo.requireAccess("s.h.component_removed", "HW management") neo.requireAccess("s.h.component_removed", "HW management")
local function shutdownFin(reboot)
-- any final actions donkonit needs to take here
computer.shutdown(reboot)
end
-- keys are pids -- keys are pids
local targs = {} -- settings notify targs local targs = {} -- settings notify targs
local targsDC = {} -- displaycontrol settings notify targs local targsDC = {} -- displaycontrol settings notify targs
@ -50,7 +45,7 @@ local function loadSettings()
pcall(function () pcall(function ()
local fw = require("sys-filewrap").create local fw = require("sys-filewrap").create
local se = require("serial").deserialize local se = require("serial").deserialize
local st = fw(fs.primary, "data/sys-glacier/sysconf.lua", false) local st = fw(primary, "data/sys-glacier/sysconf.lua", false)
local cfg = st.read("*a") local cfg = st.read("*a")
st.close() st.close()
st = nil st = nil
@ -65,11 +60,12 @@ local function loadSettings()
end end
end) end)
end end
local function saveSettings() local function saveSettings()
local fw = require("sys-filewrap").create local fw = require("sys-filewrap").create
local se = require("serial").serialize local se = require("serial").serialize
fs.primary.makeDirectory("data/sys-glacier") primary.makeDirectory("data/sys-glacier")
local st = fw(fs.primary, "data/sys-glacier/sysconf.lua", true) local st = fw(primary, "data/sys-glacier/sysconf.lua", true)
st.write(se(settings)) st.write(se(settings))
st.close() st.close()
end end
@ -83,7 +79,7 @@ local currentGPUBinding = {}
-- [gpuAddr] = userCount -- [gpuAddr] = userCount
local currentGPUUsers = {} local currentGPUUsers = {}
-- Thanks to Skye for this! -- Thanks to Skye for this design!
local keyboardMonCacheK, keyboardMonCacheV = nil local keyboardMonCacheK, keyboardMonCacheV = nil
local function announceFreeMonitor(address, except) local function announceFreeMonitor(address, except)
@ -94,40 +90,6 @@ local function announceFreeMonitor(address, except)
end end
end end
local function getGPU(monitor)
local bestG, bestStats = nil, {-math.huge, -math.huge, -math.huge}
currentGPUBinding = {}
for v in gpus.list() do
v.bind(monitor.address, false)
local w, h = v.maxResolution()
local quality = w * h * v.maxDepth()
local users = (currentGPUUsers[v.address] or 0)
local gquality = 0
for scr in screens.list() do
v.bind(scr.address, false)
w, h = v.maxResolution()
local squality = w * h * v.maxDepth()
gquality = math.max(gquality, squality)
end
local stats = {quality, -users, -gquality}
for i = 1, #stats do
if stats[i] > bestStats[i] then
bestG = v
bestStats = stats
break
elseif stats[i] < bestStats[i] then
break
end
end
end
if bestG then
neo.emergency("glacier bound " .. monitor.address .. " to " .. bestG.address)
else
neo.emergency("glacier failed to bind " .. monitor.address)
end
return bestG
end
local function sRattle(name, val) local function sRattle(name, val)
for _, v in pairs(targs) do for _, v in pairs(targs) do
v("set_setting", name, val) v("set_setting", name, val)
@ -148,32 +110,6 @@ local function getMonitorSettings(a)
w, h, d = math.floor(w), math.floor(h), math.floor(d) w, h, d = math.floor(w), math.floor(h), math.floor(d)
return w, h, d, t return w, h, d, t
end end
local function setupMonitor(gpu, monitor)
monitor.setPrecise(true)
monitor.turnOn()
gpu.bind(monitor.address, false)
currentGPUBinding[gpu.address] = monitor.address
local maxW, maxH = gpu.maxResolution()
local maxD = gpu.maxDepth()
local w, h, d, t = getMonitorSettings(monitor.address)
w, h, d = math.min(w, maxW), math.min(h, maxH), math.min(d, maxD)
if monitor.setTouchModeInverted then
monitor.setTouchModeInverted(t == "yes")
else
t = "no"
end
settings["scr.w." .. monitor.address] = tostring(w)
settings["scr.h." .. monitor.address] = tostring(h)
settings["scr.d." .. monitor.address] = tostring(d)
settings["scr.t." .. monitor.address] = t
sRattle("scr.w." .. monitor.address, tostring(w))
sRattle("scr.h." .. monitor.address, tostring(h))
sRattle("scr.d." .. monitor.address, tostring(d))
sRattle("scr.t." .. monitor.address, t)
gpu.setResolution(w, h)
gpu.setDepth(d)
pcall(saveSettings)
end
donkonitSPProvider(function (pkg, pid, sendSig) donkonitSPProvider(function (pkg, pid, sendSig)
targs[pid] = sendSig targs[pid] = sendSig
@ -228,12 +164,12 @@ donkonitSPProvider(function (pkg, pid, sendSig)
v("shutdown", reboot, function () v("shutdown", reboot, function ()
counter = counter - 1 counter = counter - 1
if counter == 0 then if counter == 0 then
shutdownFin(reboot) shutdownFin(shutdownMode)
end end
end) end)
end end
if counter == 0 then if counter == 0 then
shutdownFin(reboot) shutdownFin(shutdownMode)
end end
-- donkonit will shutdown when the timer is hit. -- donkonit will shutdown when the timer is hit.
end end
@ -253,7 +189,7 @@ donkonitRDProvider(function (pkg, pid, sendSig)
if keyboardMonCacheK == kb then if keyboardMonCacheK == kb then
return keyboardMonCacheV return keyboardMonCacheV
end end
for v in screens.list() do for v in screens() do
for _, v2 in ipairs(v.getKeyboards()) do for _, v2 in ipairs(v.getKeyboards()) do
if v2 == kb then if v2 == kb then
keyboardMonCacheK, keyboardMonCacheV = kb, v.address keyboardMonCacheK, keyboardMonCacheV = kb, v.address
@ -265,53 +201,19 @@ donkonitRDProvider(function (pkg, pid, sendSig)
getClaimable = function () getClaimable = function ()
local c = {} local c = {}
-- do we have gpu? -- do we have gpu?
if not gpus.list()() then return c end if not gpus()() then return c end
for _, v in ipairs(monitorPool) do for _, v in ipairs(monitorPool) do
table.insert(c, v.address) table.insert(c, v.address)
end end
return c return c
end, end,
claim = function (address) claim = function (...) -- see sys-gpualloc
neo.ensureType(address, "string") return require("sys-gpualloc")(
for k, v in ipairs(monitorPool) do gpus, screens,
if v.address == address then getMonitorSettings, settings, sRattle, saveSettings,
local gpu = getGPU(v) announceFreeMonitor, pid, claimed, sendSig,
if gpu then monitorClaims, monitorPool, currentGPUUsers, currentGPUBinding,
setupMonitor(gpu, v) ...)
gpu = gpu.address
currentGPUBinding[gpu] = address
currentGPUUsers[gpu] = (currentGPUUsers[gpu] or 0) + 1
local disclaimer = function (wasDevLoss)
-- we lost it
monitorClaims[address] = nil
claimed[address] = nil
if not wasDevLoss then
currentGPUUsers[gpu] = currentGPUUsers[gpu] - 1
table.insert(monitorPool, v)
announceFreeMonitor(address, pid)
else
sendSig("lost", address)
end
end
claimed[address] = disclaimer
monitorClaims[address] = {gpu, disclaimer}
table.remove(monitorPool, k)
return function ()
for v in gpus.list() do
if v.address == gpu then
local didBind = false
if currentGPUBinding[gpu] ~= address then
v.bind(address, false)
didBind = true
end
currentGPUBinding[gpu] = address
return v, didBind
end
end
end, v
end
end
end
end, end,
disclaim = function (address) disclaim = function (address)
if not address then error("Cannot disclaim nothing.") end if not address then error("Cannot disclaim nothing.") end
@ -329,14 +231,13 @@ local function rescanDevs()
currentGPUBinding = {} currentGPUBinding = {}
currentGPUUsers = {} currentGPUUsers = {}
keyboardMonCacheK, keyboardMonCacheV = nil, nil keyboardMonCacheK, keyboardMonCacheV = nil, nil
local hasGPU = gpus.list()()
for k, v in pairs(monitorClaims) do for k, v in pairs(monitorClaims) do
v[2](true) v[2](true)
end end
monitorClaims = {} monitorClaims = {}
for m in screens.list() do for m in screens() do
table.insert(monitorPool, m) table.insert(monitorPool, m)
if hasGPU then if gpus()() then
announceFreeMonitor(m.address) announceFreeMonitor(m.address)
end end
end end

View File

@ -20,7 +20,8 @@ return {
"libs/neoux.lua", "libs/neoux.lua",
"libs/braille.lua", "libs/braille.lua",
"libs/bmp.lua", "libs/bmp.lua",
"libs/sys-filewrap.lua" "libs/sys-filewrap.lua",
"libs/sys-gpualloc.lua"
}, },
}, },
["neo-init"] = { ["neo-init"] = {

View File

@ -359,7 +359,6 @@ function baseProcEnv()
local pe = setmetatable({}, baseProcEnvMT) local pe = setmetatable({}, baseProcEnvMT)
pe.neo = setmetatable({}, baseProcNeoMT) pe.neo = setmetatable({}, baseProcNeoMT)
pe._G = pe pe._G = pe
pe._ENV = pe
return pe return pe
end end

View File

@ -77,16 +77,17 @@ end
function getFsNode(fs, parent, fsc, path, mode) function getFsNode(fs, parent, fsc, path, mode)
local va = fsc.address:sub(1, 4) local va = fsc.address:sub(1, 4)
local fscrw = not fsc.isReadOnly() local fscrw = not fsc.isReadOnly()
if path:sub(#path, #path) == "/" then local dir = path:sub(#path, #path) == "/"
local t local confirmedDel = false
local confirmedDel = false local t
t = { t = {
name = "DIR: " .. va .. path, name = ((dir and "DIR: ") or "FILE: ") .. va .. path,
list = function () list = function ()
local n = {} local n = {}
n[1] = {"..", function () n[1] = {"..", function ()
return nil, parent return nil, parent
end} end}
if dir then
for k, v in ipairs(fsc.list(path)) do for k, v in ipairs(fsc.list(path)) do
local nm = "F: " .. v local nm = "F: " .. v
local fp = path .. v local fp = path .. v
@ -95,42 +96,17 @@ function getFsNode(fs, parent, fsc, path, mode)
end end
n[k + 1] = {nm, function () return nil, getFsNode(fs, t, fsc, fp, mode) end} n[k + 1] = {nm, function () return nil, getFsNode(fs, t, fsc, fp, mode) end}
end end
if fscrw then end
if path ~= "/" then if fscrw then
local delText = "Delete" if dir then
if confirmedDel then
delText = "Delete <ARMED>"
end
table.insert(n, {delText, function ()
if not confirmedDel then
confirmedDel = true
return nil, t
end
fsc.remove(path)
return nil, dialog("Done.", parent)
end})
else
table.insert(n, {"Relabel Disk", function ()
return nil, {
name = "Disk Relabel...",
list = function () return {{
fsc.getLabel() or "Cancel",
function ()
return false, t
end
}} end,
unknownAvailable = true,
selectUnknown = function (tx)
fsc.setLabel(tx)
return false, t
end
}
end})
end
table.insert(n, {"Mk. Directory", function () table.insert(n, {"Mk. Directory", function ()
return nil, { return nil, {
name = "MKDIR...", name = "MKDIR...",
list = function () return {} end, list = function () return {{
"Cancel", function ()
return false, t
end
}} end,
unknownAvailable = true, unknownAvailable = true,
selectUnknown = function (text) selectUnknown = function (text)
fsc.makeDirectory(path .. text) fsc.makeDirectory(path .. text)
@ -138,62 +114,76 @@ function getFsNode(fs, parent, fsc, path, mode)
end end
} }
end}) end})
end else
return n if mode ~= nil then
end, local tx = "Open"
unknownAvailable = (mode ~= nil) and ((mode == false) or fscrw), if mode == true then
selectUnknown = function (text) tx = "Save"
local rt, re = require("sys-filewrap").create(fsc, path .. text, mode) elseif mode == "append" then
if not rt then tx = "Append"
return false, dialog("Open Error: " .. tostring(re), parent) end
end if fscrw or mode == false then
return true, rt table.insert(n, {tx, function ()
end local rt, re = require("sys-filewrap").create(fsc, path, mode)
} if not rt then
return t return false, dialog("Open Error: " .. tostring(re), parent)
end end
return { return true, rt
name = "FILE: " .. va .. path, end})
list = function () end
local n = {} end
table.insert(n, {"Back", function () table.insert(n, {"Copy", function ()
return nil, parent local rt, re = require("sys-filewrap").create(fsc, path, false)
end})
if mode ~= nil then
local tx = "Open"
if mode == true then
tx = "Save"
elseif mode == "append" then
tx = "Append"
end
if fscrw or mode == false then
table.insert(n, {tx, function ()
local rt, re = require("sys-filewrap").create(fsc, path, mode)
if not rt then if not rt then
return false, dialog("Open Error: " .. tostring(re), parent) return false, dialog("Open Error: " .. tostring(re), parent)
end end
return true, rt return nil, setupCopyVirtualEnvironment(fs, parent, rt, path:match("[^/]*$") or "")
end})
end
if path ~= "/" then
local delText = "Delete"
if confirmedDel then
delText = "Delete <ARMED>"
end
table.insert(n, {delText, function ()
if not confirmedDel then
confirmedDel = true
return nil, t
end
fsc.remove(path)
return nil, dialog("Done.", parent)
end})
else
table.insert(n, {"Relabel Disk", function ()
return nil, {
name = "Disk Relabel...",
list = function () return {{
fsc.getLabel() or "Cancel",
function ()
return false, t
end
}} end,
unknownAvailable = true,
selectUnknown = function (tx)
fsc.setLabel(tx)
return false, t
end
}
end}) end})
end end
end end
table.insert(n, {"Copy", function ()
local rt, re = require("sys-filewrap").create(fsc, path, false)
if not rt then
return false, dialog("Open Error: " .. tostring(re), parent)
end
return nil, setupCopyVirtualEnvironment(fs, parent, rt, path:match("[^/]*$") or "")
end})
if fscrw then
table.insert(n, {"Delete", function ()
fsc.remove(path)
return nil, dialog("Done.", parent)
end})
end
return n return n
end, end,
unknownAvailable = false, unknownAvailable = dir and (mode ~= nil) and ((mode == false) or fscrw),
selectUnknown = function (text) end selectUnknown = function (text)
local rt, re = require("sys-filewrap").create(fsc, path .. text, mode)
if not rt then
return false, dialog("Open Error: " .. tostring(re), parent)
end
return true, rt
end
} }
return t
end end
function getRoot(fs, mode) function getRoot(fs, mode)
local t local t

104
code/libs/sys-gpualloc.lua Normal file
View File

@ -0,0 +1,104 @@
-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
return function (
gpus, screens,
getMonitorSettings, settings, sRattle, saveSettings,
announceFreeMonitor, pid, claimed, sendSig,
monitorClaims, monitorPool, currentGPUUsers, currentGPUBinding,
address
)
neo.ensureType(address, "string")
for _, monitor in ipairs(monitorPool) do
if monitor.address == address then
-- find GPU
local gpu, bestStats = nil, {-math.huge, -math.huge, -math.huge}
currentGPUBinding = {}
for k, _ in pairs(currentGPUBinding) do
currentGPUBinding[k] = nil
end
for v in gpus() do
v.bind(monitor.address, false)
local w, h = v.maxResolution()
local quality = w * h * v.maxDepth()
local users = (currentGPUUsers[v.address] or 0)
local gquality = 0
for scr in screens() do
v.bind(scr.address, false)
w, h = v.maxResolution()
local squality = w * h * v.maxDepth()
gquality = math.max(gquality, squality)
end
local stats = {quality, -users, -gquality}
for i = 1, #stats do
if stats[i] > bestStats[i] then
gpu = v
bestStats = stats
break
elseif stats[i] < bestStats[i] then
break
end
end
end
-- setup monitor
if gpu then
monitor.setPrecise(true)
monitor.turnOn()
gpu.bind(address, false)
currentGPUBinding[gpu.address] = address
local maxW, maxH = gpu.maxResolution()
local maxD = gpu.maxDepth()
local w, h, d, t = getMonitorSettings(address)
w, h, d = math.min(w, maxW), math.min(h, maxH), math.min(d, maxD)
if monitor.setTouchModeInverted then
monitor.setTouchModeInverted(t == "yes")
else
t = "no"
end
settings["scr.w." .. monitor.address] = tostring(w)
settings["scr.h." .. monitor.address] = tostring(h)
settings["scr.d." .. monitor.address] = tostring(d)
settings["scr.t." .. monitor.address] = t
sRattle("scr.w." .. monitor.address, tostring(w))
sRattle("scr.h." .. monitor.address, tostring(h))
sRattle("scr.d." .. monitor.address, tostring(d))
sRattle("scr.t." .. monitor.address, t)
gpu.setResolution(w, h)
gpu.setDepth(d)
pcall(saveSettings)
-- finish up
gpu = gpu.address
currentGPUUsers[gpu] = (currentGPUUsers[gpu] or 0) + 1
local disclaimer = function (wasDevLoss)
-- we lost it
monitorClaims[address] = nil
claimed[address] = nil
if not wasDevLoss then
currentGPUUsers[gpu] = currentGPUUsers[gpu] - 1
table.insert(monitorPool, monitor)
announceFreeMonitor(address, pid)
else
sendSig("lost", address)
end
end
claimed[address] = disclaimer
monitorClaims[address] = {gpu, disclaimer}
table.remove(monitorPool, k)
return function ()
for v in gpus() do
if v.address == gpu then
local didBind = false
if currentGPUBinding[gpu] ~= address then
v.bind(address, false)
didBind = true
end
currentGPUBinding[gpu] = address
return v, didBind
end
end
end, v
end
end
end
end

View File

@ -108,8 +108,8 @@ return function (nexus, settings, pkg, pid, perm, rsp, matchesSvc)
end end
elseif ev == "close" then elseif ev == "close" then
rsp(false) rsp(false)
nexus.windows[w.id] = nil nexus.windows[window.id] = nil
w.close() window.close()
ev = nil ev = nil
elseif ev == "key" then elseif ev == "key" then
if c and (a == 9 or b == 205) then if c and (a == 9 or b == 205) then

View File

@ -0,0 +1,37 @@
-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
-- app-allmem.lua : Memory usage tester
-- Authors: 20kdc
local value, w = 0
-- Use an event to cleanup load costs
-- We don't care about this event
neo.scheduleTimer(0)
coroutine.yield()
-- Run memory test
pcall(function ()
local data = ""
while true do
data = data .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1)
-- NOTE: we do not #data outside because that would allow it to live too long
value = value + 16
end
end)
value = math.floor(value / 102.4) / 10
value = tostring(value) .. "KiB remaining"
w = neo.requireAccess("x.neo.pub.window", "Windowing")(#value, 1)
while true do
local ev, a, b = coroutine.yield()
if ev == "x.neo.pub.window" then
if b == "line" then
w.span(1, 1, value, 0xFFFFFF, 0)
elseif b == "close" then
w.close()
return
end
end
end

View File

@ -71,6 +71,23 @@ return {
"docs/repoauthors/app-nbox2018" "docs/repoauthors/app-nbox2018"
}, },
}, },
["app-allmem"] = {
desc = "Near-reproducible memory usage figures",
v = 0,
deps = {
"neo",
"zzz-license-pd"
},
dirs = {
"apps",
"docs",
"docs/repoauthors"
},
files = {
"apps/app-allmem.lua",
"docs/repoauthors/app-allmem"
},
},
["svc-ghostie"] = { ["svc-ghostie"] = {
desc = "Application that schedules a scare after a random time to test svc autostart", desc = "Application that schedules a scare after a random time to test svc autostart",
v = 0, v = 0,

View File

@ -0,0 +1,2 @@
repository/apps/app-allmem.lua: 20kdc, Public Domain