From 130eaa54f0a3d2e4b90094014d61bafda19421d0 Mon Sep 17 00:00:00 2001 From: augustin64 Date: Fri, 19 Apr 2024 09:57:02 +0200 Subject: [PATCH] Add VMap lock --- TP/TP2/rendu/README.md | 14 +++ TP/TP2/rendu/tests/success/threads.c | 56 +++++++++++ TP/TP2/rendu/vmap.c | 137 +++++++++++++++------------ TP/TP2/rendu/vmap.h | 5 +- 4 files changed, 148 insertions(+), 64 deletions(-) create mode 100644 TP/TP2/rendu/README.md create mode 100644 TP/TP2/rendu/tests/success/threads.c diff --git a/TP/TP2/rendu/README.md b/TP/TP2/rendu/README.md new file mode 100644 index 0000000..9a95153 --- /dev/null +++ b/TP/TP2/rendu/README.md @@ -0,0 +1,14 @@ +# TP2 + +## Tests + +Exécuter tous les tests et s'arrêter quand l'un produit un résultat différent de celui attendu +```bash +./make.sh +``` + +## Implémentation + +Pour les différents processus: +- une structure de `(VMap, pid) list` est utilisée pour gérer les VMaps reliées à chaque processus +- Dès qu'une VMap est récupérée, elle est verrouillée (Un mutex par VMap), ne fonctionne pas \ No newline at end of file diff --git a/TP/TP2/rendu/tests/success/threads.c b/TP/TP2/rendu/tests/success/threads.c new file mode 100644 index 0000000..b541e77 --- /dev/null +++ b/TP/TP2/rendu/tests/success/threads.c @@ -0,0 +1,56 @@ +#include +#include + +#include "../../vmap.h" + +#define N 6 + +struct args { + Memory* mem; + int count; + int size; + int pid; +}; + + +void* thread(void* void_args) { + struct args* args = (struct args*)void_args; + Memory* mem = args->mem; + int count = args->count; + int size = args->size; + int pid = args->pid; + + void** ptrs = malloc(sizeof(void*)*count); + for (int i=0; i < count; i++) { + ptrs[i] = my_malloc(mem, size, pid); + } + + for (int i=0; i < count; i++) { + my_free(mem, ptrs[i], pid); + } + free(ptrs); + return NULL; +} + + +int main() { + struct args* args = malloc(sizeof(struct args)); + int pid = 12; + Memory* mem = memory_init(pid); + + args->mem = mem; + args->pid = pid; + args->count = 20; + args->size = 4; + + pthread_t tid[N]; + + for (int i=0; i < N; i++) { + pthread_create(&(tid[i]), NULL, &thread, (void*)args); + } + + for (int i=0; i < N; i++) { + pthread_join(tid[i], NULL); + } + return 0; +} diff --git a/TP/TP2/rendu/vmap.c b/TP/TP2/rendu/vmap.c index 88b42bf..89d362e 100644 --- a/TP/TP2/rendu/vmap.c +++ b/TP/TP2/rendu/vmap.c @@ -103,99 +103,110 @@ void* my_malloc(Memory* mem, int size, int pid) { } VMap* vmap = memory_get(mem, pid); - // 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++; + pthread_mutex_lock(&vmap->lock); + // 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; + pthread_mutex_unlock(&vmap->lock); + return ptr; + } + current = current->next; } - current = current->next; - } - PageMapInfo* page = vmap_new_page(vmap); + PageMapInfo* page = vmap_new_page(vmap); - void* ptr = (void*)((uint64_t)page->start+page->cursor); - page->cursor += size; - page->nb_allocs++; + void* ptr = (void*)((uint64_t)page->start+page->cursor); + page->cursor += size; + page->nb_allocs++; + pthread_mutex_unlock(&vmap->lock); return ptr; } void my_free(Memory* mem, void* ptr, int pid) { VMap* vmap = memory_get(mem, pid); - PageMapInfo* page = vmap_get_page(vmap, ptr); + pthread_mutex_lock(&vmap->lock); + PageMapInfo* page = vmap_get_page(vmap, ptr); - if (!page) { - fprintf(stderr, "my_free: Double free or memory corrupted\n"); - exit(1); - } + 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); - } + page->nb_allocs--; + if (page->nb_allocs == 0) { + vmap_free_page(vmap, page); + } + pthread_mutex_unlock(&vmap->lock); } void my_copy(Memory* mem, void* src, void* dst, int size, int pid) { VMap* vmap = memory_get(mem, pid); - PageMapInfo* page_map_src = vmap_get_page(vmap, src); - PageMapInfo* page_map_dst = vmap_get_page(vmap, dst); + pthread_mutex_lock(&vmap->lock); + PageMapInfo* page_map_src = vmap_get_page(vmap, src); + PageMapInfo* page_map_dst = vmap_get_page(vmap, dst); - if (!page_map_src || !page_map_dst) { - fprintf(stderr, "my_copy: segmentation fault\n"); // Trying to access bad page - exit(1); - } + if (!page_map_src || !page_map_dst) { + fprintf(stderr, "my_copy: segmentation fault\n"); // Trying to access bad page + exit(1); + } - if (((int64_t)src % PAGE_SIZE) + size >= PAGE_SIZE) { - fprintf(stderr, "my_copy: size not available in this src page\n"); - exit(1); - } + if (((int64_t)src % PAGE_SIZE) + size >= PAGE_SIZE) { + fprintf(stderr, "my_copy: size not available in this src page\n"); + exit(1); + } - if (((int64_t)dst % PAGE_SIZE) + size >= PAGE_SIZE) { - fprintf(stderr, "my_copy: size not available in this dst page\n"); - exit(1); - } + if (((int64_t)dst % PAGE_SIZE) + size >= PAGE_SIZE) { + 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); - } + 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); + PageInfo* page_src = page_lookup(vmap->mmap, page_map_src->key); + PageInfo* page_dst = page_lookup(vmap->mmap, page_map_dst->key); - memcpy(page_src->data+((int64_t)dst % PAGE_SIZE), page_dst->data+((int64_t)src % PAGE_SIZE), size); + memcpy(page_src->data+((int64_t)dst % PAGE_SIZE), page_dst->data+((int64_t)src % PAGE_SIZE), size); + pthread_mutex_unlock(&vmap->lock); } void vmap_copy_to_memory(Memory* mem, void *src, void *dst, int size, int pid) { VMap* vmap = memory_get(mem, pid); - PageMapInfo* page_map = vmap_get_page(vmap, src); - PageInfo* page = page_lookup(vmap->mmap, page_map->key); + pthread_mutex_lock(&vmap->lock); + PageMapInfo* page_map = vmap_get_page(vmap, src); + PageInfo* page = page_lookup(vmap->mmap, page_map->key); - if (!page) { - fprintf(stderr, "vmap_copy_to_memory: page not found\n"); - exit(1); - } - - memcpy(dst, page->data + ((int64_t)src % PAGE_SIZE), size); + if (!page) { + fprintf(stderr, "vmap_copy_to_memory: page not found\n"); + exit(1); + } + + memcpy(dst, page->data + ((int64_t)src % PAGE_SIZE), size); + pthread_mutex_unlock(&vmap->lock); } void vmap_copy_from_memory(Memory* mem, void *src, void *dst, int size, int pid) { VMap* vmap = memory_get(mem, pid); - PageMapInfo* page_map = vmap_get_page(vmap, dst); - PageInfo* page = page_lookup(vmap->mmap, page_map->key); + pthread_mutex_lock(&vmap->lock); + PageMapInfo* page_map = vmap_get_page(vmap, dst); + PageInfo* page = page_lookup(vmap->mmap, page_map->key); - if (!page) { - fprintf(stderr, "vmap_copy_to_memory: page not found\n"); - exit(1); - } - - memcpy(page->data + ((int64_t)dst % PAGE_SIZE), src, size); + if (!page) { + fprintf(stderr, "vmap_copy_to_memory: page not found\n"); + exit(1); + } + + memcpy(page->data + ((int64_t)dst % PAGE_SIZE), src, size); + pthread_mutex_unlock(&vmap->lock); } \ No newline at end of file diff --git a/TP/TP2/rendu/vmap.h b/TP/TP2/rendu/vmap.h index 0ac6dc2..9661e5d 100644 --- a/TP/TP2/rendu/vmap.h +++ b/TP/TP2/rendu/vmap.h @@ -1,12 +1,15 @@ #ifndef DEF_VMAP_H #define DEF_VMAP_H +#include + #include "mmap.h" typedef struct VMap { MMap* mmap; linkedList* pages; - int index; // index of virt memory + pthread_mutex_t lock; + int index; // size already alloc'ed } VMap; typedef struct Memory { // List of VMaps