-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkernel.py
More file actions
104 lines (83 loc) · 3.11 KB
/
Copy pathkernel.py
File metadata and controls
104 lines (83 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
from kernel.ipc import *
from kernel.proc import *
from kernel.fs import *
import uasyncio as asyncio
from machine import *
procs = {fs_proc.pid: fs_proc}
pipes = []
async def send(pipe_id, data, pid):
if pid not in procs or pipe_id not in procs[pid].pipes:
print(f"[KERNEL]: Send Error: PID {pid} has no pipe {pipe_id}")
return 0
pipe_obj, side = procs[pid].pipes[pipe_id]
await pipe_obj.write(side, data)
async def recv(pipe_id, pid):
if pid not in procs or pipe_id not in procs[pid].pipes:
print(f"[KERNEL]: Recv Error: PID {pid} has no pipe {pipe_id}")
return 0
pipe_obj, side = procs[pid].pipes[pipe_id]
return await pipe_obj.read(side)
def create_proc(func_text, prio):
p = Proc(func_text, prio)
procs[p.pid] = p
return p.pid
def create_pipe():
global pipes
pipes.append(Pipe())
return len(pipes) - 1
def connect(pid, local_id, global_id, side):
if pid not in procs: return 0
procs[pid].pipes[local_id] = (pipes[global_id], side)
async def run_proc(pid):
p = procs[pid]
p.state = RUNNING
ctx = {
"pid": pid, "send": send, "recv": recv, "asyncio": asyncio,
"os": None, "eval": None, "SLEEP_TIME": 0.020,
"create_pipe": create_pipe,
"connect": lambda local_id, side: connect(pid, local_id, create_pipe(), side),
"machine": None, "gc": None, "micropython": None,
"__import__": None, "importlib": None, "exec": None,
"timer": Timer
}
if p.server:
ctx['fs'] = fs
wrapper = f"async def _task_{pid}():\n"
for line in p.func.split('\n'):
if line.strip(): wrapper += f" {line}\n"
try:
exec(compile(wrapper, f"<task_{pid}>", 'exec'), ctx)
await ctx[f"_task_{pid}"]()
except Exception as err:
print(f"[KERNEL]: Error in task {pid}: {err}")
finally:
if p.server:
return 0
p.state = CLOSED
async def scheduler():
print("[KERNEL]: Scheduler started.")
for pid in sorted(procs.keys(), key=lambda p: procs[p].prio, reverse=True):
procs[pid].state = RUNNING
asyncio.create_task(run_proc(pid))
while True:
for pid, p in procs.items():
if p.server and p.state == CLOSED:
p.state = RUNNING
asyncio.create_task(run_proc(pid))
active_procs = [p for p in procs.values() if p.state == RUNNING]
if not active_procs:
print("[KERNEL]: All processes finished. System idle.")
await asyncio.sleep(0.020)
def boot():
print("[BOOT]: Initializing Kernel...")
fs_bus = create_pipe()
fs_pid = fs_proc.pid
for p_id, p in procs.items():
if p.server:
connect(p_id, 0, fs_bus, 0)
else:
connect(p_id, 0, fs_bus, 1)
reply_bus = create_pipe()
connect(p_id, 1, reply_bus, 0)
connect(fs_pid, p_id, reply_bus, 1)
print(f"[BOOT]: {len(procs)} processes linked via Pech-pipes.")