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;
|
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
|
||||||
|
|
||||||
int parentSlot = Ipc::CurrentSlot();
|
int parentSlot = Ipc::CurrentSlot();
|
||||||
int childPid = Sched::Spawn(resolved, args);
|
int childPid = Sched::Spawn(resolved, args, false);
|
||||||
if (childPid < 0) return -1;
|
if (childPid < 0) return -1;
|
||||||
|
|
||||||
auto* child = Sched::GetProcessByPid(childPid);
|
auto* child = Sched::GetProcessByPid(childPid);
|
||||||
int childSlot = Ipc::SlotForPid(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* outStream = Ipc::CreateStream();
|
||||||
Ipc::Stream* inStream = Ipc::CreateStream();
|
Ipc::Stream* inStream = Ipc::CreateStream();
|
||||||
@@ -68,8 +71,12 @@ namespace Montauk {
|
|||||||
|
|
||||||
child->redirected = true;
|
child->redirected = true;
|
||||||
child->parentPid = Sched::GetCurrentPid();
|
child->parentPid = Sched::GetCurrentPid();
|
||||||
child->termCols = 0;
|
child->termCols = 80;
|
||||||
child->termRows = 0;
|
child->termRows = 25;
|
||||||
|
if (Sched::StartProcess(childPid) < 0) {
|
||||||
|
Sched::KillProcess(childPid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return childPid;
|
return childPid;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,10 +46,11 @@ namespace Montauk {
|
|||||||
|
|
||||||
auto* parent = Sched::GetCurrentProcessPtr();
|
auto* parent = Sched::GetCurrentProcessPtr();
|
||||||
int parentSlot = Ipc::CurrentSlot();
|
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 (childPid < 0) return childPid;
|
||||||
|
|
||||||
if (parent && parent->redirected) {
|
if (inheritRedirection) {
|
||||||
auto* child = Sched::GetProcessByPid(childPid);
|
auto* child = Sched::GetProcessByPid(childPid);
|
||||||
int childSlot = Ipc::SlotForPid(childPid);
|
int childSlot = Ipc::SlotForPid(childPid);
|
||||||
if (child == nullptr || childSlot < 0 || parentSlot < 0) {
|
if (child == nullptr || childSlot < 0 || parentSlot < 0) {
|
||||||
@@ -71,6 +72,10 @@ namespace Montauk {
|
|||||||
child->parentPid = parent->pid;
|
child->parentPid = parent->pid;
|
||||||
child->termCols = parent->termCols;
|
child->termCols = parent->termCols;
|
||||||
child->termRows = parent->termRows;
|
child->termRows = parent->termRows;
|
||||||
|
if (Sched::StartProcess(childPid) < 0) {
|
||||||
|
Sched::KillProcess(childPid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return childPid;
|
return childPid;
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ namespace Sched {
|
|||||||
processTable[i].runningOnCpu = -1;
|
processTable[i].runningOnCpu = -1;
|
||||||
processTable[i].killPending = false;
|
processTable[i].killPending = false;
|
||||||
processTable[i].reapReady = false;
|
processTable[i].reapReady = false;
|
||||||
|
processTable[i].startPending = false;
|
||||||
processTable[i].waitingForPid = -1;
|
processTable[i].waitingForPid = -1;
|
||||||
processTable[i].sleepUntilTick = 0;
|
processTable[i].sleepUntilTick = 0;
|
||||||
processTable[i].waitingOnObject = nullptr;
|
processTable[i].waitingOnObject = nullptr;
|
||||||
@@ -203,7 +204,7 @@ namespace Sched {
|
|||||||
<< " process slots, " << (uint64_t)TimeSliceMs << " ms time slice)";
|
<< " 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();
|
schedLock.Acquire();
|
||||||
|
|
||||||
int slot = -1;
|
int slot = -1;
|
||||||
@@ -343,8 +344,9 @@ namespace Sched {
|
|||||||
|
|
||||||
Process& proc = processTable[slot];
|
Process& proc = processTable[slot];
|
||||||
proc.pid = nextPid++;
|
proc.pid = nextPid++;
|
||||||
proc.state = ProcessState::Ready;
|
proc.state = startReady ? ProcessState::Ready : ProcessState::Blocked;
|
||||||
readyCount++;
|
if (startReady)
|
||||||
|
readyCount++;
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < 63 && vfsPath[i]; i++) proc.name[i] = vfsPath[i];
|
for (; i < 63 && vfsPath[i]; i++) proc.name[i] = vfsPath[i];
|
||||||
@@ -363,6 +365,7 @@ namespace Sched {
|
|||||||
proc.runningOnCpu = -1;
|
proc.runningOnCpu = -1;
|
||||||
proc.killPending = false;
|
proc.killPending = false;
|
||||||
proc.reapReady = false;
|
proc.reapReady = false;
|
||||||
|
proc.startPending = !startReady;
|
||||||
proc.waitingForPid = -1;
|
proc.waitingForPid = -1;
|
||||||
proc.sleepUntilTick = 0;
|
proc.sleepUntilTick = 0;
|
||||||
proc.waitingOnObject = nullptr;
|
proc.waitingOnObject = nullptr;
|
||||||
@@ -436,11 +439,39 @@ namespace Sched {
|
|||||||
|
|
||||||
int resultPid = proc.pid;
|
int resultPid = proc.pid;
|
||||||
schedLock.Release();
|
schedLock.Release();
|
||||||
KickOneIdleCpu(Smp::GetCurrentCpuData() ? Smp::GetCurrentCpuData()->cpuIndex : -1);
|
if (startReady)
|
||||||
|
KickOneIdleCpu(Smp::GetCurrentCpuData() ? Smp::GetCurrentCpuData()->cpuIndex : -1);
|
||||||
|
|
||||||
return resultPid;
|
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
|
// Schedule -- core context switch logic
|
||||||
//
|
//
|
||||||
@@ -470,6 +501,7 @@ namespace Sched {
|
|||||||
processTable[i].stackBase = 0;
|
processTable[i].stackBase = 0;
|
||||||
processTable[i].pml4Phys = 0;
|
processTable[i].pml4Phys = 0;
|
||||||
processTable[i].reapReady = false;
|
processTable[i].reapReady = false;
|
||||||
|
processTable[i].startPending = false;
|
||||||
processTable[i].state = ProcessState::Free;
|
processTable[i].state = ProcessState::Free;
|
||||||
|
|
||||||
// Release lock during PFA::Free to minimize hold time
|
// Release lock during PFA::Free to minimize hold time
|
||||||
@@ -683,6 +715,7 @@ namespace Sched {
|
|||||||
|
|
||||||
Process& proc = processTable[slot];
|
Process& proc = processTable[slot];
|
||||||
proc.killPending = false;
|
proc.killPending = false;
|
||||||
|
proc.startPending = false;
|
||||||
int exitingPid = proc.pid;
|
int exitingPid = proc.pid;
|
||||||
|
|
||||||
// Clean up any windows owned by this process
|
// Clean up any windows owned by this process
|
||||||
@@ -823,6 +856,7 @@ namespace Sched {
|
|||||||
readyCount--;
|
readyCount--;
|
||||||
proc.state = ProcessState::Terminated;
|
proc.state = ProcessState::Terminated;
|
||||||
proc.killPending = false;
|
proc.killPending = false;
|
||||||
|
proc.startPending = false;
|
||||||
proc.reapReady = false;
|
proc.reapReady = false;
|
||||||
proc.waitingForPid = -1;
|
proc.waitingForPid = -1;
|
||||||
proc.sleepUntilTick = 0;
|
proc.sleepUntilTick = 0;
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ namespace Sched {
|
|||||||
int runningOnCpu; // CPU index running this process (-1 if not running)
|
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 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 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
|
// I/O redirection for GUI terminal
|
||||||
bool redirected = false;
|
bool redirected = false;
|
||||||
@@ -85,7 +86,8 @@ namespace Sched {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void Initialize();
|
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();
|
void Schedule();
|
||||||
|
|
||||||
// True when there is runnable work somewhere in the process table.
|
// True when there is runnable work somewhere in the process table.
|
||||||
|
|||||||
Reference in New Issue
Block a user