[proc] Fix some latent management bugs
This commit is contained in:
parent
b8d8140530
commit
ddc71135af
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user