fix: add start pending mode to mitigate Terminal output redirection issue
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,8 +344,9 @@ namespace Sched {
|
||||
|
||||
Process& proc = processTable[slot];
|
||||
proc.pid = nextPid++;
|
||||
proc.state = ProcessState::Ready;
|
||||
readyCount++;
|
||||
proc.state = startReady ? ProcessState::Ready : ProcessState::Blocked;
|
||||
if (startReady)
|
||||
readyCount++;
|
||||
{
|
||||
int i = 0;
|
||||
for (; i < 63 && vfsPath[i]; i++) proc.name[i] = vfsPath[i];
|
||||
@@ -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();
|
||||
KickOneIdleCpu(Smp::GetCurrentCpuData() ? Smp::GetCurrentCpuData()->cpuIndex : -1);
|
||||
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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user