[proc] Fix some latent management bugs

This commit is contained in:
Kevin Lange 2011-12-15 21:08:48 -06:00
parent b8d8140530
commit ddc71135af
6 changed files with 57 additions and 8 deletions

View File

@ -139,6 +139,10 @@ void tree_remove(tree_t * tree, tree_node_t * node) {
if (!parent) return;
tree->nodes--;
list_delete(parent->children, list_find(parent->children, node));
foreach(child, node->children) {
/* Reassign the parents */
((tree_node_t *)child->value)->parent = parent;
}
list_merge(parent->children, node->children);
free(node);
}

View File

@ -155,7 +155,7 @@ system(
}
/* Grab the child's return value */
int ret = child_task->status;
free(child_task);
delete_process(child_task);
return ret;
}
}

View File

@ -431,6 +431,28 @@ uint32_t shell_cmd_dmesg(int argc, char * argv[]) {
return 0;
}
uint32_t shell_cmd_kill(int argc, char * argv[]) {
if (argc < 2) {
kprintf(" kill pid\n");
kprintf(" Remove the zombie process with PID `n`.\n");
return 1;
}
pid_t id = atoi(argv[1]);
process_t * child_task = process_from_pid(id);
if (!child_task) {
kprintf("No process with pid %d found.\n", id);
return 1;
} else if (!child_task->finished) {
kprintf("Process %d is not a zombie.\n", id);
return 1;
} else {
kprintf("Killing process %d [0x%x]\n", child_task->id, child_task);
delete_process(child_task);
return 0;
}
}
void install_commands() {
shell_install_command("cd", shell_cmd_cd);
shell_install_command("ls", shell_cmd_ls);
@ -448,6 +470,7 @@ void install_commands() {
shell_install_command("test-tree", shell_cmd_testtree);
shell_install_command("ps", shell_cmd_ps);
shell_install_command("dmesg", shell_cmd_dmesg);
shell_install_command("kill", shell_cmd_kill);
}
void add_path_contents() {

View File

@ -15,6 +15,10 @@ list_t * process_queue; /* Ready queue */
list_t * reap_queue; /* Processes to reap */
volatile process_t * current_process = NULL;
static uint8_t volatile ready_lock;
static uint8_t volatile reap_lock;
static uint8_t volatile tree_lock;
/* Default process name string */
char * default_name = "[unnamed]";
@ -46,6 +50,9 @@ void debug_print_process_tree_node(tree_node_t * node, size_t height) {
/* And, if it has one, its description */
kprintf(" %s", proc->description);
}
if (proc->finished) {
kprintf(" [zombie]");
}
/* Linefeed */
kprintf("\n");
foreach(child, node->children) {
@ -68,7 +75,9 @@ void debug_print_process_tree() {
* @return A pointer to the next process in the queue.
*/
process_t * next_ready_process() {
spin_lock(&ready_lock);
node_t * np = list_dequeue(process_queue);
spin_unlock(&ready_lock);
assert(np && "Ready queue is empty.");
process_t * next = np->value;
free(np);
@ -76,8 +85,10 @@ process_t * next_ready_process() {
}
process_t * next_reapable_process() {
spin_lock(&reap_lock);
node_t * np = list_dequeue(reap_queue);
assert(np && "Nothing to reap.");
spin_unlock(&reap_lock);
if (!np) { return NULL; }
process_t * next = np->value;
free(np);
return next;
@ -89,11 +100,15 @@ process_t * next_reapable_process() {
* @param proc Process to reinsert
*/
void make_process_ready(process_t * proc) {
spin_lock(&ready_lock);
list_insert(process_queue, (void *)proc);
spin_unlock(&ready_lock);
}
void make_process_reapable(process_t * proc) {
spin_lock(&reap_lock);
list_insert(reap_queue, (void *)proc);
spin_unlock(&reap_lock);
}
/*
@ -111,11 +126,11 @@ void delete_process(process_t * proc) {
assert((entry != process_tree->root) && "Attempted to kill init.");
/* Remove the entry. */
spin_lock(&tree_lock);
tree_remove(process_tree, entry);
}
spin_unlock(&tree_lock);
void process_destroy() {
/* Free all the dynamicly allocate elements of a process */
free(proc);
}
/*
@ -183,9 +198,11 @@ void process_disown(process_t * proc) {
/* Find the process in the tree */
tree_node_t * entry = proc->tree_entry;
/* Break it of from its current parent */
spin_lock(&tree_lock);
tree_break_off(process_tree, entry);
/* And insert it back elsewhere */
tree_node_insert_child_node(process_tree, process_tree->root, entry);
spin_unlock(&tree_lock);
}
/*
@ -242,7 +259,9 @@ process_t * spawn_process(volatile process_t * parent) {
tree_node_t * entry = tree_node_create(proc);
assert(entry && "Failed to allocate a process tree node for new process.");
proc->tree_entry = entry;
spin_lock(&tree_lock);
tree_node_insert_child_node(process_tree, parent->tree_entry, entry);
spin_unlock(&tree_lock);
/* Return the new process */
return proc;
@ -258,7 +277,9 @@ uint8_t process_compare(void * proc_v, void * pid_v) {
process_t * process_from_pid(pid_t pid) {
assert((pid > 0) && "Tried to retreive a process with PID < 0");
spin_lock(&tree_lock);
tree_node_t * entry = tree_find(process_tree,&pid,process_compare);
spin_unlock(&tree_lock);
if (entry) {
return (process_t *)entry->value;
} else {

View File

@ -102,7 +102,7 @@ static int wait(int child) {
}
/* Grab the child's return value */
int ret = child_task->status;
free(child_task);
delete_process(child_task);
return ret;
}

View File

@ -71,7 +71,6 @@ void free_directory(page_directory_t * dir) {
}
void reap_process(process_t * proc) {
delete_process(proc);
free((void *)(proc->image.stack - KERNEL_STACK_SIZE));
free_directory(proc->thread.page_directory);
free((void *)(proc->fds.entries));
@ -235,7 +234,9 @@ switch_task() {
IRQ_OFF;
while (should_reap()) {
process_t * proc = next_reapable_process();
reap_process(proc);
if (proc) {
reap_process(proc);
}
}
IRQ_ON;
return;