TEMA 3. GESTIÃN DE MEMORIA - Universidad de AlmerÃa
TEMA 3. GESTIÃN DE MEMORIA - Universidad de AlmerÃa
TEMA 3. GESTIÃN DE MEMORIA - Universidad de AlmerÃa
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Diseño <strong>de</strong> Sistemas Operativos<br />
Tema <strong>3.</strong> Gestión <strong>de</strong> Memoria<br />
El sistema agrupa los cachés formando una lista enlazada. Los slabs <strong>de</strong>ntro <strong>de</strong> una caché se agrupan<br />
formando una lista circular doblemente enlazada. Se mantiene la lista parcialmente or<strong>de</strong>nada; primero los<br />
slabs llenos, luego los parcialmente llenos y luego los vacíos. La caché mantiene un puntero al primer slab con<br />
al menos un objeto libre. Los <strong>de</strong>scriptores <strong>de</strong> slab se pue<strong>de</strong>n almacenar <strong>de</strong>ntro o fuera <strong>de</strong>l propio slab. Para<br />
ilustrar este comportamiento po<strong>de</strong>mos estudiar la siguiente figura,<br />
Figura <strong>3.</strong>14. Relación entre los <strong>de</strong>scriptores <strong>de</strong> caché y los <strong>de</strong>scriptores <strong>de</strong> slabs.<br />
Los cachés se divi<strong>de</strong>n en dos categorías: (1) cachés generales, utilizados por el Slab allocator para<br />
propósitos propios); (2) cachés específicos, utilizados por lss restantes partes <strong>de</strong>l kernel. Los cachés<br />
generales son: (1) un primer caché que contiene los <strong>de</strong>scriptores <strong>de</strong> caché utilizados por el kernel (la variable<br />
cache_cache contiene su <strong>de</strong>scriptor). (2) Trece cachés adicionales para almacenar áreas <strong>de</strong> tamaño<br />
geométricamente distribuido, <strong>de</strong> tamaños 32, 64, 128, 256, 512 hasta 131072 bytes. Por cada tamaño hay dos<br />
cachés, uno apropiado para asignaciones DMA y el otro para asignaciones normales (la tabla cache_sizes se<br />
utiliza eficientemente para <strong>de</strong>rivar la dirección <strong>de</strong> caché correspondiente a un tamaño dado. Los cachés<br />
generales se inicializan con kmem_cache_init() y kmem_cache_sizes_init() durante la inicialización <strong>de</strong>l<br />
sistema. Por otro lado, los cachés específicos se crean mediante kmem_cache_create(). Para <strong>de</strong>struir un<br />
caché se llama a la función kmem_cache_<strong>de</strong>stroy() que se encuentra en el archivo fuente .<br />
Cada objeto tiene un <strong>de</strong>scriptor <strong>de</strong> tipo kmem_bufctl_t en el archivo fuente . Los <strong>de</strong>scriptores <strong>de</strong><br />
objetos se almacenan en un array ubicado <strong>de</strong>spués <strong>de</strong>l correspondiente <strong>de</strong>scriptor <strong>de</strong> slab. Al igual que los<br />
<strong>de</strong>scriptores <strong>de</strong> slabs, los <strong>de</strong>scriptores <strong>de</strong> objetos <strong>de</strong> un slab pue<strong>de</strong>n almacenarse <strong>de</strong> dos formas: <strong>de</strong>scriptores<br />
<strong>de</strong> objetos externos e internos. El primer <strong>de</strong>scriptor <strong>de</strong> objeto en el array <strong>de</strong>scribe el primer objeto en el array<br />
y así sucesivamente. Un <strong>de</strong>scriptor <strong>de</strong> objetos es simplemente en entero (unsigned int), que tiene significado<br />
cuando el objeto está libre. Éste contiene el índice al siguiente objeto libre en el slab, implementando así una<br />
liste <strong>de</strong> objetos libres en el slab. El <strong>de</strong>scriptor <strong>de</strong>l objeto <strong>de</strong>l último elemento <strong>de</strong> la lista <strong>de</strong> objetos libres se<br />
marca como BUFCLT_END (0xffffffff). Los objetos se asignan y se liberan mediante las funciones<br />
kmem_cache_alloc() y kmem_cache_free(). Los objetos <strong>de</strong> propósito general se obtienen mediante las<br />
funciones kmalloc() y se liberan con kfree(), implementadas en , permitiendo asignar y liberar<br />
áreas <strong>de</strong> memoria formadas por páginas contiguas en memoria central.<br />
<strong>3.</strong>4.<strong>3.</strong>6. Gestión <strong>de</strong> Área <strong>de</strong> Memoria no Contigua<br />
En ocasiones no es posible o no es ventajoso emplear marcos <strong>de</strong> página contiguos. En ese caso, se mapea un<br />
rango <strong>de</strong> direcciones lineal contiguo sobre marcos <strong>de</strong> página no contiguos. La principal ventaja <strong>de</strong> este<br />
esquema es que evita la fragmentación externa, mientras que el inconveniente es que es necesario modificar<br />
las tablas <strong>de</strong> páginas <strong>de</strong>l kernel. Es práctico para asignaciones infrecuentes. El tamaño <strong>de</strong> la asignación<br />
lógicamente <strong>de</strong>be ser múltiplo <strong>de</strong> 4 KBytes.<br />
Departamento <strong>de</strong> Lenguajes y Computación. <strong>Universidad</strong> <strong>de</strong> Almería Página <strong>3.</strong>35