Reuse stacks of dead processes
In order to make the stack-space of dead processes usable again, I addeed a stack data structure which holds unused stack pointers. When a process is killed, the destructor is called, which will free the stack associated with the process.master
parent
1a6abb5e1b
commit
df0a944528
@ -1,26 +1,58 @@
|
|||||||
|
#include "../kernel.h"
|
||||||
#include "malloc.h"
|
#include "malloc.h"
|
||||||
#include "ecall.h"
|
#include "ecall.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
malloc_info global_malloc_info = { 0 };
|
// information about the systems memory layout is stored here
|
||||||
void* allocate_memory_end;
|
static malloc_info global_malloc_info = { 0 };
|
||||||
|
// this pointer points to the end of unused memory
|
||||||
|
static void* allocate_memory_end;
|
||||||
|
// this stack holds currently unused program stacks
|
||||||
|
// it is a stack in the sense that you can push and pop variables
|
||||||
|
static struct voidptr_stack unused_stacks;
|
||||||
|
|
||||||
|
void stash_stack(void* stack_top)
|
||||||
|
{
|
||||||
|
if (voidptr_stack_push(&unused_stacks, stack_top) == 0) {
|
||||||
|
// if this happens, we know we messed up and created more stacks than we
|
||||||
|
// could ever have processes running simultaneously!
|
||||||
|
// we probably have an erro in retrieving stashed stacks?
|
||||||
|
dbgln("cannot stash stack, no space left! This should never ever happen!", 65);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void malloc_init(malloc_info* given_info)
|
void malloc_init(malloc_info* given_info)
|
||||||
{
|
{
|
||||||
global_malloc_info = *given_info;
|
global_malloc_info = *given_info;
|
||||||
allocate_memory_end = given_info->allocate_memory_end;
|
allocate_memory_end = given_info->allocate_memory_end;
|
||||||
|
allocate_memory_end = (void*) (((int) allocate_memory_end) - PROCESS_COUNT);
|
||||||
|
voidptr_stack_new(&unused_stacks, (void**) allocate_memory_end, PROCESS_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate stack and return a pointer to the *end* of the allocated region
|
// allocate stack and return a pointer to the *end* of the allocated region
|
||||||
// this doesn't reuse stack from functions which exited
|
// this doesn't reuse stack from functions which exited
|
||||||
optional_voidptr malloc_stack(size_t size)
|
optional_voidptr malloc_stack()
|
||||||
{
|
{
|
||||||
void* new_alloc_end = (void*) (((int) allocate_memory_end) - size);
|
// try to reuse a stack top
|
||||||
|
void* stack_top = voidptr_stack_pop(&unused_stacks);
|
||||||
|
|
||||||
|
if (stack_top != NULL) {
|
||||||
|
return (optional_voidptr) { .value = stack_top };
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise allocate a new stack at the end of available memory
|
||||||
|
void* new_alloc_end = (void*) (((int) allocate_memory_end) - USER_STACK_SIZE);
|
||||||
|
|
||||||
|
// check if we ran out of space
|
||||||
if (new_alloc_end < global_malloc_info.allocate_memory_start)
|
if (new_alloc_end < global_malloc_info.allocate_memory_start)
|
||||||
return (optional_voidptr) { .error = ENOMEM };
|
return (optional_voidptr) { .error = ENOMEM };
|
||||||
void* stack_top = allocate_memory_end;
|
|
||||||
|
|
||||||
|
stack_top = allocate_memory_end;
|
||||||
allocate_memory_end = new_alloc_end;
|
allocate_memory_end = new_alloc_end;
|
||||||
return (optional_voidptr) { .value = stack_top };
|
return (optional_voidptr) { .value = stack_top };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_stack(void* stack_top)
|
||||||
|
{
|
||||||
|
stash_stack(stack_top);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue