diff --git a/TD/TD5/sujet.pdf b/TD/TD5/sujet.pdf new file mode 100644 index 0000000..69fa8b1 Binary files /dev/null and b/TD/TD5/sujet.pdf differ diff --git a/TD/TD5/td5_lucas/Makefile b/TD/TD5/td5_lucas/Makefile new file mode 100644 index 0000000..a48e225 --- /dev/null +++ b/TD/TD5/td5_lucas/Makefile @@ -0,0 +1,17 @@ +BUILDDIR := build +SRCDIR := src + +FLAGS = -Wall -Wextra -g -O3 +LD_CXXFLAGS = + +SRC := $(wildcard $(SRCDIR)/*.c) +OBJ = $(filter-out $(BUILDDIR)/main.o, $(SRC:$(SRCDIR)/%.c=$(BUILDDIR)/%.o)) + + + +$(BUILDDIR)/main: $(SRCDIR)/main.c $(OBJ) + $(CC) $^ -o $@ $(FLAGS) $(LD_FLAGS) + + +$(BUILDDIR)/%.o: $(SRCDIR)/%.c $(SRCDIR)/include/%.h + $(CC) -c $< -o $@ $(FLAGS) diff --git a/TD/TD5/td5_lucas/bash.md b/TD/TD5/td5_lucas/bash.md new file mode 100644 index 0000000..2149ba0 --- /dev/null +++ b/TD/TD5/td5_lucas/bash.md @@ -0,0 +1,11 @@ +# Top + +Processus: Hyprland +Virt: 1209212 +%Mem: 0,6 + +# /proc/meminfo + +MemTotal: 16160648 kB +MemAvailable: 14705168 kB +PageTables: 12680 kB diff --git a/TD/TD5/td5_lucas/src/alloc.c b/TD/TD5/td5_lucas/src/alloc.c new file mode 100644 index 0000000..421a2a3 --- /dev/null +++ b/TD/TD5/td5_lucas/src/alloc.c @@ -0,0 +1,128 @@ +#include +#include + +#include "include/alloc.h" + + +linked_list* init_linked_list(void* start, size_t page_size, int page_count, int start_key) { + if (page_count == 0) + return NULL; + + linked_list* list = malloc(sizeof(linked_list)); + list->page = malloc(sizeof(PageInfo)); + + list->page->key = start_key; + list->page->start = start; + + list->next = init_linked_list(start+page_size, page_size, page_count-1, start_key+1); + + return list; +} + +int size(linked_list* l) { + if (!l) + return 0; + + return 1+size(l->next); +} + +mmap* init() { + mmap* m = malloc(sizeof(mmap)); + + m->memory = (void*)malloc(PAGE_SIZE*INITIAL_PAGE_COUNT); + m->page_count = 0; + m->swap = fopen(SWAP_FILE, "w+"); + m->alloc = NULL; + m->free = NULL; + + return m; +} + +PageInfo* page_alloc(mmap* mmap) { + if (mmap->page_count == INITIAL_PAGE_COUNT) + FAIL("Plus d'espace disponible"); + + PageInfo* p = malloc(sizeof(PageInfo)); + p->key = mmap->page_count; + p->start = mmap->memory+p->key*PAGE_SIZE; + mmap->page_count++; + + for (int i=0; i < PAGE_SIZE; i++) { + *(char*)(p->start+i) = '\0'; + } + + linked_list* l = malloc(sizeof(linked_list)); + l->next = mmap->alloc; + l->page = p; + + mmap->alloc = l; + return p; +} + +PageInfo* page_free(mmap* mmap) { + if (!mmap->free) { + FAIL("No more pages available\n"); + } + linked_list* l = mmap->free; + mmap->free = mmap->free->next; + l->next = mmap->alloc; + mmap->alloc = l; + + return l->page; +} + +int check_page_free_list(mmap* mmap) { + return size(mmap->free); +} + +int check_page_alloc(mmap* mmap) { + return size(mmap->alloc); +} + +void move_to_swap(mmap* mmap, int id_page) { + linked_list* prev = NULL; + linked_list* current = mmap->alloc; + while (current && current->page->key != id_page) { + prev = current; + current = current->next; + } + if (!current) { + FAIL("Page not found\n"); + } + + if (prev) { + prev->next = current->next; + } else { + mmap->alloc = current->next; + } + + current->next = mmap->free; + mmap->free = current; + + fseek(mmap->swap, 0, SEEK_END); + fwrite(&id_page, sizeof(int), 1, mmap->swap); + fwrite(current->page->start, PAGE_SIZE, 1, mmap->swap); + free(current); +} + +PageInfo* read_from_swap(mmap* mmap, int id_page) { + int key = -1; + fseek(mmap->swap, 0, SEEK_SET); + while (fread(&key, sizeof(int), 1, mmap->swap) && key != id_page) { + fseek(mmap->swap, PAGE_SIZE, SEEK_CUR); + } + if (key != id_page) + FAIL("Page not found\n"); + + PageInfo* p = malloc(sizeof(PageInfo)); + p->key = id_page; + p->start = malloc(PAGE_SIZE); + fread(p->start, PAGE_SIZE, 1, mmap->swap); + + linked_list* l = malloc(sizeof(linked_list)); + l->next = mmap->alloc; + l->page = p; + + mmap->alloc = l; + return p; +} diff --git a/TD/TD5/td5_lucas/src/include/alloc.h b/TD/TD5/td5_lucas/src/include/alloc.h new file mode 100644 index 0000000..ecd3916 --- /dev/null +++ b/TD/TD5/td5_lucas/src/include/alloc.h @@ -0,0 +1,52 @@ +#ifndef DEF_ALLOC_H +#define DEF_ALLOC_H +#include + +#define FAIL(s) { fprintf(stderr, (s)); exit(EXIT_FAILURE); } + +#define SWAP_FILE "/tmp/archisys.swap" +#define INITIAL_PAGE_COUNT 80 +#define PAGE_SIZE 64 + +typedef struct PageInfo { + void* start; + int key; +} PageInfo; + +typedef struct linked_list { + PageInfo* page; + struct linked_list* next; +} linked_list; + +typedef struct mmap { + linked_list* free; + linked_list* alloc; + void* memory; + FILE* swap; + int page_count; +} mmap; + +/* cette fonction initialise l'allocateur de mémoire. Elle génère les structures de données nécessaires pour gérer la +mémoire. De plus, elle alloue un "grand" espace mémoire que vous utiliserez pour émuler votre mémoire physique (évidemment, vous ne +travaillerez pas avec votre vraie mémoire physique */ +mmap* init(); + +/* cette fonction alloue une page physique. NOTE : la fonction doit remplir la totalité +de la page physique retournée avec des octets '\0'. */ +PageInfo* page_alloc(mmap* mmap); + +/* renvoie une page dans la liste des pages libres. */ +PageInfo* page_free(mmap* mmap); + +/* renvoie le nombre de pages libres */ +int check_page_free_list(mmap* mmap); + +int check_page_alloc(mmap* mmap); + +/* déplace une page vers votre swap émulé. Le swap doit être un fichier appelé (vous l'avez deviné) swap. Vous pouvez stocker ce fichier n'importe où dans votre système de fichiers (je suggère de le stocker dans le dossier /tmp/). */ +void move_to_swap(mmap* mmap, int id_page); + +/* Lit une page du swap et la supprime. */ +PageInfo* read_from_swap(mmap* mmap, int id_page); + +#endif diff --git a/TD/TD5/td5_lucas/src/main.c b/TD/TD5/td5_lucas/src/main.c new file mode 100644 index 0000000..d098de1 --- /dev/null +++ b/TD/TD5/td5_lucas/src/main.c @@ -0,0 +1,30 @@ +#include + +#include "include/alloc.h" + + +int main() { + mmap* m = init(); + + page_alloc(m); + page_alloc(m); + + PageInfo* p = page_alloc(m); + + for (int i=0; i < PAGE_SIZE; i++) { + *(char*)(p->start+i) = (i+20)%200; + } + + int key = p->key; + move_to_swap(m, key); + + for (int i=0; i < PAGE_SIZE; i++) { + *(char*)(p->start+i) = 0; + } + + p = read_from_swap(m, key); + + for (int i=0; i < PAGE_SIZE; i++) { + assert((i+20)%200 == *(char*)(p->start+i)); + } +}