OSWait: Fix waiting on a specific PID

This commit is contained in:
Ali Mashtizadeh 2023-09-03 14:54:14 -04:00
parent 179c862c51
commit feb45381ba
3 changed files with 47 additions and 6 deletions

View File

@ -58,6 +58,10 @@ typedef struct Thread {
#define PROCESS_HANDLE_SLOTS 128
#define PROCESS_TITLE_LENGTH 128
#define PROC_STATE_NULL 0
#define PROC_STATE_READY 1
#define PROC_STATE_ZOMBIE 2
typedef struct Process {
uint64_t pid;
AS *space;
@ -68,6 +72,7 @@ typedef struct Process {
TAILQ_ENTRY(Process) processList;
uint64_t refCount;
char title[PROCESS_TITLE_LENGTH];
int procState;
uint64_t exitCode;
// Process
Process *parent;
@ -76,6 +81,7 @@ typedef struct Process {
ProcessQueue zombieProc;
Mutex zombieProcLock;
CV zombieProcCV;
CV zombieProcPCV;
// Threads
uint64_t threads;
ThreadQueue threadList;

View File

@ -45,6 +45,7 @@ Process_Create(Process *parent, const char *title)
proc->pid = nextProcessID++;
proc->threads = 0;
proc->refCount = 1;
proc->procState = PROC_STATE_NULL;
TAILQ_INIT(&proc->threadList);
if (title) {
@ -77,6 +78,7 @@ Process_Create(Process *parent, const char *title)
TAILQ_INIT(&proc->zombieProc);
Mutex_Init(&proc->zombieProcLock, "Zombie Process Lock");
CV_Init(&proc->zombieProcCV, "Zombie Process CV");
CV_Init(&proc->zombieProcPCV, "Zombie Process PCV");
Spinlock_Lock(&procLock);
TAILQ_INSERT_TAIL(&processList, proc, processList);
@ -92,6 +94,7 @@ Process_Destroy(Process *proc)
Spinlock_Destroy(&proc->lock);
Semaphore_Destroy(&proc->zombieSemaphore);
CV_Destroy(&proc->zombieProcPCV);
CV_Destroy(&proc->zombieProcCV);
Mutex_Destroy(&proc->zombieProcLock);
PMap_DestroyAS(proc->space);
@ -146,6 +149,7 @@ Process_Release(Process *proc)
}
}
// XXX: Cleanup return value
uint64_t
Process_Wait(Process *proc, uint64_t pid)
{
@ -157,15 +161,34 @@ Process_Wait(Process *proc, uint64_t pid)
// XXX: Need to verify pid exists!
Mutex_Lock(&proc->zombieProcLock);
if (pid == 0) {
while (1) {
p = TAILQ_FIRST(&proc->zombieProc);
if (p != NULL && (pid == 0 || p->pid == pid)) {
if (p != NULL) {
TAILQ_REMOVE(&proc->zombieProc, p, siblingList);
break;
}
CV_Wait(&proc->zombieProcCV, &proc->zombieProcLock);
}
} else {
p = Process_Lookup(pid);
if (p == NULL) {
Mutex_Unlock(&proc->zombieProcLock);
return ENOENT;
}
while (p->procState != PROC_STATE_ZOMBIE) {
CV_Wait(&p->zombieProcPCV, &proc->zombieProcLock);
}
TAILQ_REMOVE(&proc->zombieProc, p, siblingList);
/*
* Release the reference from Process_Lookup but it's okay to continue
* using p because we're cleaning up the last reference as the parent
* process.
*/
Process_Release(p);
}
Mutex_Unlock(&proc->zombieProcLock);
status = (p->pid << 16) | p->exitCode;
@ -188,8 +211,15 @@ Process_Wait(Process *proc, uint64_t pid)
void
Process_Dump(Process *proc)
{
const char *stateStrings[] = {
"NULL",
"READY",
"ZOMBIE"
};
kprintf("title %s\n", proc->title);
kprintf("pid %llu\n", proc->pid);
kprintf("state %s\n", stateStrings[proc->procState]);
kprintf("space %016llx\n", proc->space);
kprintf("threads %llu\n", proc->threads);
kprintf("refCount %d\n", proc->refCount);

View File

@ -46,6 +46,9 @@ Sched_SetRunnable(Thread *thr)
{
Spinlock_Lock(&schedLock);
if (thr->proc->procState == PROC_STATE_NULL)
thr->proc->procState = PROC_STATE_READY;
if (thr->schedState == SCHED_STATE_WAITING) {
thr->waitTime += KTime_GetEpochNS() - thr->waitStart;
thr->waitStart = 0;
@ -86,9 +89,11 @@ Sched_SetZombie(Thread *thr)
ASSERT(proc->parent != NULL);
Mutex_Lock(&proc->parent->zombieProcLock);
Spinlock_Lock(&proc->parent->lock); // Guards child list
proc->procState = PROC_STATE_ZOMBIE;
TAILQ_REMOVE(&proc->parent->childrenList, proc, siblingList);
TAILQ_INSERT_TAIL(&proc->parent->zombieProc, proc, siblingList);
Spinlock_Unlock(&proc->parent->lock);
CV_Signal(&proc->zombieProcPCV);
CV_Signal(&proc->parent->zombieProcCV);
Mutex_Unlock(&proc->parent->zombieProcLock);
}