From 513d5aaac86da67e1361b4c9792a5f3889439c19 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Sun, 9 Nov 2008 11:42:10 +0200 Subject: [PATCH] Added exit.c that seemed to be out of tree. --- tasks/mm0/src/exit.c | 102 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 tasks/mm0/src/exit.c diff --git a/tasks/mm0/src/exit.c b/tasks/mm0/src/exit.c new file mode 100644 index 0000000..ee70f24 --- /dev/null +++ b/tasks/mm0/src/exit.c @@ -0,0 +1,102 @@ +/* + * exit() + * + * Copyright (C) 2008 Bahadir Balban + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Sends vfs task information about forked child, and its utcb + */ +int vfs_notify_exit(struct tcb *task, int status) +{ + int err = 0; + + // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); + + l4_save_ipcregs(); + + /* Write parent and child information */ + write_mr(L4SYS_ARG0, task->tid); + write_mr(L4SYS_ARG1, status); + + if ((err = l4_sendrecv(VFS_TID, VFS_TID, + L4_IPC_TAG_NOTIFY_EXIT)) < 0) { + printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); + goto out; + } + + /* Check if syscall was successful */ + if ((err = l4_get_retval()) < 0) { + printf("%s: VFS returned ipc error: %d.\n", + __FUNCTION__, err); + goto out; + } + +out: + l4_restore_ipcregs(); + return err; +} + + +/* Closes all file descriptors of a task */ +int task_close_files(struct tcb *task) +{ + int err = 0; + + /* Flush all file descriptors */ + for (int fd = 0; fd < TASK_FILES_MAX; fd++) + if (task->files->fd[fd].vmfile) + if ((err = sys_close(task, fd)) < 0) { + printf("File close error. Tid: %d," + " fd: %d, error: %d\n", + task->tid, fd, err); + break; + } + return err; +} + +void sys_exit(struct tcb *task, int status) +{ + struct task_ids ids = { + .tid = task->tid, + .spid = task->spid, + .tgid = task->tgid, + }; + + /* Flush all IO on task's files and close fds */ + task_close_files(task); + + /* Tell vfs that task is exiting */ + vfs_notify_exit(task, status); + + /* Remove utcb shm areas from vfs */ + // printf("Unmapping 0x%p from vfs as utcb of %d\n", task->utcb, task->tid); + utcb_unmap_from_task(task, find_task(VFS_TID)); + + /* Free task's local tcb */ + tcb_destroy(task); + + /* Ask the kernel to delete it from its records */ + l4_thread_control(THREAD_DESTROY, &ids); + + /* TODO: Wake up any waiters about task's destruction */ +#if 0 + struct tcb *parent = find_task(task->parentid); + if (parent->waiting) { + exregs_set_mr_return(status); + l4_exchange_registers(parent->tid); + l4_thread_control(THREAD_RUN, parent->tid); + } +#endif +} +