diff --git a/halyde/kernel/modules/tsched.lua b/halyde/kernel/modules/tsched.lua new file mode 100644 index 0000000..a51d356 --- /dev/null +++ b/halyde/kernel/modules/tsched.lua @@ -0,0 +1,117 @@ +local module = {} + +module.dependencies = {} + +function module.check() + return true +end + +function module.init() + _G._PUBLIC.tsched = {} + _G.tsched = {} + _G.tsched.tasks = {} + + local component = require("component") + local filesystem = require("filesystem") + local gpu = component.gpu + local log = require("log") + + local idCounter = 1 + + function _G._PUBLIC.tsched.runAsTask(path, ...) + checkArg(1, path, "string") + local args = { ... } + local function taskFunction() + local result, errorMessage = xpcall(function(...) + local args = table.pack(...) + if not filesystem.exists(path) then + error("No such file: " .. path) + end + local handle, data, tmpdata = filesystem.open(path), "", nil + repeat + tmpdata = handle:read(math.huge or math.maxinteger) + data = data .. (tmpdata or "") + until not tmpdata + handle:close() + + -- Userland environment definition + local userland = table.copy(_PUBLIC) + userland._G = userland + userland.load = function(chunk, chunkname, mode, env) + if not env or env == _G then + env = userland + end -- if they SOMEHOW get the kernel environment they're not running jack shit + return load(chunk, chunkname, mode, env) + end + userland.require = reqgen(userland.load) + + assert(load(data, "=" .. path, "t", userland))(table.unpack(args)) + end, function(errorMessage) + return errorMessage .. "\n \n" .. debug.traceback() + end, --[[ path,]] table.unpack(args)) + if not result then + if print then + gpu.freeAllBuffers() + print("\n\27[91m" .. errorMessage) + else + error(errorMessage) + end + end + --require(path, table.unpack(args)) + end + local _, taskInfo = _PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$")) + taskInfo.path = path + taskInfo.args = table.copy(args) + end + + function _G._PUBLIC.tsched.addTask(func, name) + checkArg(1, func, "function") + checkArg(2, name, "string") + local task = coroutine.create(func) + local taskInfo = { ["task"] = task, ["name"] = name, ["id"] = idCounter } + if type(tsched.currentTask) == "table" and type(tsched.currentTask.id) == "number" then + taskInfo.parent = tsched.currentTask.id + end + table.insert(tsched.tasks, taskInfo) + idCounter = idCounter + 1 + if taskInfo.parent then + log.kernel.info( + "Created task " .. name .. " with PID " .. idCounter - 1 .. " by parent with PID " .. taskInfo.parent + ) + else + log.kernel.info("Created task " .. name .. " with PID " .. idCounter - 1 .. " (no parent found)") + end + return task, taskInfo + end + + function _G._PUBLIC.tsched.removeTask(id) + checkArg(1, id, "number") + -- TODO: Check for user permissions before running + for index, task in pairs(tsched.tasks) do + if task.id == id then + table.remove(tsched.tasks, index) + log.kernel.info("Removed task with PID " .. id) + return true + end + end + log.kernel.warn("Tried to remove task that doesn't exist - PID " .. id) + return false + end + + function _G._PUBLIC.tsched.getCurrentTask() + return table.copy(tsched.currentTask) + end + + function _G._PUBLIC.tsched.getTasks() + return table.copy(tsched.tasks) + end +end + +function module.exit() + -- why would you even want to + _G._PUBLIC.tsched = nil + _G.tsched = nil + _G.tsched.tasks = nil +end + +return module diff --git a/halyde/kernel/tsched.lua b/halyde/kernel/tsched.lua index 4a7dd32..0a6b1b1 100644 --- a/halyde/kernel/tsched.lua +++ b/halyde/kernel/tsched.lua @@ -1,11 +1,3 @@ -local idCounter = 1 - -_G._PUBLIC.tsched = {} -_G.tsched = {} -_G.tsched.tasks = {} - -local currentTask - local component = require("component") local computer = require("computer") local filesystem = require("filesystem") @@ -13,86 +5,6 @@ local json = require("json") local gpu = component.gpu local log = require("log") -function _G._PUBLIC.tsched.runAsTask(path, ...) - checkArg(1, path, "string") - local args = { ... } - local function taskFunction() - local result, errorMessage = xpcall(function(...) - local args = table.pack(...) - if not filesystem.exists(path) then - error("No such file: " .. path) - end - local handle, data, tmpdata = filesystem.open(path), "", nil - repeat - tmpdata = handle:read(math.huge or math.maxinteger) - data = data .. (tmpdata or "") - until not tmpdata - handle:close() - - -- Userland environment definition - local userland = table.copy(_PUBLIC) - userland._G = userland - userland.load = function(chunk, chunkname, mode, env) - if not env or env == _G then - env = userland - end -- if they SOMEHOW get the kernel environment they're not running jack shit - return load(chunk, chunkname, mode, env) - end - userland.require = reqgen(userland.load) - - assert(load(data, "=" .. path, "t", userland))(table.unpack(args)) - end, function(errorMessage) - return errorMessage .. "\n \n" .. debug.traceback() - end, --[[ path,]] table.unpack(args)) - if not result then - if print then - gpu.freeAllBuffers() - print("\n\27[91m" .. errorMessage) - else - error(errorMessage) - end - end - --require(path, table.unpack(args)) - end - local _, taskInfo = _PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$")) - taskInfo.path = path - taskInfo.args = table.copy(args) -end - -function _G._PUBLIC.tsched.addTask(func, name) - checkArg(1, func, "function") - checkArg(2, name, "string") - local task = coroutine.create(func) - local taskInfo = { ["task"] = task, ["name"] = name, ["id"] = idCounter } - if type(currentTask) == "table" and type(currentTask.id) == "number" then - taskInfo.parent = currentTask.id - end - table.insert(tsched.tasks, taskInfo) - idCounter = idCounter + 1 - if taskInfo.parent then - log.kernel.info( - "Created task " .. name .. " with PID " .. idCounter - 1 .. " by parent with PID " .. taskInfo.parent - ) - else - log.kernel.info("Created task " .. name .. " with PID " .. idCounter - 1 .. " (no parent found)") - end - return task, taskInfo -end - -function _G._PUBLIC.tsched.removeTask(id) - checkArg(1, id, "number") - -- TODO: Check for user permissions before running - for index, task in pairs(tsched.tasks) do - if task.id == id then - table.remove(tsched.tasks, index) - log.kernel.info("Removed task with PID " .. id) - return true - end - end - log.kernel.warn("Tried to remove task that doesn't exist - PID " .. id) - return false -end - function handleError(errormsg) if errormsg == nil then -- TODO: Replace with proper error handling print("\27[91munknown error" .. "\n \n" .. debug.traceback()) @@ -104,7 +16,7 @@ end local function runTasks() for i = 1, #_G.tsched.tasks do if tsched.tasks[i] then - currentTask = tsched.tasks[i] + tsched.currentTask = tsched.tasks[i] local result, errorMessage = coroutine.resume(tsched.tasks[i].task) if not result then handleError(errorMessage) @@ -122,14 +34,6 @@ local function runTasks() end end -function _G._PUBLIC.tsched.getCurrentTask() - return table.copy(currentTask) -end - -function _G._PUBLIC.tsched.getTasks() - return table.copy(tsched.tasks) -end - local function taskFunction() local result, errorMessage = xpcall(function() if not filesystem.exists("/halyde/kernel/evmgr.lua") then