diff --git a/code/apps/sys-glacier.lua b/code/apps/sys-glacier.lua index 205243e..fc94d23 100644 --- a/code/apps/sys-glacier.lua +++ b/code/apps/sys-glacier.lua @@ -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 glacierDCProvider = neo.requireAccess("r.neo.pub.globals", "creating NEO core APIs") -local computer = neo.requireAccess("k.computer", "shutting down") -local fs = neo.requireAccess("c.filesystem", "settings I/O") -local gpus = neo.requireAccess("c.gpu", "screen control") -local screens = neo.requireAccess("c.screen", "screen control") +local shutdownFin = neo.requireAccess("k.computer", "shutting down").shutdown +local primary = neo.requireAccess("c.filesystem", "settings I/O").primary +local gpus = neo.requireAccess("c.gpu", "screen control").list +local screens = neo.requireAccess("c.screen", "screen control").list neo.requireAccess("s.h.component_added", "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 local targs = {} -- settings notify targs local targsDC = {} -- displaycontrol settings notify targs @@ -50,7 +45,7 @@ local function loadSettings() pcall(function () local fw = require("sys-filewrap").create 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") st.close() st = nil @@ -65,11 +60,12 @@ local function loadSettings() end end) end + local function saveSettings() local fw = require("sys-filewrap").create local se = require("serial").serialize - fs.primary.makeDirectory("data/sys-glacier") - local st = fw(fs.primary, "data/sys-glacier/sysconf.lua", true) + primary.makeDirectory("data/sys-glacier") + local st = fw(primary, "data/sys-glacier/sysconf.lua", true) st.write(se(settings)) st.close() end @@ -83,7 +79,7 @@ local currentGPUBinding = {} -- [gpuAddr] = userCount local currentGPUUsers = {} --- Thanks to Skye for this! +-- Thanks to Skye for this design! local keyboardMonCacheK, keyboardMonCacheV = nil local function announceFreeMonitor(address, except) @@ -94,40 +90,6 @@ local function announceFreeMonitor(address, except) 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) for _, v in pairs(targs) do 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) return w, h, d, t 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) targs[pid] = sendSig @@ -228,12 +164,12 @@ donkonitSPProvider(function (pkg, pid, sendSig) v("shutdown", reboot, function () counter = counter - 1 if counter == 0 then - shutdownFin(reboot) + shutdownFin(shutdownMode) end end) end if counter == 0 then - shutdownFin(reboot) + shutdownFin(shutdownMode) end -- donkonit will shutdown when the timer is hit. end @@ -253,7 +189,7 @@ donkonitRDProvider(function (pkg, pid, sendSig) if keyboardMonCacheK == kb then return keyboardMonCacheV end - for v in screens.list() do + for v in screens() do for _, v2 in ipairs(v.getKeyboards()) do if v2 == kb then keyboardMonCacheK, keyboardMonCacheV = kb, v.address @@ -265,53 +201,19 @@ donkonitRDProvider(function (pkg, pid, sendSig) getClaimable = function () local c = {} -- 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 table.insert(c, v.address) end return c end, - claim = function (address) - neo.ensureType(address, "string") - for k, v in ipairs(monitorPool) do - if v.address == address then - local gpu = getGPU(v) - if gpu then - 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 + claim = function (...) -- see sys-gpualloc + return require("sys-gpualloc")( + gpus, screens, + getMonitorSettings, settings, sRattle, saveSettings, + announceFreeMonitor, pid, claimed, sendSig, + monitorClaims, monitorPool, currentGPUUsers, currentGPUBinding, + ...) end, disclaim = function (address) if not address then error("Cannot disclaim nothing.") end @@ -329,14 +231,13 @@ local function rescanDevs() currentGPUBinding = {} currentGPUUsers = {} keyboardMonCacheK, keyboardMonCacheV = nil, nil - local hasGPU = gpus.list()() for k, v in pairs(monitorClaims) do v[2](true) end monitorClaims = {} - for m in screens.list() do + for m in screens() do table.insert(monitorPool, m) - if hasGPU then + if gpus()() then announceFreeMonitor(m.address) end end diff --git a/code/data/app-claw/local.lua b/code/data/app-claw/local.lua index fd733ce..00e45d4 100644 --- a/code/data/app-claw/local.lua +++ b/code/data/app-claw/local.lua @@ -20,7 +20,8 @@ return { "libs/neoux.lua", "libs/braille.lua", "libs/bmp.lua", - "libs/sys-filewrap.lua" + "libs/sys-filewrap.lua", + "libs/sys-gpualloc.lua" }, }, ["neo-init"] = { diff --git a/code/init.lua b/code/init.lua index 664fbe2..b6b9dc3 100644 --- a/code/init.lua +++ b/code/init.lua @@ -359,7 +359,6 @@ function baseProcEnv() local pe = setmetatable({}, baseProcEnvMT) pe.neo = setmetatable({}, baseProcNeoMT) pe._G = pe - pe._ENV = pe return pe end diff --git a/code/libs/sys-filevfs.lua b/code/libs/sys-filevfs.lua index 3b945e0..3534de0 100644 --- a/code/libs/sys-filevfs.lua +++ b/code/libs/sys-filevfs.lua @@ -77,16 +77,17 @@ end function getFsNode(fs, parent, fsc, path, mode) local va = fsc.address:sub(1, 4) local fscrw = not fsc.isReadOnly() - if path:sub(#path, #path) == "/" then - local t - local confirmedDel = false - t = { - name = "DIR: " .. va .. path, - list = function () - local n = {} - n[1] = {"..", function () - return nil, parent - end} + local dir = path:sub(#path, #path) == "/" + local confirmedDel = false + local t + t = { + name = ((dir and "DIR: ") or "FILE: ") .. va .. path, + list = function () + local n = {} + n[1] = {"..", function () + return nil, parent + end} + if dir then for k, v in ipairs(fsc.list(path)) do local nm = "F: " .. v local fp = path .. v @@ -95,42 +96,17 @@ function getFsNode(fs, parent, fsc, path, mode) end n[k + 1] = {nm, function () return nil, getFsNode(fs, t, fsc, fp, mode) end} end - if fscrw then - if path ~= "/" then - local delText = "Delete" - if confirmedDel then - delText = "Delete " - 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 + if fscrw then + if dir then table.insert(n, {"Mk. Directory", function () return nil, { name = "MKDIR...", - list = function () return {} end, + list = function () return {{ + "Cancel", function () + return false, t + end + }} end, unknownAvailable = true, selectUnknown = function (text) fsc.makeDirectory(path .. text) @@ -138,62 +114,76 @@ function getFsNode(fs, parent, fsc, path, mode) end } end}) - end - return n - end, - unknownAvailable = (mode ~= nil) and ((mode == false) or fscrw), - 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 - return { - name = "FILE: " .. va .. path, - list = function () - local n = {} - table.insert(n, {"Back", function () - return nil, parent - 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) + else + 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 + return false, dialog("Open Error: " .. tostring(re), parent) + end + return true, rt + 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 true, rt + return nil, setupCopyVirtualEnvironment(fs, parent, rt, path:match("[^/]*$") or "") + end}) + end + if path ~= "/" then + local delText = "Delete" + if confirmedDel then + delText = "Delete " + 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 - 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 end, - unknownAvailable = false, - selectUnknown = function (text) end + unknownAvailable = dir and (mode ~= nil) and ((mode == false) or fscrw), + 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 function getRoot(fs, mode) local t diff --git a/code/libs/sys-gpualloc.lua b/code/libs/sys-gpualloc.lua new file mode 100644 index 0000000..e2382af --- /dev/null +++ b/code/libs/sys-gpualloc.lua @@ -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 + diff --git a/code/libs/sys-secpolicy.lua b/code/libs/sys-secpolicy.lua index 8721c1d..fc2005c 100644 --- a/code/libs/sys-secpolicy.lua +++ b/code/libs/sys-secpolicy.lua @@ -108,8 +108,8 @@ return function (nexus, settings, pkg, pid, perm, rsp, matchesSvc) end elseif ev == "close" then rsp(false) - nexus.windows[w.id] = nil - w.close() + nexus.windows[window.id] = nil + window.close() ev = nil elseif ev == "key" then if c and (a == 9 or b == 205) then diff --git a/repository/apps/app-allmem.lua b/repository/apps/app-allmem.lua new file mode 100644 index 0000000..891c625 --- /dev/null +++ b/repository/apps/app-allmem.lua @@ -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 diff --git a/repository/data/app-claw/local.lua b/repository/data/app-claw/local.lua index 238fd57..0e757e0 100644 --- a/repository/data/app-claw/local.lua +++ b/repository/data/app-claw/local.lua @@ -71,6 +71,23 @@ return { "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"] = { desc = "Application that schedules a scare after a random time to test svc autostart", v = 0, diff --git a/repository/docs/repoauthors/app-allmem b/repository/docs/repoauthors/app-allmem new file mode 100644 index 0000000..645da15 --- /dev/null +++ b/repository/docs/repoauthors/app-allmem @@ -0,0 +1,2 @@ +repository/apps/app-allmem.lua: 20kdc, Public Domain +