Ajout TD5: Loin d'être parfait

This commit is contained in:
augustin64 2024-03-09 18:59:49 +01:00
parent c66710c817
commit cec685ff86
6 changed files with 238 additions and 0 deletions

BIN
TD/TD5/sujet.pdf Normal file

Binary file not shown.

17
TD/TD5/td5_lucas/Makefile Normal file
View File

@ -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)

11
TD/TD5/td5_lucas/bash.md Normal file
View File

@ -0,0 +1,11 @@
# Top
Processus: Hyprland
Virt: 1209212
%Mem: 0,6
# /proc/meminfo
MemTotal: 16160648 kB
MemAvailable: 14705168 kB
PageTables: 12680 kB

View File

@ -0,0 +1,128 @@
#include <stdio.h>
#include <stdlib.h>
#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;
}

View File

@ -0,0 +1,52 @@
#ifndef DEF_ALLOC_H
#define DEF_ALLOC_H
#include <stdio.h>
#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

View File

@ -0,0 +1,30 @@
#include <assert.h>
#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));
}
}