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

View File

@ -45,6 +45,7 @@ Process_Create(Process *parent, const char *title)
proc->pid = nextProcessID++; proc->pid = nextProcessID++;
proc->threads = 0; proc->threads = 0;
proc->refCount = 1; proc->refCount = 1;
proc->procState = PROC_STATE_NULL;
TAILQ_INIT(&proc->threadList); TAILQ_INIT(&proc->threadList);
if (title) { if (title) {
@ -77,6 +78,7 @@ Process_Create(Process *parent, const char *title)
TAILQ_INIT(&proc->zombieProc); TAILQ_INIT(&proc->zombieProc);
Mutex_Init(&proc->zombieProcLock, "Zombie Process Lock"); Mutex_Init(&proc->zombieProcLock, "Zombie Process Lock");
CV_Init(&proc->zombieProcCV, "Zombie Process CV"); CV_Init(&proc->zombieProcCV, "Zombie Process CV");
CV_Init(&proc->zombieProcPCV, "Zombie Process PCV");
Spinlock_Lock(&procLock); Spinlock_Lock(&procLock);
TAILQ_INSERT_TAIL(&processList, proc, processList); TAILQ_INSERT_TAIL(&processList, proc, processList);
@ -92,6 +94,7 @@ Process_Destroy(Process *proc)
Spinlock_Destroy(&proc->lock); Spinlock_Destroy(&proc->lock);
Semaphore_Destroy(&proc->zombieSemaphore); Semaphore_Destroy(&proc->zombieSemaphore);
CV_Destroy(&proc->zombieProcPCV);
CV_Destroy(&proc->zombieProcCV); CV_Destroy(&proc->zombieProcCV);
Mutex_Destroy(&proc->zombieProcLock); Mutex_Destroy(&proc->zombieProcLock);
PMap_DestroyAS(proc->space); PMap_DestroyAS(proc->space);
@ -146,6 +149,7 @@ Process_Release(Process *proc)
} }
} }
// XXX: Cleanup return value
uint64_t uint64_t
Process_Wait(Process *proc, uint64_t pid) Process_Wait(Process *proc, uint64_t pid)
{ {
@ -157,14 +161,33 @@ Process_Wait(Process *proc, uint64_t pid)
// XXX: Need to verify pid exists! // XXX: Need to verify pid exists!
Mutex_Lock(&proc->zombieProcLock); Mutex_Lock(&proc->zombieProcLock);
while (1) { if (pid == 0) {
p = TAILQ_FIRST(&proc->zombieProc); while (1) {
if (p != NULL && (pid == 0 || p->pid == pid)) { p = TAILQ_FIRST(&proc->zombieProc);
TAILQ_REMOVE(&proc->zombieProc, p, siblingList); if (p != NULL) {
break; 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;
} }
CV_Wait(&proc->zombieProcCV, &proc->zombieProcLock); 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); Mutex_Unlock(&proc->zombieProcLock);
@ -188,8 +211,15 @@ Process_Wait(Process *proc, uint64_t pid)
void void
Process_Dump(Process *proc) Process_Dump(Process *proc)
{ {
const char *stateStrings[] = {
"NULL",
"READY",
"ZOMBIE"
};
kprintf("title %s\n", proc->title); kprintf("title %s\n", proc->title);
kprintf("pid %llu\n", proc->pid); kprintf("pid %llu\n", proc->pid);
kprintf("state %s\n", stateStrings[proc->procState]);
kprintf("space %016llx\n", proc->space); kprintf("space %016llx\n", proc->space);
kprintf("threads %llu\n", proc->threads); kprintf("threads %llu\n", proc->threads);
kprintf("refCount %d\n", proc->refCount); kprintf("refCount %d\n", proc->refCount);

View File

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