2019-01-02 16:41:39 +11:00
|
|
|
do
|
2023-07-31 08:11:24 +10:00
|
|
|
local tTasks,nPid,nTimeout,cPid = {},1,0.25,0 -- table of tasks, next process ID, default event timeout, current PID
|
2020-05-12 17:55:05 +10:00
|
|
|
function os.spawn(f,n) -- function string -- number -- creates a process from function *f* with name *n*
|
2019-10-27 23:34:02 +11:00
|
|
|
tTasks[nPid] = {
|
2020-06-29 15:25:58 +10:00
|
|
|
c=coroutine.create(function()
|
|
|
|
local rt = {pcall(f)}
|
|
|
|
if not rt[1] then
|
|
|
|
syslog(rt[2])
|
|
|
|
end
|
|
|
|
computer.pushSignal("process_finished",os.pid(),table.unpack(rt))
|
|
|
|
end), -- actual coroutine
|
2019-10-27 23:34:02 +11:00
|
|
|
n=n, -- process name
|
|
|
|
p=nPid, -- process PID
|
|
|
|
P=cPid, -- parent PID
|
2023-07-04 18:25:11 +10:00
|
|
|
t=0, -- CPU time
|
|
|
|
T=0, -- total uptime
|
2023-07-31 08:11:24 +10:00
|
|
|
E=nTimeout, -- event timeout
|
2019-10-27 23:34:02 +11:00
|
|
|
e={} -- environment variables
|
|
|
|
}
|
2019-01-02 16:41:39 +11:00
|
|
|
if tTasks[cPid] then
|
|
|
|
for k,v in pairs(tTasks[cPid].e) do
|
|
|
|
tTasks[nPid].e[k] = tTasks[nPid].e[k] or v
|
|
|
|
end
|
2018-11-03 03:05:41 +11:00
|
|
|
end
|
|
|
|
nPid = nPid + 1
|
|
|
|
return nPid - 1
|
|
|
|
end
|
2020-05-12 17:55:05 +10:00
|
|
|
function os.kill(pid) -- number -- -- removes process *pid* from the task list
|
2019-01-02 16:41:39 +11:00
|
|
|
tTasks[pid] = nil
|
|
|
|
end
|
2020-05-12 17:55:05 +10:00
|
|
|
function os.pid() -- -- number -- returns the current process' PID
|
2019-10-27 23:34:02 +11:00
|
|
|
return cPid
|
|
|
|
end
|
2020-05-12 17:55:05 +10:00
|
|
|
function os.tasks() -- -- table -- returns a table of process IDs
|
2019-10-27 23:34:02 +11:00
|
|
|
local rt = {}
|
|
|
|
for k,v in pairs(tTasks) do
|
|
|
|
rt[#rt+1] = k
|
|
|
|
end
|
|
|
|
return rt
|
|
|
|
end
|
2020-05-12 17:55:05 +10:00
|
|
|
function os.taskInfo(pid) -- number -- table -- returns info on process *pid* as a table with name and parent values
|
2019-11-09 13:52:39 +11:00
|
|
|
pid = pid or os.pid()
|
2019-11-09 13:14:58 +11:00
|
|
|
if not tTasks[pid] then return false end
|
2023-07-04 18:25:11 +10:00
|
|
|
return {name=tTasks[pid].n,parent=tTasks[pid].P,cputime=tTasks[pid].t,iotime=tTasks[pid].T}
|
2019-10-27 23:34:02 +11:00
|
|
|
end
|
|
|
|
function os.sched() -- the actual scheduler function
|
|
|
|
os.sched = nil
|
2023-07-31 08:11:24 +10:00
|
|
|
local sTimeout = nTimeout
|
2018-11-03 03:05:41 +11:00
|
|
|
while #tTasks > 0 do
|
2023-07-31 08:11:24 +10:00
|
|
|
local tEv = {computer.pullSignal(sTimeout)}
|
|
|
|
sTimeout = nTimeout
|
2018-11-03 03:05:41 +11:00
|
|
|
for k,v in pairs(tTasks) do
|
|
|
|
if coroutine.status(v.c) ~= "dead" then
|
|
|
|
cPid = k
|
2023-07-04 18:25:11 +10:00
|
|
|
local sT, sC = os.clock(), computer.uptime()
|
2018-11-03 03:05:41 +11:00
|
|
|
coroutine.resume(v.c,table.unpack(tEv))
|
2023-07-04 18:25:11 +10:00
|
|
|
v.t, v.T = v.t + os.clock() - sT, v.T + computer.uptime() - sC
|
2023-07-31 08:11:24 +10:00
|
|
|
sTimeout=math.min(sTimeout, v.E)
|
2018-11-03 03:05:41 +11:00
|
|
|
else
|
|
|
|
tTasks[k] = nil
|
|
|
|
end
|
|
|
|
end
|
2023-07-31 08:11:24 +10:00
|
|
|
sTimeout = nTimeout
|
2018-11-03 03:05:41 +11:00
|
|
|
end
|
|
|
|
end
|
2019-01-02 16:41:39 +11:00
|
|
|
function os.setenv(k,v) -- set's the current process' environment variable *k* to *v*, which is passed to children
|
|
|
|
if tTasks[cPid] then
|
|
|
|
tTasks[cPid].e[k] = v
|
|
|
|
end
|
|
|
|
end
|
|
|
|
function os.getenv(k) -- gets a process' *k* environment variable
|
|
|
|
if tTasks[cPid] then
|
|
|
|
return tTasks[cPid].e[k]
|
|
|
|
end
|
|
|
|
end
|
2020-06-11 12:46:00 +10:00
|
|
|
function os.getTimeout()
|
2023-07-31 08:11:24 +10:00
|
|
|
return tTasks[cPid].E
|
2020-06-11 12:46:00 +10:00
|
|
|
end
|
2023-07-31 08:11:24 +10:00
|
|
|
function os.setTimeout(n,pid)
|
|
|
|
assert(type(n) == "number" and n >= 0)
|
|
|
|
tTasks[pid or cPid].E = n
|
|
|
|
return true
|
2020-04-11 12:10:58 +10:00
|
|
|
end
|
2019-01-02 16:41:39 +11:00
|
|
|
end
|