OSWait: Fix waiting on a specific PID
This commit is contained in:
parent
179c862c51
commit
feb45381ba
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user