Corrige

Transcription

Corrige
TP7-8: Allocateur de mémoire.
(Basé sur Centrale 1999)– Correction
MP2/MP*- Khôles Caml 7-8
TP7-8: Allocateur de mémoire.
(Basé sur Centrale 1999)– Correction
Damien Martin-Guillerez
Lycée Chateaubriand
Février 2007
Si vous avez des questions, n’hésitez pas à m’interroger lors d’une séance de TP, ou par courrier
électronique :
[email protected]
1 Un corrigé
I Question 1
l e t a l l o c a t o r l i s t = r e f [ ( 0 , memsize ) ] ; ;
let f i r s t f i t size =
l e t rec aux = fun
| []
−> r a i s e NotEnoughMemory
| ( ( a , s ) : : q) −>
i f s > s i z e then a , ( a+s i z e , s−s i z e ) : : q
e l s e i f s = s i z e then a , q
else
l e t a ’ , l = aux q
in
a’,(a, s ):: l
in
l e t x , l = aux ! a l l o c a t o r l i s t
in
a l l o c a t o r l i s t := l ;
x
;;
I Question 2
let best fit size =
l e t rec aux r = fun
| []
−> i f ( f s t r ) < 0 then r a i s e NotEnoughMemory e l s e r , [ ]
| ( ( a , s ) : : q) −>
i f s = s i z e then ( a , s ) , q
e l s e i f ( s > s i z e ) && (( snd r ) > s ) then
l e t r ’ , l = aux ( a , s ) q
in
i f ( f s t r ’) <> a then r ’ , ( ( a , s ) : : l )
e l s e ( a , s ) , ( ( a+s i z e , s−s i z e ) : : l )
else
l e t a ’ , l = aux r q
in
a’,(a, s ):: l
in
l e t x , l = aux (−1, max int ) ! a l l o c a t o r l i s t
in
a l l o c a t o r l i s t := l ;
fst x
;;
1
TP7-8: Allocateur de mémoire.
(Basé sur Centrale 1999)– Correction
MP2/MP*- Khôles Caml 7-8
I Question 3
let
|
|
|
merge chunks = fun
[]
−> []
[t]
−> [t ]
( ( a1 , s1 ) : : ( a2 , s2 ) : : q) −>
i f a1+s1 = a2 then
( a1 , s1+s2 ) : : q
else
( a1 , s1 ) : : ( a2 , s2 ) : : q
;;
let free a t =
l e t rec aux = fun
| []
−> [(a , t ) ]
| [( x, s )]
−>
i f x < a then merge chunks [ ( x , s ) ; ( a , t ) ]
e l s e merge chunks [ ( a , t ) ; ( x , s ) ]
| ( ( x1 , s1 ) : : ( x2 , s2 ) : : q) −>
i f ( a > x1) && (a < x2 ) then
merge chunks ( ( x1 , s1 ) : : ( merge chunks ( ( a , t ) : : ( x2 , s2 ) : : q ) ) )
e l s e i f a < x1 then
merge chunks ( ( a , t ) : : ( x1 , s1 ) : : ( x2 , s2 ) : : q)
else
( x1 , s1 ) : : ( aux ( ( x2 , s2 ) : : q ) )
in
a l l o c a t o r l i s t : = aux ! a l l o c a t o r l i s t
;;
Le test demandé rendait la dernière allocation impossible selon la stratégie first-fit alors qu’il n’y avait
aucun problème sur la stratégie best-fit. On obtenait l’inverse en mettant la demande d’allocation de
500 mots à la fin.
I Question 4 On conservait le haut de la liste des blocs libre dans une référence vers un entier
( let head chunks = ref 0;;).
Tout d’abord, il était utile de faire des fonctions de manipulation des blocs.
l e t chunk size a = abs mem. ( a ) ; ;
le t set chunk size a s =
mem. ( a+(abs s)−1) <− abs s ;
mem. ( a )
<− s ;
;;
l e t create chunk a s =
mem. ( a )
<− s ;
mem. ( a+(abs s)−1) <− abs s ;
mem. ( a+1)
<− −1;
mem. ( a+2)
<− −1
;;
l e t chunk inuse a = mem. ( a ) < 0 ; ;
l e t c h u n k n e x t l i s t a = mem. ( a +1);;
l e t c h u n k p r e v l i s t a = mem. ( a +2);;
l e t insert chunk w a =
mem. ( a+2)
<− w;
mem. ( a+1)
<− mem. (w+1);
mem. (w+1)
<− a ;
i f mem. ( a+1) >= 0 then
mem. (mem. ( a+1)+2) <− a
;;
l e t insert chunk top w a =
mem. ( a+2) <− −1;
mem. (w+2) <− a ;
mem. ( a+1) <− w
;;
l e t unlink chunk a =
i f mem. ( a+1) >= 0 then
mem. (mem. ( a+1)+2) <− mem. ( a+2);
i f mem. ( a+2) >= 0 then
mem. (mem. ( a+2)+1) <− mem. ( a+1);
2
TP7-8: Allocateur de mémoire.
(Basé sur Centrale 1999)– Correction
MP2/MP*- Khôles Caml 7-8
mem. ( a+1) <− −1;
mem. ( a+2) <− −1
;;
l e t chunk next a = i f a+mem. ( a) >= memsize then −1 e l s e a + ( abs mem. ( a ) ) ; ;
l e t chunk prev a = i f a > 0 then a − mem. ( a−1) e l s e − 1 ; ;
Une fonction donnant la taille nécessaire en fonction de la taille demandée était utile également :
let convert size s =
let t = s + 2
in
i f t < min size then min size
e l s e i f ( t mod alignement ) <> 0 then t − ( t mod alignement ) + alignement
else t
;;
Ensuite, on pouvait faire la fonction d’initialisation :
l e t init mem () =
create chunk 0 memsize ;
head chunks := 0
;;
Après quelques fonctions de manipulation des listes de blocs :
l e t rec i n s e r t c h u n k l i s t b a c k w a r d top prev next cur =
i f prev < 0 then
begin
i f next >= 0 then insert chunk top next cur
e l s e (mem. ( cur+1) <− −1; mem. ( cur+2) <− −1);
cur
end
e l s e i f ( chunk size prev ) > ( chunk size cur ) then
i n s e r t c h u n k l i s t b a c k w a r d top ( c h u n k p r e v l i s t prev ) prev cur
e l s e ( insert chunk prev cur ; top )
;;
l e t rec i n s e r t c h u n k l i s t f o r w a r d top prev next cur =
i f next < 0 then
begin
i f prev >= 0 then ( insert chunk prev cur ; top )
e l s e (mem. ( cur+1) <− −1; mem. ( cur+2) <− −1; cur )
end
e l s e i f ( chunk size next ) < ( chunk size cur ) then
i n s e r t c h u n k l i s t f o r w a r d top next ( c h u n k n e x t l i s t next ) cur
e l s e i f prev < 0 then
( insert chunk top next cur ; cur )
e l s e ( insert chunk prev cur ; top )
;;
l e t chunk allocate top a t =
l e t x = chunk size a
in
i f x <= t+min size then
begin
l e t n = c h u n k n e x t l i s t a in
unlink chunk a ;
s e t c h u n k s i z e a (−x ) ;
i f top = a then n
e l s e top
end
else
begin
l e t prev = c h u n k p r e v l i s t a
and next = c h u n k n e x t l i s t a
in
unlink chunk a ;
3
TP7-8: Allocateur de mémoire.
(Basé sur Centrale 1999)– Correction
MP2/MP*- Khôles Caml 7-8
set chunk size a
(−t ) ;
create chunk
( a+t ) ( x−t ) ;
i n s e r t c h u n k l i s t b a c k w a r d top prev next ( a+t )
end
;;
l e t chunk merge top a =
l e t next = chunk next a
and prev = chunk prev a
and t = r e f top
and adr = r e f a
in
i f next >= 0 then
i f not ( chunk inuse next ) then
begin
i f next = top then t : = ( c h u n k n e x t l i s t next ) ;
unlink chunk next ;
s e t c h u n k s i z e a ( ( chunk size a)+( chunk size next ) )
end ;
i f prev >= 0 then
i f not ( chunk inuse prev ) then
begin
i f prev = ! t then t : = ( c h u n k n e x t l i s t prev ) ;
unlink chunk prev ;
s e t c h u n k s i z e prev ( ( chunk size prev)+( chunk size a ) ) ;
adr : = prev
end ;
! t , ! adr
;;
l e t chunk free top a =
create chunk
a ( chunk size a ) ;
l e t x , adr = chunk merge top a in
i n s e r t c h u n k l i s t f o r w a r d x (−1) x adr
;;
l e t rec c h u n k f i r s t f i t top t =
i f top < 0 then r a i s e NotEnoughMemory
e l s e i f ( chunk size top) >= t then top
e l s e c h u n k f i r s t f i t ( c h u n k n e x t l i s t top ) t
;;
Enfin, on pouvait faire les fonctions d’allocation et de libération :
let bin alloc size =
let t = convert size size
in
l e t a = c h u n k f i r s t f i t ! head chunks t
in
head chunks : = chunk allocate ! head chunks a t ;
a+1
;;
l e t b i n f r e e adr =
l e t a = adr − 1
in
i f not ( chunk inuse a ) then r a i s e DoubleFree ;
head chunks : = chunk free ! head chunks a
;;
I Question 5 Ici, quelques adaptations simples était nécessaire, notamment pour remettre les blocs
dans les bonnes listes.
l e t bins = make vect 8 8 ( − 1 ) ; ;
l e t log2 n =
let r = ref 0
4
TP7-8: Allocateur de mémoire.
(Basé sur Centrale 1999)– Correction
MP2/MP*- Khôles Caml 7-8
and m = r e f n
in
while !m <> 0 do
incr r ;
m : = !m / 2
done ;
! r−1
;;
l e t index from size s i z e =
i f s i z e <= 128 then ( ( s i z e +1) / 2) − 1
e l s e ( log2 s i z e ) + 57
;;
l e t d l i n i t () =
create chunk 0 memsize ;
f o r i = 0 to ( v e c t l e n g t h bins )−1 do bins . ( i ) <− −1 done ;
bins . ( i n d e x f r o m s i z e memsize) <− 0
;;
l e t choose bin t =
l e t i = r e f ( index from size t )
in
while ( ! i < ( v e c t l e n g t h bins )) && ( bins . ( ! i ) = −1) do i n c r i done ;
i f ! i = ( v e c t l e n g t h bins ) then r a i s e NotEnoughMemory
else ! i
;;
l e t next bin b =
l e t i = r e f ( b+1)
in
while ( ! i < ( v e c t l e n g t h bins )) && ( bins . ( ! i ) = −1) do i n c r i done ;
i f ! i = ( v e c t l e n g t h bins ) then r a i s e NotEnoughMemory
else ! i
;;
l e t dl movebin bin =
l e t x = bins . ( bin ) in
i f x >= 0 then
l e t i = i n d e x f r o m s i z e ( chunk size x)
in
i f i <> bin then
begin
bins . ( bin) <− c h u n k n e x t l i s t x ;
unlink chunk x ;
bins . ( i ) <− i n s e r t c h u n k l i s t f o r w a r d bins . ( i ) (−1) bins . ( i ) x
end
;;
let dl alloc size =
let t = convert size size
in
l e t bin = r e f ( choose bin t )
in
l e t a = ( try c h u n k f i r s t f i t bins . ( ! bin ) t
with NotEnoughMemory −> bin : = next bin ! bin ; c h u n k f i r s t f i t bins . ( ! bin ) t )
in
bins . ( ! bin) <− chunk allocate bins . ( ! bin ) a t ;
dl movebin ! bin ;
a+1
;;
l e t dl chunk merge a =
l e t next = chunk next a
and prev = chunk prev a
and adr = r e f a
in
i f next >= 0 then
i f not ( chunk inuse next ) then
begin
l e t i = ( i n d e x f r o m s i z e ( chunk size next ) ) in
i f next = bins . ( i ) then bins . ( i ) <− ( c h u n k n e x t l i s t next ) ;
unlink chunk next ;
s e t c h u n k s i z e a ( ( chunk size a)+( chunk size next ) )
end ;
5
TP7-8: Allocateur de mémoire.
(Basé sur Centrale 1999)– Correction
MP2/MP*- Khôles Caml 7-8
i f prev >= 0 then
i f not ( chunk inuse prev ) then
begin
l e t i = ( i n d e x f r o m s i z e ( chunk size prev ) ) in
i f prev = bins . ( i ) then bins . ( i ) <− ( c h u n k n e x t l i s t prev ) ;
unlink chunk prev ;
s e t c h u n k s i z e prev ( ( chunk size prev)+( chunk size a ) ) ;
adr : = prev
end ;
! adr
;;
l e t d l f r e e adr =
l e t a = adr − 1
in
i f not ( chunk inuse a ) then r a i s e DoubleFree ;
create chunk
a ( chunk size a ) ;
l e t x = dl chunk merge a
in
l e t i = i n d e x f r o m s i z e ( chunk size x)
in
bins . ( i ) <− i n s e r t c h u n k l i s t f o r w a r d bins . ( i ) (−1) bins . ( i ) x
;;
6