From d57c82f4969bfc7c523375bcedfd83139284fcb9 Mon Sep 17 00:00:00 2001 From: augustin64 Date: Sun, 31 Mar 2024 18:27:05 +0200 Subject: [PATCH] TP1: VMap: Initial commit --- TP/TP1/rendu/vmap.c | 132 ++++++++++++++++++++++++++++++++++++++++++++ TP/TP1/rendu/vmap.h | 32 ++++++++++- 2 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 TP/TP1/rendu/vmap.c diff --git a/TP/TP1/rendu/vmap.c b/TP/TP1/rendu/vmap.c new file mode 100644 index 0000000..70ad2e3 --- /dev/null +++ b/TP/TP1/rendu/vmap.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include + +#include "vmap.h" + +VMap* vmap_init() { + VMap* vmap = (VMap*)malloc(sizeof(VMap)); + vmap->mmap = mmap_init(); + vmap->pages = createLinkedList(); + vmap->index = 0; + + return vmap; +} + +PageMapInfo* vmap_new_page(VMap* vmap) { + PageMapInfo* page = (PageMapInfo*)malloc(sizeof(PageMapInfo)); + + bool moved; + page->key = page_create(vmap->mmap, &moved)->key; + page->start = vmap->index; + page->cursor = 0; + page->nb_allocs = 0; + page->swapped = moved; + + vmap->index += 4096; + + insertFirst(vmap->pages, page->start, page); + + return page; +} + +int page_map_available_size(PageMapInfo* page) { + int avail = page->start + 4096 - page->cursor; + assert(avail >= 0); + return avail; +} + + +void vmap_free_page(VMap* vmap, PageMapInfo* page) { + deleteElement(vmap->pages, page->key); + page_remove(vmap->mmap, page->key); + free(page); +} + +PageMapInfo* vmap_get_page(VMap* vmap, void* ptr) { + node* current = vmap->pages->head; + while (current) { + PageMapInfo* page = current->data; + if (page->start <= (int64_t)ptr && page->start+4096 > (int64_t)ptr) { + return page; + } + current = current->next; + } + return NULL; +} + +void vmap_unswap(VMap* vmap, PageMapInfo* page) { + if (!page->swapped) + return; + + read_from_swap(vmap->mmap, page_lookup(vmap->mmap, page->key)); + page->swapped = false; +} + + +void* my_malloc(VMap* vmap, int size) { + // Parcours de la liste pour trouver un candidat. Sinon, nouvelle page + node* current = vmap->pages->head; + while (current) { + PageMapInfo* page = current->data; + if (page_map_available_size(page) >= size) { + void* ptr = (void*)((uint64_t)page->start+page->cursor); + page->cursor += size; + page->nb_allocs++; + + return ptr; + } + current = current->next; + } + + PageMapInfo* page = vmap_new_page(vmap); + + void* ptr = (void*)((uint64_t)page->start+page->cursor); + page->cursor += size; + page->nb_allocs++; + + return ptr; +} + +void my_free(VMap* vmap, void* ptr) { + PageMapInfo* page = vmap_get_page(vmap, ptr); + + if (!page) { + fprintf(stderr, "my_free: Double free or memory corrupted\n"); + exit(1); + } + + page->nb_allocs--; + if (page->nb_allocs == 0) { + vmap_free_page(vmap, page); + } +} + +void my_copy(VMap* vmap, void* src, void* dst, int size) { + PageMapInfo* page_map_src = vmap_get_page(vmap, src); + PageMapInfo* page_map_dst = vmap_get_page(vmap, dst); + + if (((int64_t)src % 4096) + size >= 4096) { + fprintf(stderr, "my_copy: size not available in this src page\n"); + exit(1); + } + + if (((int64_t)dst % 4096) + size >= 4096) { + fprintf(stderr, "my_copy: size not available in this dst page\n"); + exit(1); + } + + if (page_map_src->swapped) { + vmap_unswap(vmap, page_map_src); + } + if (page_map_dst->swapped) { + vmap_unswap(vmap, page_map_dst); + } + + PageInfo* page_src = page_lookup(vmap->mmap, page_map_src->key); + PageInfo* page_dst = page_lookup(vmap->mmap, page_map_dst->key); + + memcpy(page_dst->data, page_src->data, size); +} \ No newline at end of file diff --git a/TP/TP1/rendu/vmap.h b/TP/TP1/rendu/vmap.h index fb30ca8..30a29c0 100644 --- a/TP/TP1/rendu/vmap.h +++ b/TP/TP1/rendu/vmap.h @@ -1,3 +1,29 @@ -void *my_malloc(int size); -void my_free(void *data); -void my_copy(void *mem, void *data, int size); \ No newline at end of file +#ifndef DEF_VMAP_H +#define DEF_VMAP_H + +#include "mmap.h" + +typedef struct VMap { + MMap* mmap; + linkedList* pages; + int index; // index of virt memory +} VMap; + +typedef struct PageMapInfo { + int start; + int key; // key for mmap + int cursor; // Last allocation end + int nb_allocs; // Free page if 0 + bool swapped; +} PageMapInfo; + +/** + * Get page hosting a certain pointer +*/ +PageMapInfo* vmap_get_page(VMap* vmap, void* ptr); + +void* my_malloc(VMap* vmap, int size); +void my_free(VMap* vmap, void* ptr); +void my_copy(VMap* vmap, void* src, void* dst, int size); + +#endif \ No newline at end of file