Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "mem.h"
- #include "common.h"
- #include <stdio.h>
- void mem_init(char* mem, size_t taille){
- *(struct fb**) mem = mem + sizeof(struct fb*);
- struct fb* first_free_zone = *(struct fb**) mem ;
- first_free_zone->size = taille-sizeof(struct fb*);
- first_free_zone->next = NULL;
- printf("Taille : %d , Adresse de la premiere zone libre: %p\n",first_free_zone->size,first_free_zone);
- }
- //retourne l'adresse de la prochaine zone inoccupテee, retourne NULL si il n'y en a pas
- struct fb* trouver_voisin_droite(void * zone){
- struct fb * parcours = *((struct fb**) get_memory_adr());
- while(parcours != NULL && (void *) parcours + parcours->size < zone){
- parcours = parcours->next;
- }
- return parcours;
- };
- //Renvoi l'adresse de la zone libre la plus proche de la zone "zone" a liberer.
- struct fb* trouver_voisin_gauche(void * zone){
- struct fb * parcours = *((struct fb**) get_memory_adr());
- struct fb * prec = parcours;
- while(parcours != NULL && (void *) parcours + parcours->size <= zone-sizeof(int)){
- prec = parcours;
- parcours = parcours->next;
- }
- return prec;
- };
- void* mem_alloc(size_t size){
- void* mem = get_memory_adr();
- struct fb* fb_current = mem_fit_first(*(struct fb**) mem, size);
- printf("On cherche a allouer a l'adresse %p\n", fb_current);
- //Si on a rテゥussi a trouver une zone memoire adequate
- if (fb_current != NULL){
- struct fb * voisin_gauche = trouver_voisin_gauche((void*)fb_current);
- struct fb * voisin_droit = trouver_voisin_droite((void*)fb_current);
- //printf("Mon voisin de droite est : %p \n", (void *) voisin_droit);
- //printf("Mon voisin de gauche est : %p \n", (void *) voisin_gauche);
- //Modification de la taille de la zone si nテゥcessaire : si on ne peut pas allouer de fb dans l'espace restant
- if(fb_current->size - size - sizeof(int) <= sizeof(struct fb)){
- size = fb_current->size - sizeof(int);
- }
- //Si le bloc à droite est occupé
- if(size == fb_current->size-sizeof(int)){
- if(voisin_gauche != NULL && (void*)voisin_gauche->next == (void*)fb_current){
- voisin_gauche->next = (void *)fb_current->next;
- }
- else{
- *(struct fb**)mem = (void *)fb_current->next;
- }
- }
- //Si le bloc immediatemment a droite est libre
- else{
- struct fb* suivant = (void*)fb_current->next;
- struct fb* fb_new = (void *)fb_current + sizeof(int) + size;
- if(voisin_gauche != NULL && (void*)voisin_gauche->next == (void*)fb_current){
- voisin_gauche->next = (void *)fb_new;
- }
- else{
- *(struct fb**)mem = (void *)fb_new;
- }
- fb_new->size = fb_current->size - (size + sizeof(int));
- fb_new->next = (void*)suivant;
- }
- *(int*)((void*)fb_current) = size;
- //printf("Prochain bloc libre en %p",*(struct fb **)mem);
- return (void *) fb_current + sizeof(int);
- }
- else{
- return NULL;
- }
- }
- void affiche_chainage(){
- struct fb* tete = *(struct fb**)get_memory_adr();
- while(tete != NULL){
- printf(" %p => ",(void*)tete);
- tete = tete->next;
- }
- printf("\n");
- }
- void mem_free(void* zone){
- if(!est_liberable(zone)){
- printf("L'adresse %p n'est pas une adresse de debut de zone allouee\n",zone);
- return;
- }
- void* mem = get_memory_adr();
- //Adresse oテケ est stockee la valeur de la zone a liberer
- void * ptr_taille_zone = zone - sizeof(int);
- size_t taille_zone = *(int*) ptr_taille_zone;
- size_t nouvelle_taille = taille_zone + sizeof(int);
- struct fb * voisin_gauche = trouver_voisin_gauche(zone);
- struct fb * voisin_droit = trouver_voisin_droite(zone);
- //printf("Mon voisin de droite est : %p \n", (void *) voisin_droit);
- //printf("Mon voisin de gauche est : %p \n", (void *) voisin_gauche);
- //Si il y a un voisin a gauche qui n'est pas le premier
- if(voisin_gauche != NULL && (void*)voisin_gauche+voisin_gauche->size == ptr_taille_zone){
- //Si il y a un voisin a droite, fusionner avec lui
- nouvelle_taille += voisin_gauche->size;
- //Si la zone droite adjacente est libre : fusionner
- if((void *) voisin_droit == zone + taille_zone){
- nouvelle_taille+= voisin_droit->size;
- voisin_gauche->next = (void*)voisin_droit->next;
- }
- else{
- voisin_gauche->next = (void*)voisin_droit;
- }
- voisin_gauche->size = nouvelle_taille;
- }
- //Si on doit liberer le premier bloc disponible
- else if(voisin_gauche == voisin_droit){
- struct fb* fb_new = ptr_taille_zone;
- //Si la zone adjacente droite est libre : fusionner
- if((void *) voisin_droit == zone + taille_zone){
- nouvelle_taille+= voisin_droit->size;
- fb_new->next = voisin_droit->next;
- }
- else{
- fb_new->next = voisin_droit;
- }
- fb_new->size = nouvelle_taille;
- *(struct fb**) get_memory_adr() = (void *) fb_new;
- }
- //si il n'y a pas de voisin a gauche
- else{
- struct fb* fb_new = ptr_taille_zone;
- //si la zone adjacente droite est libre : fusionner
- if((void *) voisin_droit == zone + taille_zone){
- nouvelle_taille+= voisin_droit->size;
- fb_new->next = voisin_droit->next;
- }
- else{
- fb_new->next = voisin_droit;
- }
- fb_new->size = nouvelle_taille;
- voisin_gauche->next = fb_new;
- }
- }
- size_t mem_get_size(void * zone){
- return *(int*) zone - sizeof(int);
- }
- /* Iterateur sur le contenu de l'allocateur */
- void mem_show(void (*print)(void * zone, size_t size, int free)){
- affiche_chainage();
- void* mem = get_memory_adr();
- struct fb* fb = *(struct fb**) mem;
- void* addr = mem + sizeof(struct fb*);
- size_t count = sizeof(struct fb**);
- while(count < get_memory_size()){
- if(addr == (void *)fb){
- print(addr, fb->size, 1);
- addr = addr + fb->size;
- count += fb->size;
- fb = fb->next;
- } else {
- print(addr, *(int*)addr, 0);
- count += *(int*)addr + sizeof(int);
- addr += *(int*)addr + sizeof(int);
- }
- }
- }
- int est_liberable(void * zone){
- void* mem = get_memory_adr();
- struct fb* fb = *(struct fb**) mem;
- void* addr = mem + sizeof(struct fb*);
- size_t count = sizeof(struct fb**);
- int retour = 0;
- while(count < get_memory_size() && retour == 0){
- if(addr == (void *)fb){
- addr = addr + fb->size;
- count += fb->size;
- fb = fb->next;
- } else {
- if(addr+sizeof(int) == zone)
- retour =1;
- count += *(int*)addr + sizeof(int);
- addr += *(int*)addr + sizeof(int);
- }
- }
- return retour;
- }
- /* Choix de la strategie et strategies usuelles */
- typedef struct fb* (mem_fit_function_t)(struct fb *, size_t);
- void mem_fit(mem_fit_function_t*);
- struct fb* mem_fit_first(struct fb* list, size_t size){
- while(list != NULL && list->size < size+sizeof(int)){
- list = list->next;
- }
- printf("%p\n",list);
- return list == NULL ? NULL : list;
- }
- /* Si vous avez le temps */
- struct fb* mem_fit_best(struct fb* list, size_t size);
- struct fb* mem_fit_worst(struct fb* list, size_t size);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement