diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-14 20:15:19 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-14 20:15:19 +0100 |
commit | fcc321d0ef1771edff61a986df62d2cda2d7485e (patch) | |
tree | 15bfe6c37a53010342b8fc0f66262bbd0a2ea5f8 /src | |
parent | fea4c7a29e26bccab9a2982d600bd272e21a925a (diff) | |
download | kogata-fcc321d0ef1771edff61a986df62d2cda2d7485e.tar.gz kogata-fcc321d0ef1771edff61a986df62d2cda2d7485e.zip |
Use btrees to find memory regions.
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/include/process.h | 2 | ||||
-rw-r--r-- | src/kernel/user/process.c | 46 |
2 files changed, 34 insertions, 14 deletions
diff --git a/src/kernel/include/process.h b/src/kernel/include/process.h index c9615d7..edb25c3 100644 --- a/src/kernel/include/process.h +++ b/src/kernel/include/process.h @@ -11,6 +11,7 @@ // - mchmap = change mode on already mapped zone (eg. after loading code) #include <hashtbl.h> +#include <btree.h> #include <thread.h> #include <vfs.h> @@ -28,6 +29,7 @@ struct user_region; typedef struct process { pagedir_t *pd; struct user_region *regions; + btree_t *regions_idx; hashtbl_t *filesystems; diff --git a/src/kernel/user/process.c b/src/kernel/user/process.c index c0aea53..a4383f7 100644 --- a/src/kernel/user/process.c +++ b/src/kernel/user/process.c @@ -33,20 +33,16 @@ process_t *current_process() { process_t *new_process(process_t *parent) { process_t *proc = (process_t*)malloc(sizeof(process_t)); - if (proc == 0) return 0; + if (proc == 0) goto error; proc->filesystems = create_hashtbl(str_key_eq_fun, str_hash_fun, free_key); - if (proc->filesystems == 0) { - free(proc); - return 0; - } + if (proc->filesystems == 0) goto error; + + proc->regions_idx = create_btree(id_key_cmp_fun, 0); + if (proc->regions_idx == 0) goto error; proc->pd = create_pagedir(proc_usermem_pf, proc); - if (proc->pd == 0) { - delete_hashtbl(proc->filesystems); - free(proc); - return 0; - } + if (proc->pd == 0) goto error; proc->regions = 0; proc->thread = 0; @@ -54,6 +50,12 @@ process_t *new_process(process_t *parent) { proc->parent = parent; return proc; + +error: + if (proc && proc->regions_idx) delete_btree(proc->regions_idx); + if (proc && proc->filesystems) delete_hashtbl(proc->filesystems); + if (proc) free(proc); + return 0; } static void run_user_code(void* entry) { @@ -129,10 +131,13 @@ fs_t *proc_find_fs(process_t *p, const char* name) { // ============================= // static user_region_t *find_user_region(process_t *proc, const void* addr) { - for (user_region_t *it = proc->regions; it != 0; it = it->next) { - if (addr >= it->addr && addr < it->addr + it->size) return it; - } - return 0; + user_region_t *r = (user_region_t*)btree_lower(proc->regions_idx, addr); + if (r == 0) return 0; + + ASSERT(addr >= r->addr); + + if (addr >= r->addr + r->size) return 0; + return r; } bool mmap(process_t *proc, void* addr, size_t size, int mode) { @@ -151,6 +156,12 @@ bool mmap(process_t *proc, void* addr, size_t size, int mode) { return false; } + bool add_ok = btree_add(proc->regions_idx, r->addr, r); + if (!add_ok) { + free(r); + return false; + } + r->mode = mode; r->file = 0; r->file_offset = 0; @@ -177,6 +188,12 @@ bool mmap_file(process_t *proc, fs_handle_t *h, size_t offset, void* addr, size_ return false; } + bool add_ok = btree_add(proc->regions_idx, r->addr, r); + if (!add_ok) { + free(r); + return false; + } + ref_file(h); r->mode = mode; @@ -218,6 +235,7 @@ bool munmap(process_t *proc, void* addr) { if (r->file != 0) unref_file(r->file); + btree_remove_v(proc->regions_idx, r->addr, r); free(r); return true; |