Efficient reallocation of SHM chunks (mostly)
This commit is contained in:
parent
deeb1c42a5
commit
d0bfc0a5bb
@ -98,6 +98,42 @@ node_t * list_insert_after(list_t * list, node_t * before, void * item) {
|
||||
return node;
|
||||
}
|
||||
|
||||
void list_append_before(list_t * list, node_t * after, node_t * node) {
|
||||
assert(!(node->next || node->prev) && "Node is already in a list.");
|
||||
node->owner = list;
|
||||
if (!list->length) {
|
||||
list_append(list, node);
|
||||
return;
|
||||
}
|
||||
if (after == NULL) {
|
||||
node->next = NULL;
|
||||
node->prev = list->tail;
|
||||
list->tail->next = node;
|
||||
list->tail = node;
|
||||
list->length++;
|
||||
return;
|
||||
}
|
||||
if (after == list->head) {
|
||||
list->head = node;
|
||||
} else {
|
||||
after->prev->next = node;
|
||||
node->prev = after->prev;
|
||||
}
|
||||
node->next = after;
|
||||
after->prev = node;
|
||||
list->length++;
|
||||
}
|
||||
|
||||
node_t * list_insert_before(list_t * list, node_t * after, void * item) {
|
||||
node_t * node = malloc(sizeof(node_t));
|
||||
node->value = item;
|
||||
node->next = NULL;
|
||||
node->prev = NULL;
|
||||
node->owner = NULL;
|
||||
list_append_before(list, after, node);
|
||||
return node;
|
||||
}
|
||||
|
||||
list_t * list_create(void) {
|
||||
/* Create a fresh list */
|
||||
list_t * out = malloc(sizeof(list_t));
|
||||
|
@ -43,6 +43,9 @@ void list_merge(list_t * target, list_t * source);
|
||||
void list_append_after(list_t * list, node_t * before, node_t * node);
|
||||
node_t * list_insert_after(list_t * list, node_t * before, void * item);
|
||||
|
||||
void list_append_before(list_t * list, node_t * after, node_t * node);
|
||||
node_t * list_insert_before(list_t * list, node_t * after, void * item);
|
||||
|
||||
#define foreach(i, list) for (node_t * i = list->head; i != NULL; i = i->next)
|
||||
|
||||
#endif
|
||||
|
@ -163,6 +163,55 @@ static void * map_in (shm_chunk_t * chunk, process_t * proc) {
|
||||
mapping->num_vaddrs = chunk->num_frames;
|
||||
mapping->vaddrs = malloc(sizeof(uintptr_t) * mapping->num_vaddrs);
|
||||
|
||||
debug_print(INFO, "want %d bytes, running through mappings...", mapping->num_vaddrs * 0x1000);
|
||||
uintptr_t last_address = SHM_START;
|
||||
foreach(node, proc->shm_mappings) {
|
||||
shm_mapping_t * m = node->value;
|
||||
if (m->vaddrs[0] > last_address) {
|
||||
size_t gap = (uintptr_t)m->vaddrs[0] - last_address;
|
||||
debug_print(INFO, "gap found at 0x%x of size %d", last_address, gap);
|
||||
if (gap >= mapping->num_vaddrs * 0x1000) {
|
||||
debug_print(INFO, "Gap is sufficient, we can insert here.");
|
||||
|
||||
/* Map the gap */
|
||||
for (unsigned int i = 0; i < chunk->num_frames; ++i) {
|
||||
page_t * page = get_page(last_address + i * 0x1000, 1, proc->thread.page_directory);
|
||||
alloc_frame(page, 0, 1);
|
||||
page->frame = chunk->frames[i];
|
||||
mapping->vaddrs[i] = last_address + i * 0x1000;
|
||||
}
|
||||
|
||||
/* Insert us before this node */
|
||||
list_insert_before(proc->shm_mappings, node, mapping);
|
||||
|
||||
return (void *)mapping->vaddrs[0];
|
||||
}
|
||||
}
|
||||
last_address = m->vaddrs[0] + m->num_vaddrs * 0x1000;
|
||||
debug_print(INFO, "[0x%x:0x%x] %s", m->vaddrs[0], last_address, m->chunk->parent->name);
|
||||
}
|
||||
if (proc->image.shm_heap > last_address) {
|
||||
size_t gap = proc->image.shm_heap - last_address;
|
||||
debug_print(INFO, "gap found at 0x%x of size %d", last_address, gap);
|
||||
if (gap >= mapping->num_vaddrs * 0x1000) {
|
||||
debug_print(INFO, "Gap is sufficient, we can insert here.");
|
||||
|
||||
for (unsigned int i = 0; i < chunk->num_frames; ++i) {
|
||||
page_t * page = get_page(last_address + i * 0x1000, 1, proc->thread.page_directory);
|
||||
alloc_frame(page, 0, 1);
|
||||
page->frame = chunk->frames[i];
|
||||
mapping->vaddrs[i] = last_address + i * 0x1000;
|
||||
}
|
||||
|
||||
list_insert(proc->shm_mappings, mapping);
|
||||
|
||||
return (void *)mapping->vaddrs[0];
|
||||
} else {
|
||||
debug_print(INFO, "should be more efficient here - there is space available, but we are not going to use it");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (uint32_t i = 0; i < chunk->num_frames; i++) {
|
||||
uintptr_t new_vpage = proc_sbrk(1, proc);
|
||||
assert(new_vpage % 0x1000 == 0);
|
||||
@ -241,6 +290,10 @@ int shm_release (char * path) {
|
||||
spin_lock(&bsl);
|
||||
process_t * proc = (process_t *)current_process;
|
||||
|
||||
if (proc->group != 0) {
|
||||
proc = process_from_pid(proc->group);
|
||||
}
|
||||
|
||||
/* First, find the right chunk */
|
||||
shm_node_t * _node = get_node(path, 0);
|
||||
if (!_node) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user