Ajout TD5: Loin d'être parfait
This commit is contained in:
parent
c66710c817
commit
cec685ff86
BIN
TD/TD5/sujet.pdf
Normal file
BIN
TD/TD5/sujet.pdf
Normal file
Binary file not shown.
17
TD/TD5/td5_lucas/Makefile
Normal file
17
TD/TD5/td5_lucas/Makefile
Normal 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
11
TD/TD5/td5_lucas/bash.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Top
|
||||
|
||||
Processus: Hyprland
|
||||
Virt: 1209212
|
||||
%Mem: 0,6
|
||||
|
||||
# /proc/meminfo
|
||||
|
||||
MemTotal: 16160648 kB
|
||||
MemAvailable: 14705168 kB
|
||||
PageTables: 12680 kB
|
128
TD/TD5/td5_lucas/src/alloc.c
Normal file
128
TD/TD5/td5_lucas/src/alloc.c
Normal 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;
|
||||
}
|
52
TD/TD5/td5_lucas/src/include/alloc.h
Normal file
52
TD/TD5/td5_lucas/src/include/alloc.h
Normal 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
|
30
TD/TD5/td5_lucas/src/main.c
Normal file
30
TD/TD5/td5_lucas/src/main.c
Normal 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));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user