Commit 854f1a37 authored by Léo Grange's avatar Léo Grange

implement memory area manipulation functions

parent 5c141032
#include "mem_area.h"
#include <sys/process.h>
#include <utils/pool_alloc.h>
#include <fs/vfs_file.h>
#include <utils/log.h>
// pool allocation data
static struct pool_alloc _mem_area_pool = POOL_INIT(struct mem_area);
void mem_area_init() {
printk(LOG_DEBUG, "mem_area: area/page=%d\n", _mem_area_pool.perpage);
}
struct mem_area *mem_area_alloc() {
struct mem_area *ret;
ret = pool_alloc(&_mem_area_pool);
if(ret != NULL) {
ret->flags = 0;
ret->address = NULL;
ret->max_size = 0;
}
return ret;
}
void mem_area_free(struct mem_area *area) {
pool_free(&_mem_area_pool, area);
}
struct mem_area *mem_area_find(struct process *proc, void *address) {
// for now, the list is not sorted, so check for each
struct list_head *cur;
struct mem_area *ret = NULL;
list_for_each(cur, &(proc->mem_areas)) {
// check if address is inside this area
struct mem_area *area = container_of(cur, struct mem_area, list);
if(address >= area->address && address < (area->address + area->max_size)) {
ret = area;
break;
}
}
return ret;
}
/**
* internal function, check if an area is defined in the given address range
* Return 0 if this range is empty, 1 if an area exists.
*/
static int mem_area_check_range(struct process *proc, void *addr_begin, size_t size) {
struct list_head *cur;
list_for_each(cur, &(proc->mem_areas)) {
// check if address range intersects with this area
struct mem_area *area = container_of(cur, struct mem_area, list);
if(area->address < (addr_begin + size)
&& (area->address + area->max_size) > addr_begin)
return 1;
}
return 0;
}
int mem_area_insert(struct process *proc, struct mem_area *area) {
// check for any overlayed area
if(!mem_area_check_range(proc, area->address, area->max_size)) {
// not sorted, insert in front
list_push_front(& proc->mem_areas, & area->list);
return 0;
}
printk(LOG_ERR, "mem_area: unable to insert area (overlay)\n");
return -1;
}
int mem_area_copy_raw(struct mem_area *area, size_t offset, void *dest, size_t size) {
int ret = -1;
if(area->flags & MEM_AREA_TYPE_ANON) {
// anonymous area, the current implementation do nothing...
ret = 0;
}
else if(area->flags & MEM_AREA_TYPE_FILE) {
// file mapped to memory, for now use a generic way to handle them
// TODO improve this with map_area_ops struct to allow "override"
size_t nbread;
vfs_lseek(area->file.filep, SEEK_SET, offset);
nbread = vfs_read(area->file.filep, dest, size);
ret = nbread == size ? 0 : -1;
}
return ret;
}
......@@ -31,7 +31,7 @@ struct mem_area {
union {
struct {
// file structure of the file mapped to this area
struct file *f;
struct file *filep;
// origin's position in the file
size_t origin;
......@@ -61,6 +61,7 @@ void mem_area_init();
* Return a newly allocated memory area, not initialized.
*/
struct mem_area *mem_area_alloc();
void mem_area_free(struct mem_area *area);
/**
......
......@@ -8,7 +8,7 @@
#include <utils/bitfield.h>
#include <interface/fixos/fcntl.h>
#include <interface/fixos/errno.h>
#include <sys/mem_areas.h>
#include <sys/mem_area.h>
#include <loader/elfloader/loader.h>
#include <fs/vfs_file.h>
......@@ -111,7 +111,7 @@ struct process *process_alloc() {
arch_adrsp_init(& proc->addr_space);
proc->dir_list = NULL;
INIT_LIST_HEAD(proc->mem_areas);
INIT_LIST_HEAD(& proc->mem_areas);
sigemptyset(& proc->sig_blocked);
......
......@@ -12,7 +12,8 @@ C_SRC_L:= \
kdebug.c \
sysctl.c \
waitqueue.c \
tty.c
tty.c \
mem_area.c
CURDIR:=sys
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment