kernel: make an attempt to clean up processes in SMP

This commit is contained in:
K. Lange 2021-06-04 21:51:45 +09:00
parent 39a267e871
commit d9e462633f

View File

@ -45,6 +45,7 @@ tree_t * process_tree; /* Stores the parent-child process relationships; the ro
list_t * process_list; /* Stores all existing processes. Mostly used for sanity checking or for places where iterating over all processes is useful. */
list_t * process_queue; /* Scheduler ready queue. This the round-robin source. The head is the next process to run. */
list_t * sleep_queue; /* Ordered list of processes waiting to be awoken by timeouts. The head is the earliest thread to awaken. */
list_t * reap_queue; /* Processes that could not be cleaned up and need to be deleted. */
struct ProcessorLocal processor_local_data[32] = {0};
int processor_count = 1;
@ -55,6 +56,7 @@ static spin_lock_t tree_lock = { 0 };
static spin_lock_t process_queue_lock = { 0 };
static spin_lock_t wait_lock_tmp = { 0 };
static spin_lock_t sleep_lock = { 0 };
static spin_lock_t reap_lock = { 0 };
#define must_have_lock(lck) if (lck.owner != this_core->cpu_id+1) { printf("Failed lock check.\n"); arch_fatal(); }
@ -200,6 +202,7 @@ void initialize_process_tree(void) {
process_list = list_create("global process list",NULL);
process_queue = list_create("global scheduler queue",NULL);
sleep_queue = list_create("global timed sleep queue",NULL);
reap_queue = list_create("processes awaiting later cleanup",NULL);
/* TODO: PID bitset? */
}
@ -488,6 +491,50 @@ process_t * spawn_process(volatile process_t * parent, int flags) {
extern void tree_remove_reparent_root(tree_t * tree, tree_node_t * node);
void process_reap(process_t * proc) {
if (proc->signal_kstack) {
free(proc->signal_kstack);
}
/* Unmark the stack bottom's fault detector */
mmu_frame_allocate(
mmu_get_page(proc->image.stack - KERNEL_STACK_SIZE, 0),
MMU_FLAG_KERNEL | MMU_FLAG_WRITABLE);
free((void *)(proc->image.stack - KERNEL_STACK_SIZE));
process_release_directory(proc->thread.page_directory);
free(proc->name);
free(proc);
}
static int process_is_owned(process_t * proc) {
for (int i = 0; i < processor_count; ++i) {
if (processor_local_data[i].previous_process == proc ||
processor_local_data[i].current_process == proc) {
return 1;
}
}
return 0;
}
void process_reap_later(process_t * proc) {
spin_lock(reap_lock);
/* See if we can delete anything */
while (reap_queue->head) {
process_t * proc = reap_queue->head->value;
if (!process_is_owned(proc)) {
free(list_dequeue(reap_queue));
process_reap(proc);
} else {
break;
}
}
/* And delete this thing later */
list_insert(reap_queue, proc);
spin_unlock(reap_lock);
}
/**
* @brief Remove a process from the valid process list.
*
@ -525,39 +572,20 @@ void process_delete(process_t * proc) {
// FIXME bitset_clear(&pid_set, proc->id);
proc->tree_entry = NULL;
shm_release_all(proc);
free(proc->shm_mappings);
/* Is someone using this process? */
for (int i = 0; i < processor_count; ++i) {
if (i == this_core->cpu_id) continue;
if (processor_local_data[i].current_process == proc) {
printf("Wanted to delete a process someone else was using.\n");
} else if (processor_local_data[i].previous_process == proc) {
printf("Wanted to delete a process but it's someone else's previous.\n");
printf(" pid = %d\n", proc->id);
printf(" name = %s\n", proc->name);
printf(" owned by = %d\n", proc->owner);
if (processor_local_data[i].previous_process == proc ||
processor_local_data[i].current_process == proc) {
process_reap_later(proc);
return;
}
return;
}
/* Free these later */
shm_release_all(proc);
free(proc->shm_mappings);
if (proc->signal_kstack) {
free(proc->signal_kstack);
}
/* Unmark the stack bottom's fault detector */
mmu_frame_allocate(
mmu_get_page(proc->image.stack - KERNEL_STACK_SIZE, 0),
MMU_FLAG_KERNEL | MMU_FLAG_WRITABLE);
free((void *)(proc->image.stack - KERNEL_STACK_SIZE));
process_release_directory(proc->thread.page_directory);
free(proc->name);
free(proc);
process_reap(proc);
}
/**