All pastes #2001580 Raw Edit

Mine

public c v1 · immutable
#2001580 ·published 2010-11-25 01:34 UTC
rendered paste body
#include "mem.h"#include <stdio.h>#include <stdlib.h>typedef struct fb{	size_t taille;	struct fb *next;}fb_t;typedef struct ab{	size_t taille;}ab_t;static mem_fit_function_t *fonctionRecherche;static fb_t *tete;static char *memory;static size_t tailleMemoire;void mem_init(char *mem, size_t taille){	fb_t *nouveauBloc;	memory = mem;	tailleMemoire = taille;	nouveauBloc = (fb_t*) memory;	nouveauBloc->taille = tailleMemoire;	nouveauBloc->next = NULL;	tete = nouveauBloc;	fonctionRecherche = mem_fit_first;}void mem_show(void (*print)(void *, size_t, int free)){	void* courantMem = (void*) memory;	fb_t *courantFb = tete;	ab_t *ab;	size_t tailleBlocCourant;	while((char*)courantMem < memory + tailleMemoire)	{		while((void*)courantFb != (void*)courantMem && (char*)courantMem < memory + tailleMemoire)		{			ab = (ab_t*)courantMem;			tailleBlocCourant = ab->taille;			print(courantMem, tailleBlocCourant, 0);			courantMem = (char*)courantMem + tailleBlocCourant;		}		if(courantFb)		{			tailleBlocCourant = courantFb->taille;			print(courantMem, tailleBlocCourant, 1);			courantFb = courantFb->next;			courantMem = (char*)courantMem + tailleBlocCourant;		}	}		}/*Post-Cond :prevRet pointe sur un pointeur le bloc prcdant celui renvoy.  * Si le bloc renvoy est le premier, prevRet pointe sur un pointeur qui vaut nul */fb_t *mem_fit_first(fb_t *fb, size_t taille, fb_t** prevRet){	fb_t *courant=fb, *prev=NULL;	while(courant)	{		if(courant->taille >= taille)		{			*prevRet = prev;			return courant;		}		prev = courant;		courant = courant->next;	}	return NULL;}fb_t *mem_fit_best(fb_t *fb, size_t taille, fb_t** prevRet){	fb_t *prevBest, *fbBest, *prev, *courant;	int residuMin, residuCourant;	prev = NULL;	courant = fb;	prevBest = NULL;	fbBest = NULL;	residuMin = tailleMemoire;	while(courant)	{		residuCourant = courant->taille - taille;		if(residuCourant < residuMin)		{			residuMin = residuCourant;			prevBest = prev;			fbBest = courant;		}		prev = courant;		courant = courant->next;	}	*prevRet = prevBest;	return fbBest;}fb_t *mem_fit_worst(fb_t *fb, size_t taille, fb_t** prevRet){	fb_t *prevBest, *fbBest, *prev, *courant;	int residuMax, residuCourant;	prev = NULL;	courant = fb;	prevBest = NULL;	fbBest = NULL;	residuMax = 0;	while(courant)	{		residuCourant = courant->taille - taille;		if(residuCourant > residuMax)		{			residuMax = residuCourant;			prevBest = prev;			fbBest = courant;		}		prev = courant;		courant = courant->next;	}	*prevRet = prevBest;	return fbBest;}void *mem_alloc(size_t tailleAlloc){	fb_t *blocPrev, *blocSuiv;	fb_t *blocUtilise;//descripteur du bloc libre avant allocation	ab_t *blocAlloue;//descripteur du bloc  allouer 	size_t tailleAlignee;	size_t tailleLibre;	//on verifie que la taille demand + le descripteur de bloc allou soit au moins	//gale a la taille d'un descripteur de bloc libre de faon a pouvoir liberer ce bloc		if(tailleAlloc + sizeof(ab_t) < sizeof(fb_t))	{		tailleAlloc = sizeof(fb_t);	}	//recherche d'un bloc	blocUtilise = fonctionRecherche(tete, tailleAlloc+sizeof(ab_t), &blocPrev);	//aucun bloc disponible	if(!blocUtilise)	{		return NULL;	}	blocSuiv = blocUtilise->next;	tailleLibre = blocUtilise->taille;	//alloc	blocAlloue = (ab_t*) blocUtilise;	tailleAlignee = tailleAlloc + (sizeof(size_t) - 1 - 			(tailleAlloc-1) % sizeof(tailleAlloc));	blocAlloue->taille = sizeof(ab_t) + tailleAlignee;	//on positionne le nouveau fb	if(tailleLibre > blocAlloue->taille)	{		int diff = tailleLibre - blocAlloue->taille;		//Si on a pas assez de place aprs allocation pour un descripteur de bloc libre,		//on augmente le bloc allou pour qu'il fasse la taille du bloc libre		if( diff >= sizeof(fb_t))		{			fb_t *nouveau;			nouveau = (fb_t *)(((char*) blocUtilise) + blocAlloue->taille);			nouveau->taille =  diff;			nouveau->next = blocSuiv;			if(blocPrev == NULL)				tete = nouveau;			else				blocPrev->next = nouveau;			printf("cas assez de place : blocUtilise : %p, blocPrev : %p nouveau %p\n", blocUtilise, blocPrev, nouveau);		}		else		{			blocAlloue->taille = tailleLibre;			printf("cas bug : blocUtilise : %p, blocPrev : %p\n", blocUtilise, blocPrev);		}	}	//les blocs libre et align sont de la mme taille, 	//on supprime le bloc libre	if(tailleLibre == blocAlloue->taille)	{		if(blocPrev == NULL)			tete = blocSuiv;		else			blocPrev->next = blocSuiv;	}	if((char*)blocAlloue + sizeof(ab_t) >= memory + tailleMemoire)	{		printf("BOOOOOM\n");				printf("bloc Utilus : %p, bloc Allou %p\n", blocUtilise, blocUtilise);		exit(1);	}	if(blocAlloue->taille > tailleMemoire)	{		printf("BOOOOOM2\n");				printf("bloc Utilus : %p, bloc Allou %p\n", blocUtilise, blocUtilise);		exit(1);	}	return (void *) ( (char*)blocAlloue + sizeof(ab_t));}void mem_free(void* zone) {	struct fb* nouveau;	nouveau = (struct fb*) (((char *) zone) - sizeof(struct ab));	nouveau->taille = ((struct ab*) nouveau)->taille;	if ((tete == NULL) || (((struct fb*) zone) < tete)) {		nouveau->next = tete; //nouvelle tete		tete = nouveau;		if (nouveau->next != NULL) { //fusion			if (nouveau->next == (struct fb*) (((char *) nouveau) + nouveau->taille)) {				nouveau->taille = nouveau->taille + (nouveau->next)->taille;				nouveau->next = (nouveau->next)->next;			}		}	} else {		struct fb *prev, *courant;		courant = tete;		prev = courant;		while ((courant != NULL) && (courant < nouveau)) {			prev = courant;			courant = courant->next;		}		if (courant > nouveau) {			prev->next = nouveau;			nouveau->next = courant;			if (nouveau->next != NULL) { //fusion				if (nouveau->next == (struct fb*) (((char *) nouveau) + nouveau->taille)) {					nouveau->taille = nouveau->taille + (nouveau->next)->taille;					nouveau->next = (nouveau->next)->next;				}			}			if (prev->next == (struct fb*) (((char *) prev) + prev->taille)) {				prev->taille = prev->taille + (prev->next)->taille;				prev->next = (prev->next)->next;			}		}	}}