mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
waitpid: use events instead of semaphores
This commit is contained in:
@@ -31,6 +31,7 @@ typedef struct proc_t {
|
||||
struct proc_t *sibling;
|
||||
struct proc_t *parent;
|
||||
struct proc_t *child;
|
||||
eventheader_t child_exit_event;
|
||||
pid_t pid;
|
||||
cred_t cred;
|
||||
spinlock_t threadlistlock;
|
||||
@@ -46,7 +47,6 @@ typedef struct proc_t {
|
||||
vnode_t *cwd;
|
||||
vnode_t *root;
|
||||
spinlock_t nodeslock;
|
||||
semaphore_t waitsem;
|
||||
spinlock_t exiting;
|
||||
int nice;
|
||||
|
||||
|
||||
@@ -98,7 +98,6 @@ proc_t *proc_create() {
|
||||
proc->refcount = 1;
|
||||
proc->fdfirst = 3;
|
||||
MUTEX_INIT(&proc->fdmutex);
|
||||
SEMAPHORE_INIT(&proc->waitsem, 0);
|
||||
SPINLOCK_INIT(proc->jobctllock);
|
||||
SPINLOCK_INIT(proc->pgrp.lock);
|
||||
SPINLOCK_INIT(proc->signals.lock);
|
||||
@@ -107,6 +106,7 @@ proc_t *proc_create() {
|
||||
itimer_init(&proc->timer.virtualtime, vtdpc, proc);
|
||||
itimer_init(&proc->timer.profiling, profdpc, proc);
|
||||
SPINLOCK_INIT(proc->threadlistlock);
|
||||
EVENT_INITHEADER(&proc->child_exit_event);
|
||||
|
||||
proc->fd = alloc(sizeof(fd_t) * 3);
|
||||
if (proc->fd == NULL) {
|
||||
@@ -299,10 +299,10 @@ void proc_exit(void) {
|
||||
MUTEX_RELEASE(&proc->mutex);
|
||||
|
||||
signal_signalproc(proc->parent, SIGCHLD);
|
||||
semaphore_signal(&proc->parent->waitsem);
|
||||
EVENT_SIGNAL(&proc->parent->child_exit_event);
|
||||
// TODO sigaction flag for this
|
||||
for (int i = 0; i < belowzombiecount; ++i) {
|
||||
semaphore_signal(&init_proc->waitsem);
|
||||
if (belowzombiecount) {
|
||||
EVENT_SIGNAL(&init_proc->child_exit_event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -411,7 +411,8 @@ void signal_signalproc(struct proc_t *proc, int signal) {
|
||||
if (proc->parent && (proc->parent->signals.actions[SIGCHLD].flags & SA_NOCLDSTOP) == 0) {
|
||||
signal_signalproc(proc->parent, SIGCHLD);
|
||||
}
|
||||
semaphore_signal(&proc->parent->waitsem);
|
||||
|
||||
EVENT_SIGNAL(&proc->parent->child_exit_event);
|
||||
}
|
||||
|
||||
// tell the parent that a child continued
|
||||
@@ -423,7 +424,7 @@ void signal_signalproc(struct proc_t *proc, int signal) {
|
||||
signal_signalproc(proc->parent, SIGCHLD);
|
||||
}
|
||||
|
||||
semaphore_signal(&proc->parent->waitsem);
|
||||
EVENT_SIGNAL(&proc->parent->child_exit_event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#define WCONTINUED 8
|
||||
#define KNOWN_FLAGS (WNOHANG | WSTOPPED | WCONTINUED | __WALL)
|
||||
|
||||
// TODO use events here
|
||||
syscallret_t syscall_waitpid(context_t *context, pid_t pid, int *status, int options) {
|
||||
syscallret_t ret = {
|
||||
.ret = -1
|
||||
@@ -44,6 +43,8 @@ syscallret_t syscall_waitpid(context_t *context, pid_t pid, int *status, int opt
|
||||
bool continued = false;
|
||||
bool stopped = false;
|
||||
bool zombie = false;
|
||||
eventlistener_t listener;
|
||||
EVENT_INITLISTENER(&listener);
|
||||
|
||||
for (;;) {
|
||||
if (iterator == NULL) {
|
||||
@@ -52,15 +53,22 @@ syscallret_t syscall_waitpid(context_t *context, pid_t pid, int *status, int opt
|
||||
MUTEX_RELEASE(&proc->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (options & WNOHANG) {
|
||||
MUTEX_RELEASE(&proc->mutex);
|
||||
if ((options & WNOHANG) && semaphore_test(&proc->waitsem) == false) {
|
||||
ret.errno = 0;
|
||||
ret.ret = 0;
|
||||
return ret;
|
||||
} else if ((options & WNOHANG) == 0 && semaphore_wait(&proc->waitsem, true)) {
|
||||
ret.errno = EINTR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EVENT_ATTACH(&listener, &proc->child_exit_event);
|
||||
MUTEX_RELEASE(&proc->mutex);
|
||||
|
||||
ret.errno = EVENT_WAIT(&listener, 0);
|
||||
EVENT_DETACHALL(&listener);
|
||||
if (ret.errno)
|
||||
return ret;
|
||||
|
||||
MUTEX_ACQUIRE(&proc->mutex);
|
||||
prev = NULL;
|
||||
iterator = proc->child;
|
||||
|
||||
Reference in New Issue
Block a user