feature: preemptive process management - implementation progress
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
Implement a preemptive multitasking system for the Asuro kernel. Context Switching & Scheduling: - Custom IRQ0 ISR (contextswitcher.pas) with PUSHAD/POPAD ESP-swap - Round-robin scheduler with priority-based quantum - Process table using DList of PProcessContext pointers - Idle process (PID 0) replaces kernel HLT loop Process Lifecycle: - create/kill/terminate/sendMessage API (processmanager.pas) - Process states: Created, Running, Ready, Suspended, Awaiting, Finished, Error - Parent-child tracking (ParentID, smChildExited notification on reap) - proc_yield, proc_sleep_ms, proc_await, proc_suspend, proc_exit Resource Binding & Cleanup: - Per-process resource list (bindResource/unbindResource/unbindAllResources) - TCP sockets auto-bound to owning process (OwnerPID on TTCPSocket) - socket_cleanup + auto-unbind in DestroySocket VTerminal Refactor: - Multi-instance design (heap-allocated TVTermState per terminal) - Foreground process with incremental stdout/stderr drain via LVGL timer - Ctrl+C kills foreground process (killForeground) - Per-terminal CWD, dir stack, FS builtins (CD/LS/PUSHD/POPD) - Background job support (& suffix, JOBS/FG commands) - Command history (Up/Down arrow) Command Consolidation: - 14 commands extracted from 9 units into centralized progmanager.pas - Command procedures exported in host unit interfaces - E1000/TRACER/stdio builtins kept in-place (conditional/circular) New Units: - src/include/proctypes.pas — process type definitions - src/processmanager.pas — core process manager - src/prog/ping.pas — standalone ICMP ping process - src/prog/testcmd.pas — test command (proc_sleep_ms demo) - src/testprocs.pas — process subsystem smoke tests Misc: - ICMP callbacks gain userData parameter for concurrency-safe ping - CLI/STI guards on kalloc/kfree (lmemorymanager.pas) - LV_KEY_CTRLC constant + Ctrl+C interception in LVGL keyboard hook - Window owner PID tracking (windows.pas) - ISR_32 gate override support (isrmanager.pas)
This commit is contained in:
1 parent
5e9d0004d7
commit
035d489c4f
24 files changed
+2316
-378
No files matched your search
@@ -0,0 +1,145 @@
|
||||
{
|
||||
Prog->Ping - ICMP Ping command.
|
||||
|
||||
Sends 10 ICMP echo requests to a host, printing round-trip time
|
||||
for each reply. Sleeps 1 second between pings. Each invocation
|
||||
uses a heap-allocated state record so multiple terminals can ping
|
||||
concurrently without corrupting each other.
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit ping;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
stdio, tracer;
|
||||
|
||||
procedure init();
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
bios_data_area, nettypes, icmp, netutils, strings,
|
||||
processmanager, util, lmemorymanager;
|
||||
|
||||
const
|
||||
PING_TIMEOUT_MS = 5000; { 5-second timeout per ping }
|
||||
|
||||
type
|
||||
TPingResult = (prWaiting, prGotReply, prGotError);
|
||||
PPingState = ^TPingState;
|
||||
TPingState = record
|
||||
Result : TPingResult;
|
||||
ReplyTimeMS : uint64;
|
||||
ErrorReason : TARPErrorCode;
|
||||
SendTime : uint64;
|
||||
end;
|
||||
|
||||
{ ---- ICMP callbacks (called from network recv context) ---- }
|
||||
|
||||
procedure on_reply(hdr : PICMPHeader; userData : void);
|
||||
var
|
||||
st : PPingState;
|
||||
t2 : uint64;
|
||||
begin
|
||||
st := PPingState(userData);
|
||||
if st = nil then exit;
|
||||
t2 := Counters.c64;
|
||||
st^.ReplyTimeMS := t2 - st^.SendTime;
|
||||
st^.Result := prGotReply;
|
||||
end;
|
||||
|
||||
procedure on_error(hdr : PICMPHeader; Reason : TARPErrorCode; userData : void);
|
||||
var
|
||||
st : PPingState;
|
||||
begin
|
||||
st := PPingState(userData);
|
||||
if st = nil then exit;
|
||||
st^.ErrorReason := Reason;
|
||||
st^.Result := prGotError;
|
||||
end;
|
||||
|
||||
{ ---- Command entry point (runs as a process) ---- }
|
||||
|
||||
procedure run(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
var
|
||||
ip_str : pchar;
|
||||
ip : puint8;
|
||||
i : uint16;
|
||||
st : PPingState;
|
||||
tStart : uint32;
|
||||
tNow : uint32;
|
||||
elapsed : uint32;
|
||||
timeoutTicks : uint32;
|
||||
begin
|
||||
if ParamCount(Params) < 1 then begin
|
||||
stdio.bufWriteStrLn(stderr_buf, 'Usage: PING <ip>');
|
||||
exit;
|
||||
end;
|
||||
|
||||
ip_str := getParam(0, Params);
|
||||
ip := stringToIPv4(ip_str);
|
||||
if ip = nil then begin
|
||||
stdio.bufWriteStrLn(stderr_buf, 'Invalid IP address.');
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ Allocate per-invocation state so concurrent pings are safe }
|
||||
st := PPingState(kalloc(sizeof(TPingState)));
|
||||
timeoutTicks := (PING_TIMEOUT_MS * 1024) div 1000;
|
||||
|
||||
for i := 0 to 9 do begin
|
||||
{ Send ICMP echo request }
|
||||
st^.Result := prWaiting;
|
||||
st^.SendTime := Counters.c64;
|
||||
icmp.sendICMPRequest(ip, i, 128, @on_reply, @on_error, void(st));
|
||||
|
||||
{ Spin-yield until callback fires or timeout }
|
||||
tStart := Counters.c32;
|
||||
while st^.Result = prWaiting do begin
|
||||
processmanager.proc_yield;
|
||||
tNow := Counters.c32;
|
||||
if tNow >= tStart then
|
||||
elapsed := tNow - tStart
|
||||
else
|
||||
elapsed := ($FFFFFFFF - tStart) + tNow + 1;
|
||||
if elapsed >= timeoutTicks then begin
|
||||
st^.Result := prGotError;
|
||||
st^.ErrorReason := aecTimeout;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Display result }
|
||||
if st^.Result = prGotReply then begin
|
||||
stdio.bufWriteStr(stdout_buf, 'Ping Reply: ');
|
||||
stdio.bufWriteInt(stdout_buf, st^.ReplyTimeMS);
|
||||
stdio.bufWriteStrLn(stdout_buf, 'ms.');
|
||||
end else begin
|
||||
stdio.bufWriteStr(stderr_buf, 'Ping Error: ');
|
||||
case st^.ErrorReason of
|
||||
aecFailedToResolveHost: stdio.bufWriteStrLn(stderr_buf, 'Failed to resolve host.');
|
||||
aecNoRouteToHost: stdio.bufWriteStrLn(stderr_buf, 'No route to host.');
|
||||
aecTimeout: stdio.bufWriteStrLn(stderr_buf, 'Timeout expired.');
|
||||
aecTTLExpired: stdio.bufWriteStrLn(stderr_buf, 'TTL Expired.');
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Sleep 1 second between pings (except after last) }
|
||||
if i < 9 then
|
||||
processmanager.proc_sleep_ms(1000);
|
||||
end;
|
||||
|
||||
{ Clean up }
|
||||
kfree(void(st));
|
||||
kfree(void(ip));
|
||||
end;
|
||||
|
||||
procedure init();
|
||||
begin
|
||||
tracer.push_trace('ping.init');
|
||||
stdio.registerCommand('PING', @run, 'Ping a host.');
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
Prog->TestCmd - Test command that prints 5 lines with 1-second delays.
|
||||
|
||||
Demonstrates a long-running command that writes incrementally to stdout.
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit testcmd;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
stdio, processmanager, tracer;
|
||||
|
||||
procedure init();
|
||||
|
||||
implementation
|
||||
|
||||
procedure run(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
var
|
||||
i : uint32;
|
||||
begin
|
||||
for i := 1 to 5 do begin
|
||||
case i of
|
||||
1: stdio.bufWriteStrLn(stdout_buf, 'Test output 1 of 5');
|
||||
2: stdio.bufWriteStrLn(stdout_buf, 'Test output 2 of 5');
|
||||
3: stdio.bufWriteStrLn(stdout_buf, 'Test output 3 of 5');
|
||||
4: stdio.bufWriteStrLn(stdout_buf, 'Test output 4 of 5');
|
||||
5: stdio.bufWriteStrLn(stdout_buf, 'Test output 5 of 5');
|
||||
end;
|
||||
if i < 5 then
|
||||
processmanager.proc_sleep_ms(1000);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure init();
|
||||
begin
|
||||
tracer.push_trace('testcmd.init');
|
||||
stdio.registerCommand('TEST', @run, 'Print 5 lines with 1-second delays.');
|
||||
end;
|
||||
|
||||
end.
|
||||
+833
-250
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user