fix: add start pending mode to mitigate Terminal output redirection issue

This commit is contained in:
2026-05-07 07:32:44 +02:00
parent 2523340d08
commit ecf6edb826
4 changed files with 59 additions and 11 deletions
+11 -4
View File
@@ -18,12 +18,15 @@ namespace Montauk {
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
int parentSlot = Ipc::CurrentSlot();
int childPid = Sched::Spawn(resolved, args);
int childPid = Sched::Spawn(resolved, args, false);
if (childPid < 0) return -1;
auto* child = Sched::GetProcessByPid(childPid);
int childSlot = Ipc::SlotForPid(childPid);
if (child == nullptr || childSlot < 0 || parentSlot < 0) return -1;
if (child == nullptr || childSlot < 0 || parentSlot < 0) {
Sched::KillProcess(childPid);
return -1;
}
Ipc::Stream* outStream = Ipc::CreateStream();
Ipc::Stream* inStream = Ipc::CreateStream();
@@ -68,8 +71,12 @@ namespace Montauk {
child->redirected = true;
child->parentPid = Sched::GetCurrentPid();
child->termCols = 0;
child->termRows = 0;
child->termCols = 80;
child->termRows = 25;
if (Sched::StartProcess(childPid) < 0) {
Sched::KillProcess(childPid);
return -1;
}
return childPid;
}
+7 -2
View File
@@ -46,10 +46,11 @@ namespace Montauk {
auto* parent = Sched::GetCurrentProcessPtr();
int parentSlot = Ipc::CurrentSlot();
int childPid = Sched::Spawn(resolved, args);
bool inheritRedirection = parent && parent->redirected;
int childPid = Sched::Spawn(resolved, args, !inheritRedirection);
if (childPid < 0) return childPid;
if (parent && parent->redirected) {
if (inheritRedirection) {
auto* child = Sched::GetProcessByPid(childPid);
int childSlot = Ipc::SlotForPid(childPid);
if (child == nullptr || childSlot < 0 || parentSlot < 0) {
@@ -71,6 +72,10 @@ namespace Montauk {
child->parentPid = parent->pid;
child->termCols = parent->termCols;
child->termRows = parent->termRows;
if (Sched::StartProcess(childPid) < 0) {
Sched::KillProcess(childPid);
return -1;
}
}
return childPid;
+36 -2
View File
@@ -175,6 +175,7 @@ namespace Sched {
processTable[i].runningOnCpu = -1;
processTable[i].killPending = false;
processTable[i].reapReady = false;
processTable[i].startPending = false;
processTable[i].waitingForPid = -1;
processTable[i].sleepUntilTick = 0;
processTable[i].waitingOnObject = nullptr;
@@ -203,7 +204,7 @@ namespace Sched {
<< " process slots, " << (uint64_t)TimeSliceMs << " ms time slice)";
}
int Spawn(const char* vfsPath, const char* args) {
int Spawn(const char* vfsPath, const char* args, bool startReady) {
schedLock.Acquire();
int slot = -1;
@@ -343,7 +344,8 @@ namespace Sched {
Process& proc = processTable[slot];
proc.pid = nextPid++;
proc.state = ProcessState::Ready;
proc.state = startReady ? ProcessState::Ready : ProcessState::Blocked;
if (startReady)
readyCount++;
{
int i = 0;
@@ -363,6 +365,7 @@ namespace Sched {
proc.runningOnCpu = -1;
proc.killPending = false;
proc.reapReady = false;
proc.startPending = !startReady;
proc.waitingForPid = -1;
proc.sleepUntilTick = 0;
proc.waitingOnObject = nullptr;
@@ -436,11 +439,39 @@ namespace Sched {
int resultPid = proc.pid;
schedLock.Release();
if (startReady)
KickOneIdleCpu(Smp::GetCurrentCpuData() ? Smp::GetCurrentCpuData()->cpuIndex : -1);
return resultPid;
}
int StartProcess(int pid) {
if (pid < 0) return -1;
schedLock.Acquire();
for (int i = 0; i < MaxProcesses; i++) {
if (processTable[i].pid != pid) continue;
if (processTable[i].state != ProcessState::Blocked ||
!processTable[i].startPending) {
schedLock.Release();
return -1;
}
processTable[i].startPending = false;
processTable[i].waitingForPid = -1;
processTable[i].sleepUntilTick = 0;
processTable[i].waitingOnObject = nullptr;
processTable[i].state = ProcessState::Ready;
readyCount++;
schedLock.Release();
KickOneIdleCpu(Smp::GetCurrentCpuData() ? Smp::GetCurrentCpuData()->cpuIndex : -1);
return 0;
}
schedLock.Release();
return -1;
}
// ====================================================================
// Schedule -- core context switch logic
//
@@ -470,6 +501,7 @@ namespace Sched {
processTable[i].stackBase = 0;
processTable[i].pml4Phys = 0;
processTable[i].reapReady = false;
processTable[i].startPending = false;
processTable[i].state = ProcessState::Free;
// Release lock during PFA::Free to minimize hold time
@@ -683,6 +715,7 @@ namespace Sched {
Process& proc = processTable[slot];
proc.killPending = false;
proc.startPending = false;
int exitingPid = proc.pid;
// Clean up any windows owned by this process
@@ -823,6 +856,7 @@ namespace Sched {
readyCount--;
proc.state = ProcessState::Terminated;
proc.killPending = false;
proc.startPending = false;
proc.reapReady = false;
proc.waitingForPid = -1;
proc.sleepUntilTick = 0;
+3 -1
View File
@@ -55,6 +55,7 @@ namespace Sched {
int runningOnCpu; // CPU index running this process (-1 if not running)
bool killPending = false; // Set by Sys_Kill when target is running on another CPU
bool reapReady = false; // Set once teardown is complete and BSP may free slot resources
bool startPending = false; // Spawned but not yet made runnable
// I/O redirection for GUI terminal
bool redirected = false;
@@ -85,7 +86,8 @@ namespace Sched {
};
void Initialize();
int Spawn(const char* vfsPath, const char* args = nullptr);
int Spawn(const char* vfsPath, const char* args = nullptr, bool startReady = true);
int StartProcess(int pid);
void Schedule();
// True when there is runnable work somewhere in the process table.