Download - Buddy System (Temani Afif II2H)
Temani Afif 02/21/2012
II2H
1
Méthode d’allocation par subdivision
(Buddy System)
Introduction
La technique d'allocation de mémoire par subdivision est un algorithme qui divise la mémoire
en partitions pour tenter de satisfaire une demande de mémoire de la façon la plus appropriée
que possible. Ce système permet l'utilisation de la mémoire divisée en deux moitiés pour
essayer de donner un meilleur ajustement. Selon Donald Knuth, le système de jumelage a été
inventé en 1963 par Harry Markowitz, qui a remporté le prix Nobel 1990 en économie, et a
d'abord été décrit par Kenneth C. Knowlton. L'allocation de mémoire Buddy System est
relativement facile à mettre en œuvre.
Comme le montre la figure ci-dessous, la mémoire initiale de 1024 Ko constitue un seul bloc
libre. Pour placer le programme A, le bloc de 1024 Ko est subdivisé en 1 bloc de 512 Ko, 1
bloc de 256 Ko, 1 bloc de 128 Ko, le dernier bloc de 128 Ko étant affecté au programme A.
Le programme B nécessite un espace de 64 Ko qui n'existe pas. On choisit donc de
partitionner un bloc de 128 Ko en deux blocs de 64 Ko, l'un étant affecté au programme B,
l'autre étant libre. Le placement du programme C nécessite un bloc de 128 Ko obtenu en
partitionnant un bloc de 256 Ko. La fin des programmes A puis B libère un bloc de 128 Ko,
puis un autre de 64 Ko dont le "compagnon" est libre. Ils sont donc fusionnés en un bloc de
128 Ko dont le compagnon est lui aussi libre. Leur réunion conduit à un bloc de 256 Ko.
Temani Afif 02/21/2012
II2H
2
Le simulateur
Objectif : Ce programme simule l’allocation/libération de la mémoire selon la
méthode de subdivision décrite ci-dessus. Le simulateur affiche le contenu de la mémoire
centrale après chaque opération demandée. Il nous donne une information sur le pourcentage
d’occupation de chaque partition ainsi que la taille des fragments internes.
Rq : ce programme effectue toutes les allocations ensuite les libérations. Il peut être amélioré en ajoutant un
menu interactif offrant la possibilité de choisir entre une allocation ou une libération à chaque demande.
Structure de données : Pour l’enregistrement des données de la mémoire j’ai opté pour
une structure d’arbre binaire ou chaque feuille représente un bloc mémoire (libre ou occupé)
et les blocs de même taille auront la même hauteur dans l’arbre.
Exemple d’exécution : Voici un exemple d’exécution du simulateur avec les processus
suivant : Processus 1 avec une taille de 80
Processus 2 avec une taille de 40
Processus 3 avec une taille de 256
Processus 4 avec une taille de 128
Temani Afif 02/21/2012
II2H
3
Temani Afif 02/21/2012
II2H
4
Temani Afif 02/21/2012
II2H
5
C’est une exécution sous Windows, mais le simulateur marche aussi sous Unix.
Les fonctions du simulateur : le programme contient principalement 3 fonctions qui
sont récursives. Une première fonction pour l’allocation de la mémoire et la création de
nouvelles partitions (elle fera appel à une fonction initialisation pour créer les feuilles de
l’arbre). Une deuxième fonction pour la libération de l’espace alloué à un processus donné.
Une troisième fonction pour l’affichage de l’état de la mémoire.
J’ai utilisé 2 autres fonctions pour l’interaction avec l’utilisateur, qui peuvent bien sûr être améliorées pour plus
d’interactivité.
C:\Users\Afif\Desktop\BuddySystem.c dimanche 2 décembre 2012 18:16
/*
Temani Afif
02/12/2012
Ce programme simule la méthode d'allocation mémoire par subdivision (Buddy System)
*/
#include<stdio.h>
#include<stdlib.h>
/*
déclaration de la structure de la mémoire : arbre b inaire
*/
enum etat {Rouge,Jaune ,Vert };
struct memoire
{
int taille ;
int taille_occupee ;
enum etat e ;
int pid ;
struct memoire *filsg ;
struct memoire *filsd ;
};
typedef struct memoire * Mem;
//déclaration des variables globales
Mem L; //la mémoire
int a; // la taille de la mémoire
int nb_proc ; //le nombre de processus
//fonction pour initialiser la mémoire et construir e les noeuds de l'arbre (les partition de
la mémoire)
void initialisation (int taille , Mem *L)
{
(*L)=(Mem)malloc (sizeof(struct memoire ));
(**L).taille =taille ;
(**L).e=Vert ;
(**L).pid =0;
(**L).filsd =(**L).filsg =NULL;
(**L).taille_occupee =0;
}
//allocation de la mémoire à un processus "pid" de taille "taille"
// récursive
-1-
C:\Users\Afif\Desktop\BuddySystem.c dimanche 2 décembre 2012 18:16
int allouer (int taille ,int pid ,Mem L)
{
if((*L).taille <taille )
{
return -1;
}
if((*L).e==Vert )
{
if(((*L).taille )/2<taille )
{
(*L).taille_occupee =taille ;
(*L).e=Rouge;
(*L).pid =pid ;
//printf("%d : \tla partition a ete allouee au proc essus de
pid=%d\n\n",(*L).taille,pid);
return 1;
}
else
{
//printf("%d : \tla partition est divisee en 2 de m eme
taille=%d\n\n",(*L).taille,(*L).taille/2);
initialisation ((*L).taille /2,&((*L).filsg ));
initialisation ((*L).taille /2,&((*L).filsd ));
(*L).e=Jaune ;
return allouer (taille ,pid ,(*L).filsg );
}
}
if((*L).e==Jaune )
{
if( ((*((*L).filsg )).e!=Rouge) && ((*((*L).filsd )).e==Rouge) )
return allouer (taille ,pid ,(*L).filsg );
if( ((*((*L).filsd )).e!=Rouge) && ((*((*L).filsg )).e==Rouge) )
return allouer (taille ,pid ,(*L).filsd );
if( ((*((*L).filsg )).e==Jaune ) && ((*((*L).filsd )).e!=Rouge) )
if(allouer (taille ,pid ,(*L).filsg )!=1)
return allouer (taille ,pid ,(*L).filsd );
else
return 1;
if( ((*((*L).filsg )).e==Vert ) && ((*((*L).filsd )).e==Jaune ) )
if(allouer (taille ,pid ,(*L).filsd )!=1)
return allouer (taille ,pid ,(*L).filsg );
else
return 1;
}
}
//liberation de la mémoire détenue par le processus "pid"
// récursive
int liberer (int pid ,Mem L)
{
if( ((*L).e==Rouge) && ((*L).pid ==pid ))
{
//printf("le processus de pid=%d libere la partiton de taille
%d\n\n",pid,(*L).taille);
-2-
C:\Users\Afif\Desktop\BuddySystem.c dimanche 2 décembre 2012 18:16
(*L).taille_occupee =0;
(*L).e=Vert ;
(*L).pid =0;
return 1;
}
if( ((*L).e==Rouge) && ((*L).pid !=pid ))
{
return -1;
}
if( ((*L).e==Jaune ) )
{
if( ((*((*L).filsg )).e!=Vert ) && ((*((*L).filsd )).e!=Vert ) )
if(liberer (pid ,(*L).filsg )!=1)
return liberer (pid ,(*L).filsd );
else
return 1;
if( ((*((*L).filsg )).e!=Vert ) && ((*((*L).filsd )).e==Vert ) )
{
liberer (pid ,(*L).filsg );
if((*((*L).filsg )).e==Vert )
{
free ((*L).filsg );
free ((*L).filsd );
(*L).e=Vert ;
//printf("les partitions de taille %d on ete reasse mblee en une seule de
%d\n\n",(*L).taille/2,(*L).taille);
return 1;
}
return -1;
}
if( ((*((*L).filsg )).e==Vert ) && ((*((*L).filsd )).e!=Vert ) )
{
liberer (pid ,(*L).filsd );
if((*((*L).filsd )).e==Vert )
{
free ((*L).filsg );
free ((*L).filsd );
(*L).e=Vert ;
//printf("les partitions de taille %d on ete reasse mblee en une
seule\n\n",(*L).taille/2);
return 1;
}
return -1;
}
}
}
// affichier l'état de la mémoire (les partitions l ibres et occupées)
// récursive
int afficher_etat (Mem L)
{
if( ((*L).e==Vert ) )
{
if((*L).taille /1000!=0)
printf ("\t| Taille = %d |\n" ,(*L).taille );
else if((*L).taille /100!=0)
-3-
C:\Users\Afif\Desktop\BuddySystem.c dimanche 2 décembre 2012 18:16
printf ("\t| Taille = %d |\n" ,(*L).taille );
else if((*L).taille /10!=0)
printf ("\t| Taille = %d |\n" ,(*L).taille );
else
printf ("\t| Taille = %d |\n" ,(*L).taille );
printf ("\t| libre |\n" );
printf ("\t--------------------%d\n" ,a=a-(*L).taille );
return 1;
}
if( ((*L).e==Rouge) )
{
if((*L).taille /1000!=0)
printf ("\t| Taille = %d |\n" ,(*L).taille );
else if((*L).taille /100!=0)
printf ("\t| Taille = %d |\n" ,(*L).taille );
else if((*L).taille /10!=0)
printf ("\t| Taille = %d |\n" ,(*L).taille );
else
printf ("\t| Taille = %d |\n" ,(*L).taille );
printf ("\t| occupee par %d | <-- fragment interne = %d\ n" ,(*L).pid ,(*L).taille -(*L
).taille_occupee );
printf ("\t| a %.1f%% |\n" ,((*L).taille_occupee *100)/(float )(*L).taille );
printf ("\t--------------------%d\n" ,a=a-(*L).taille );
return 1;
}
if( ((*L).e==Jaune ) )
{
afficher_etat ((*L).filsd );
return afficher_etat ((*L).filsg );
}
}
int demande_allocation ()
{
int taille ;
printf ("donnez la taille du processus %d \t(-1 pour termin er les allocation)\n" ,nb_proc );
do
{
scanf ("%d" ,&taille );
if(taille ==-1)
return 0;
if(taille <=0)
printf ("taille erronee, reesayez \n" );
}
while(taille <=0);
if(allouer (taille ,nb_proc ,L)==1)
{
printf ("\tallocation du processus %d\n\n" ,nb_proc );
printf ("\t--------------------%d\n" ,a);
afficher_etat (L);
a=1024;
nb_proc ++;
}
else
-4-
C:\Users\Afif\Desktop\BuddySystem.c dimanche 2 décembre 2012 18:16
printf ("mémoire insuffisante, reesayez\n" );
return 1;
}
void demande_liberation ()
{
int pid ;
printf ("entrez le numero de processus a liberer \n" );
scanf ("%d" ,&pid );
liberer (pid ,L);
printf ("\tliberation du processus %d\n\n" ,pid );
printf ("\t--------------------%d\n" ,a);
afficher_etat (L);
a=1024;
}
int main ()
{
L=NULL;
printf ("\tinitialisation de la memoire\n\n" );
a=1024;
nb_proc =1;
initialisation (a,&L);
printf ("\t--------------------%d\n" ,a);
afficher_etat (L);
a=1024;
while(demande_allocation ()!=0)
{;}
while((*L).e!=Vert )
{
demande_liberation ();
}
}
-5-