|
@@ -88,7 +88,7 @@ void(exit)
|
|
|
// thread_exit() does not return, so we should never get here
|
|
|
panic("return from thread_exit in sys_exit\n");
|
|
|
}*/
|
|
|
-
|
|
|
+/*
|
|
|
void sys__exit(int exitcode)
|
|
|
{
|
|
|
struct addrspace * as;
|
|
@@ -96,7 +96,19 @@ void sys__exit(int exitcode)
|
|
|
p->exitcode = exitcode;
|
|
|
DEBUG(DB_SYSCALL,"Syscall: _exit(%d)\n",exitcode);
|
|
|
KASSERT(curproc->p_addrspace != NULL);
|
|
|
- /* VFS fields */
|
|
|
+
|
|
|
+ lock_acquire(proclock);
|
|
|
+ int x = listpop(p->kids);
|
|
|
+ while (x)
|
|
|
+ {
|
|
|
+ processes->pids[x]->parent = NULL;
|
|
|
+ x = listpop(p->kids);
|
|
|
+ }
|
|
|
+ lock_release(proclock);
|
|
|
+
|
|
|
+ listelete(p->kids);
|
|
|
+
|
|
|
+ // VFS fields
|
|
|
if (p->p_cwd)
|
|
|
{
|
|
|
VOP_DECREF(p->p_cwd);
|
|
@@ -112,42 +124,84 @@ void sys__exit(int exitcode)
|
|
|
vfs_close(p->console);
|
|
|
}
|
|
|
|
|
|
- /* detach this thread from its process */
|
|
|
- /* note: curproc cannot be used after this call */
|
|
|
+ // detach this thread from its process
|
|
|
+ // note: curproc cannot be used after this call
|
|
|
proc_remthread(curthread);
|
|
|
|
|
|
+ threadarray_cleanup(&p->p_threads);
|
|
|
+ spinlock_cleanup(&p->p_lock);
|
|
|
+
|
|
|
+ lock_acquire(p->waitlock);
|
|
|
+ cv_broadcast(p->waiting, p->waitlock);
|
|
|
+ lock_release(p->waitlock);
|
|
|
+
|
|
|
+
|
|
|
+ //kprintf("parent is %p\n", p->parent);
|
|
|
+ //if (p->parent) kprintf("parent exitcode is %d\n", p->parent->exitcode);
|
|
|
+ //if (p->parent) kprintf("parent pid is %d\n", p->parent->pid);
|
|
|
+ if (!(p->parent) || p->parent->exitcode >= 0 || p->parent == kproc) proc_destroy(p);
|
|
|
+
|
|
|
+ thread_exit();
|
|
|
+ // thread_exit() does not return, so we should never get here
|
|
|
+ panic("return from thread_exit in sys_exit\n");
|
|
|
+}*/
|
|
|
+
|
|
|
+void sys__exit(int exitcode)
|
|
|
+{
|
|
|
+ struct addrspace * as;
|
|
|
+ struct proc * p = curproc;
|
|
|
+ p->exitcode = exitcode;
|
|
|
+ DEBUG(DB_SYSCALL,"Syscall: _exit(%d)\n",exitcode);
|
|
|
+ KASSERT(curproc->p_addrspace != NULL);
|
|
|
+
|
|
|
+ lock_acquire(proclock);
|
|
|
int x = listpop(p->kids);
|
|
|
while (x)
|
|
|
{
|
|
|
- lock_acquire(proclock);
|
|
|
- processes->pids[x]->parent = NULL;
|
|
|
- lock_release(proclock);
|
|
|
+ if(processes->pids[x])
|
|
|
+ {
|
|
|
+ processes->pids[x]->parent = NULL;
|
|
|
+ if (processes->pids[x]->exitcode >= 0)
|
|
|
+ {
|
|
|
+ lock_release(proclock);
|
|
|
+ proc_destroy(processes->pids[x]);
|
|
|
+ lock_acquire(proclock);
|
|
|
+ }
|
|
|
+ }
|
|
|
x = listpop(p->kids);
|
|
|
}
|
|
|
-
|
|
|
+ lock_release(proclock);
|
|
|
listelete(p->kids);
|
|
|
+
|
|
|
+ // VFS fields
|
|
|
+ if (p->p_cwd)
|
|
|
+ {
|
|
|
+ VOP_DECREF(p->p_cwd);
|
|
|
+ p->p_cwd = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ as_deactivate();
|
|
|
+ as = curproc_setas(NULL);
|
|
|
+ as_destroy(as);
|
|
|
+
|
|
|
+ /* detach this thread from its process */
|
|
|
+ /* note: curproc cannot be used after this call */
|
|
|
+ proc_remthread(curthread);
|
|
|
+
|
|
|
threadarray_cleanup(&p->p_threads);
|
|
|
spinlock_cleanup(&p->p_lock);
|
|
|
-
|
|
|
- lock_acquire(p->waitlock);
|
|
|
+
|
|
|
+ lock_acquire(p->waitlock);
|
|
|
cv_broadcast(p->waiting, p->waitlock);
|
|
|
lock_release(p->waitlock);
|
|
|
+
|
|
|
+ if (!(p->parent) || p->parent->exitcode >= 0 || p->parent == kproc) proc_destroy(p);
|
|
|
|
|
|
- if (!(p->parent)) proc_destroy(p);
|
|
|
- else if (p->parent->exitcode >= 0)
|
|
|
- {
|
|
|
- proc_destroy(p);
|
|
|
- }
|
|
|
-
|
|
|
- /* if this is the last user process in the system, proc_destroy()
|
|
|
- will wake up the kernel menu thread */
|
|
|
- //proc_destroy(p);
|
|
|
thread_exit();
|
|
|
/* thread_exit() does not return, so we should never get here */
|
|
|
panic("return from thread_exit in sys_exit\n");
|
|
|
}
|
|
|
|
|
|
-
|
|
|
// basically, return an error code, and put the actual result in retval
|
|
|
int sys_getpid(pid_t * retval)
|
|
|
{
|
|
@@ -157,16 +211,59 @@ int sys_getpid(pid_t * retval)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
-void waitpid()
|
|
|
+int sys_waitpid(pid_t pid, userptr_t status, int options, pid_t * retval)
|
|
|
{
|
|
|
- cv_wait(kid); // if valid thing to wait on, ofc
|
|
|
- fullDelete(kid);
|
|
|
+ int exitstatus;
|
|
|
+ int result;
|
|
|
+
|
|
|
+ if (options != 0) {
|
|
|
+ return(EINVAL);
|
|
|
+ }
|
|
|
+ for now, just pretend the exitstatus is 0
|
|
|
+ exitstatus = 0;
|
|
|
+ result = copyout((void *)&exitstatus,status,sizeof(int));
|
|
|
+ if (result) {
|
|
|
+ return(result);
|
|
|
+ }
|
|
|
+ *retval = pid;
|
|
|
+ return(0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int sys_waitpid(pid_t pid, userptr_t status, int options, pid_t * retval)
|
|
|
+{
|
|
|
+ int exitstatus;
|
|
|
+ int result;
|
|
|
+
|
|
|
+ (void)status;
|
|
|
+ if (options != 0)
|
|
|
+ {
|
|
|
+ return(EINVAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pid < PID_MIN || pid > PID_MAX) return ESRCH;
|
|
|
+ struct proc * target = getChild(curproc, pid);
|
|
|
+
|
|
|
+ if (!(target)) return ECHILD;
|
|
|
+ exitstatus = _MKWAIT_EXIT(target->exitcode);
|
|
|
+ result = copyout((void *)&exitstatus, status, sizeof(int));
|
|
|
+
|
|
|
+ if (exitstatus >= 0)
|
|
|
+ {
|
|
|
+ // *retval = exitstatus;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ lock_acquire(target->waitlock);
|
|
|
+ cv_wait(target->waiting, target->waitlock);
|
|
|
+ lock_release(target->waitlock);
|
|
|
+ *retval = exitstatus;
|
|
|
+ proc_destroy(target);
|
|
|
+ return 0;
|
|
|
}*/
|
|
|
|
|
|
-/* stub handler for waitpid() system call */
|
|
|
int sys_waitpid(pid_t pid, userptr_t status, int options, pid_t * retval)
|
|
|
{
|
|
|
- kprintf("Waiting on: %d\n", pid);
|
|
|
(void)status;
|
|
|
if (options != 0)
|
|
|
{
|
|
@@ -195,10 +292,10 @@ int sys_fork(struct trapframe * tf, int * retval)
|
|
|
{
|
|
|
// create new process' memory space
|
|
|
struct proc * child = proc_create_runprogram("childproc");
|
|
|
- struct addrspace * new_as;
|
|
|
- struct trapframe * new_tf = kmalloc(sizeof(*tf));
|
|
|
-
|
|
|
if ((!child)) return ENOMEM;
|
|
|
+
|
|
|
+ struct trapframe * new_tf = kmalloc(sizeof(*tf));
|
|
|
+ struct addrspace * new_as;
|
|
|
as_copy(curproc_getas(), &new_as);
|
|
|
|
|
|
if (!(new_as) || !(new_tf))
|