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 テ trouver une zone mテゥmoire adテゥquate
- 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 immテediatemment a droite est libre
- else{
- struct fb* fb_new = (void *)fb_current + sizeof(int) + size;
- fb_new->size = fb_current->size - (size + sizeof(int));
- fb_new->next = (void *)fb_current->next;
- if(voisin_gauche != NULL && (void*)voisin_gauche->next == (void*)fb_current){
- voisin_gauche->next = (void *)fb_new;
- }
- else{
- *(struct fb**)mem = (void *)fb_new;
- }
- }
- *(int*)((void*)fb_current) = size;
- //printf("Prochain bloc libre en %p",*(struct fb **)mem);
- return (void *) fb_current + sizeof(int);
- /*
- //Si le bloc immテゥdiatemment a droite est occupテゥ
- if(size == fb_current->size-sizeof(int)){
- if(voisin_gauche != NULL){
- voisin_gauche->next = (void *)fb_current->next;
- }
- else{
- *(struct fb**)mem = (void *)fb_current->next;
- }
- }
- //Si le bloc immテediatemment a droite est libre
- else{
- struct fb* fb_new = (void *)fb_current + sizeof(int) + size;
- fb_new->size = fb_current->size - (size + sizeof(int));
- fb_new->next = (void *)fb_current->next;
- if(voisin_gauche != NULL){
- voisin_gauche->next = (void *)fb_new;
- }
- else{
- *(struct fb**)mem = (void *)fb_new;
- }
- }
- *(int*)((void*)fb_current) = size;
- //printf("Prochain bloc libre en %p",*(struct fb **)mem);
- return (void *) fb_current + sizeof(int);*/
- }
- else{
- return NULL;
- }
- /* Code de Antoine : ne marche pas dans tout les cas
- if (fb_current != NULL){
- struct fb* fb_next = fb_current->next;
- struct fb* fb_before = *(struct fb**) mem;
- if (fb_before != fb_current){
- while (fb_before->next != fb_current){
- fb_before = fb_before->next;
- }
- }
- //Calcul de la taille restante du bloc テ allouer
- size_t rest_size = fb_current->size - size + sizeof(int);
- //Cas 1 = Plus de place pour allouer une zone libre
- if (rest_size < sizeof(struct fb)){
- if (fb_before == fb_current){
- *(struct fb**) mem = fb_next;
- } else {
- fb_before->next = fb_next;
- }
- *(int*)fb_current = fb_current->size - sizeof(int);
- ret = (void *) fb_current + sizeof(int);
- //Cas 2 = Crテゥation d'une nouvelle zone libre
- }else {
- struct fb* fb_new = (void *)fb_current + sizeof(int) + size;
- fb_new->size = fb_current->size - (size + sizeof(int));
- fb_new->next = fb_current->next;
- if (fb_before == fb_current){
- printf("On devrait passer la\n");
- *(struct fb**) mem = fb_new;
- } else {
- fb_before->next = fb_new;
- }
- *(int*) fb_current = size;
- ret = (void *)fb_current + sizeof(int);
- printf("On passe + %p + %d\n",ret,sizeof(int));
- }
- }else{
- return NULL;
- }
- printf("Valeur de current = %d\n",*(int*)fb_current);
- return ret;
- */}
- 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 libテゥrer 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;
- }
- /* Tentative foirテゥe de free, ca part dans tout les sens : on met a plat et on recommence !
- //Si le bloc a liberer doit devenir le premier bloc disponible
- if((void *)voisin_gauche == NULL){
- printf("Passe lalalla\n");
- //Si il n'y a plus aucun bloc libre a droite
- if((void *)voisin_droit == NULL){
- printf("PPPPPPPP\n");
- voisin_gauche = *(struct fb**)mem;
- // Cas oテケ la zone a gauche est libre et qu'il n'y a plus de voisin a droite
- if(voisin_gauche != NULL &&((void*)voisin_gauche)+voisin_gauche->size == zone-sizeof(int)){
- voisin_gauche->size+= taille_zone+sizeof(int);
- voisin_gauche->next=voisin_gauche->next;
- printf("C'est gagnテゥ\n");
- }
- //Cas oテケ la zone a gauche est libre et qu'il n'y a plus de voisin a droite
- else if(voisin_gauche != NULL &&((void*)voisin_gauche)+voisin_gauche->size != zone-sizeof(int)&& (void*)(*(struct fb**)mem) != (void*)mem){
- struct fb* fb_new = ptr_taille_zone;
- fb_new->size = taille_zone + sizeof(int);
- fb_new->next = (void *)voisin_droit;
- voisin_gauche->next = (void*)fb_new;
- printf("fusion\n");
- }
- //Cas oテケ il faut crテゥer un nouveau descripteur car pas de zone a gauche
- else{
- printf("affectation\n");
- struct fb* fb_new = ptr_taille_zone;
- fb_new->size = taille_zone + sizeof(int);
- fb_new->next = (void *)voisin_droit;
- *(struct fb**) get_memory_adr() = (void *) fb_new;
- }
- }
- //Si la zone immediatemment a droite est libre : fusionner
- else if(zone+taille_zone == (void *)voisin_droit){
- struct fb* is_first = *(struct fb**)mem ;
- if((void*)is_first+is_first->size == ptr_taille_zone){
- is_first->size += taille_zone+sizeof(int)+voisin_droit->size;
- is_first->next = (void *)voisin_droit->next;
- }
- else{
- struct fb* fb_new = ptr_taille_zone;
- fb_new->size = taille_zone + voisin_droit->size + sizeof(int);
- fb_new->next = (void *)voisin_droit->next;
- *(struct fb**)mem = (void *) fb_new;
- }
- printf("Ou lテ ?\n");
- }
- //Si la zone immediatemment a droite est occupテゥe
- else{
- struct fb* is_first = *(struct fb**)mem ;
- if((void*)is_first+is_first->size == ptr_taille_zone){
- is_first->size += taille_zone+sizeof(int);
- is_first->next = (void *)voisin_droit->next;
- }
- else{
- struct fb* fb_new = ptr_taille_zone;
- fb_new->size = taille_zone + sizeof(int);
- fb_new->next = (void *)voisin_droit;
- printf("On passelalal\n");
- is_first->next = (void *) fb_new;
- }
- }
- }
- //Si le bloc que l'on souhaite libテゥrer a un predecesseur libre
- else{
- //Si plus de voisin a droite, impossible a declencher ????
- if((void*)voisin_droit == NULL){
- struct fb* fb_new = ptr_taille_zone;
- fb_new->size = taille_zone + sizeof(int);
- fb_new->next = NULL;
- voisin_gauche->next = fb_new;
- }
- //Si le voisin a droite est libre, fusionner voisin gauche et droite
- else if(zone+taille_zone == (void *)voisin_droit && (void*)voisin_gauche+voisin_gauche->size==ptr_taille_zone){
- voisin_gauche->size += taille_zone + voisin_droit->size + sizeof(int);
- voisin_gauche->next = voisin_droit->next;
- }
- //Si le voisin テ droite est occupテゥ
- else{
- //SI le voisin de gauche est occupテゥ, crテゥer un fb et que celui テ droite est libre
- if((void *)voisin_gauche+voisin_gauche->size != ptr_taille_zone){
- struct fb* fb_new = ptr_taille_zone;
- fb_new->size = taille_zone + sizeof(int)+voisin_droit->size;
- fb_new->next = (void *)voisin_droit->next;
- voisin_gauche->next = (void*) fb_new;
- }
- //Si le voisin de gauche est libre, fusionner
- else{
- voisin_gauche->size += taille_zone + sizeof(int);
- }
- }
- }*/
- }
- /*
- Code de free de Antoine : ne marche pas
- printf("Adresse de la zone テ libテゥrer : %p\n",zone);
- struct fb* fb = *(struct fb**) get_memory_adr();
- void* zone_begin = zone - sizeof(int);
- size_t size_zone = *(int*) zone_begin;
- printf("Taille de la zone テ libテゥrer : %d\n",size_zone);
- while ((fb + fb->size) < (struct fb*)zone_begin){
- fb = fb->next;
- }
- //Zone libre prテゥcテゥdente adjacente テ la zone テ libテゥrer
- if ((fb + fb->size) == zone_begin){
- //Zone suivante
- if (fb + fb->size + sizeof(int) + size_zone == fb->next){
- fb->size = fb->size + sizeof(int) + size_zone + fb->next->size;
- fb->next = fb->next->next;
- } else {
- fb->size = fb->size + size_zone + sizeof(int);
- }
- } else {
- //A faire crテゥer fb et vテゥrifier si zone libre suivante adjacente
- struct fb* fb_new = (struct fb*)zone_begin;
- if ((struct fb*)zone_begin + sizeof(int) + size_zone == fb){
- fb_new->size = sizeof(int) + size_zone + fb->size;
- fb_new->next = fb->next;
- } else {
- fb_new->size = sizeof(int) + size_zone;
- fb_new->next = fb;
- }
- }*/
- size_t mem_get_size(void * zone){
- return *(int*) zone - sizeof(int);
- }
- /* Itテゥrateur 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