From 1eb1d0d95e35ae900684fda158ebe8ebd2021a72 Mon Sep 17 00:00:00 2001 From: Arkitu <85173315+Arkitu@users.noreply.github.com> Date: Sat, 4 Oct 2025 20:08:02 +0200 Subject: [PATCH] save --- dm_alloc/allocateur_blocs_taille_fixe.c | 42 ------ dm_alloc/allocateur_chainage.c | 188 ++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 42 deletions(-) create mode 100644 dm_alloc/allocateur_chainage.c diff --git a/dm_alloc/allocateur_blocs_taille_fixe.c b/dm_alloc/allocateur_blocs_taille_fixe.c index 9d13d45..4ef5b0e 100644 --- a/dm_alloc/allocateur_blocs_taille_fixe.c +++ b/dm_alloc/allocateur_blocs_taille_fixe.c @@ -1,45 +1,3 @@ -// #include -// #include -// #include - -// const uint64_t HEAP_SIZE = 32; -// const uint64_t BLOCK_SIZE = 8; -// uint64_t heap[HEAP_SIZE]; - -// void init_heap() { -// heap[0] = 2; -// for (uint64_t i = 1; i + BLOCK_SIZE <= HEAP_SIZE; i += BLOCK_SIZE) { -// heap[i] = 0; -// } -// } - -// bool is_free(uint64_t i) { return !heap[i - 1]; } -// void set_free(uint64_t i) { heap[i - 1] = 0; } -// void set_used(uint64_t i) { heap[i - 1] = 1; } - -// uint64_t *malloc_ui(uint64_t size) { -// for (uint64_t i = 2; i - 1 + BLOCK_SIZE <= HEAP_SIZE; i += BLOCK_SIZE) { -// if (is_free(i)) { -// set_used(i); -// if (i > heap[0]) { -// heap[0] = i; -// } -// return &heap[i]; -// } -// } -// return NULL; -// } - -// void free_ui(uint64_t *p) { -// uint64_t i = p - heap; -// heap[i - 1] = 0; -// if (i == heap[0]) { -// while (is_free(heap[0]) && heap[0] > 2) { -// heap[0] -= BLOCK_SIZE; -// } -// } -// } - #include #include #include diff --git a/dm_alloc/allocateur_chainage.c b/dm_alloc/allocateur_chainage.c new file mode 100644 index 0000000..5037a81 --- /dev/null +++ b/dm_alloc/allocateur_chainage.c @@ -0,0 +1,188 @@ +#include +#include +#include +#include +#include + +// Comme uint64_t est un peu pénible à taper, on utilise +// un typedef : +typedef uint64_t ui; + +#define HEAP_SIZE 32 + +ui heap[HEAP_SIZE]; + +// Cette fonction convertit un pointeur (qui doit être issu de +// malloc_ui) en un indice dans le tableau heap. +// Vous en aurez besoin pour écrire les différentes versions +// de free_ui (juste un appel au début, ensuite on ne manipule plus +// que des indices), mais il est complètement normal de ne pas +// comprendre comment elle fonctionne : c'est de l'arithmétique des +// pointeurs, qui est hors programme. +ui heap_index(ui *p) { return p - heap; } + +// Cette fonction initialise le tas à une valeur particulière, que +// vous avez peu de chance d'utiliser par hasard. Cela nous +// permettra en pratique de repérer les cases dont la valeur n'a +// jamais été modifiée quand on affiche le contenu du tas. +// Elle est destinée à être appelée une unique fois, tout au début +// de l'exécution du programme. +void pre_initialize_heap(void) { + for (ui i = 0; i < HEAP_SIZE; i++) { + heap[i] = 0xFFFFFFFF; + } +} + +// La fonction suivante affiche le contenu du tas. Les cases +// identifiées comme n'ayant jamais été modifiées sont affichées +// de manière particulière. +void print_heap(void) { + for (ui i = 0; i < HEAP_SIZE; i++) { + ui x = heap[i]; + if (x == 0xFFFFFFFF) { + printf("... "); + } else { + printf("%3" PRIu64 " ", x); + } + } + printf("\n"); +} + +void set_memory(ui *p, ui size, ui value) { + for (ui i = 0; i < size; i++) { + p[i] = value; + } +} + +const uint64_t prologue = 3; + +void add_begin_chain(uint64_t i) { + heap[i + 1] = heap[1]; + heap[i] = 1; + heap[heap[1]] = i; + heap[1] = i; +} + +void remove_from_chain(uint64_t i) { + heap[heap[i] + 1] = heap[1]; + heap[heap[i + 1]] = heap[0]; +} + +bool is_free(uint64_t i) { return heap[i - 1] % 2 == 0; } + +uint64_t read_size(uint64_t i) { return heap[i - 1] - (heap[i - 1] & 0b1); } + +void set_free(uint64_t i, uint64_t size) { + size += ((size & 0b1) << 1); + heap[i - 1] = size - (size & 0b1); + heap[i + size] = size - (size & 0b1); +} + +void set_used(uint64_t i, uint64_t size) { + size += ((size & 0b1) << 1); + heap[i - 1] = size | 0b1; + heap[i + size] = size | 0b1; +} + +// À ne pas appeler sur l'épilogue +uint64_t next(uint64_t i) { return i + read_size(i) + 2; } + +// À ne pas appeler sur le prologue +uint64_t previous(uint64_t i) { + return i - (heap[i - 2] - (heap[i - 2] % 2)) - 2; +} + +void init_heap(void) { + heap[0] = 5; + heap[1] = 0; + heap[2] = 1; + heap[3] = 1; + heap[4] = 1; + heap[5] = 1; +} + +// Returns the first sufficiently large free block, +// or 0 if no such block exists. +uint64_t search_free_list(uint64_t size) { + ui i = heap[0]; + while (i != 0) { + if (read_size(i) >= size) { + return i; + } + i = heap[i + 1]; + } + return 0; +} + +uint64_t *malloc_ui64(uint64_t size) { + ui i = search_free_list(size); + if (i != 0) { + remove_from_chain(i); + ui isize = read_size(i); + ui free_size = isize - size; + if (free_size >= 4) { + heap[i + size] = size; + heap[i + size + 1] = free_size - 2; + heap[i + isize] = free_size - 2; + } + } + return NULL; +} + +void free_ui64(uint64_t *p) { + // À implémenter +} + +int main(void) { + pre_initialize_heap(); + + /* // Pour tester, une fois que les fonctions sont implémentées + init_heap(); + print_heap(); + + uint64_t *p1 = malloc_ui64(2); + set_memory(p1, 2, 42); + print_heap(); + uint64_t *p2 = malloc_ui64(2); + set_memory(p2, 2, 52); + print_heap(); + uint64_t *p3 = malloc_ui64(2); + set_memory(p3, 2, 62); + print_heap(); + uint64_t *p4 = malloc_ui64(2); + set_memory(p4, 2, 72); + print_heap(); + uint64_t *p5 = malloc_ui64(1); + set_memory(p5, 1, 82); + print_heap(); + uint64_t *p6 = malloc_ui64(1); + set_memory(p6, 1, 92); + print_heap(); + + printf("\nFin des allocations initiales \n"); + + free_ui64(p1); + print_heap(); + free_ui64(p5); + print_heap(); + free_ui64(p3); + print_heap(); + free_ui64(p6); + print_heap(); + free_ui64(p2); + print_heap(); + + printf("\nAllocation d'un bloc de taille 10, initialisé à 69.\n"); + uint64_t *p7 = malloc_ui64(10); + set_memory(p7, 10, 69); + print_heap(); + + printf("\n Libération de ce bloc, puis allocation de taille 8.\n"); + free_ui64(p7); + p7 = malloc_ui64(8); + set_memory(p7, 8, 99); + print_heap(); + */ + + return EXIT_SUCCESS; +}