From 7cda165a76b11dd522db0516909da45f16ac1d84 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Thu, 30 Sep 2010 20:38:57 -0300 Subject: [PATCH] =?utf8?q?Poner=20c=C3=B3digo=20con=20un=20solo=20nivel=20?= =?utf8?q?de=20indentaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- source/dgc.rst | 132 ++++++++++++++++++++++++------------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/source/dgc.rst b/source/dgc.rst index f4cc980..faf4bd6 100644 --- a/source/dgc.rst +++ b/source/dgc.rst @@ -759,15 +759,15 @@ suficientemente grande como para poder almacenar el tamaño solicitado). Una vez más el algoritmo distingue objetos grandes de pequeños. Los pequeños se asignan de las siguiente manera:: - function new_small(block_size) is + function new_small(block_size) is + block = find_block_with_size(block_size) + if block is null + collect() block = find_block_with_size(block_size) if block is null - collect() + new_pool() block = find_block_with_size(block_size) - if block is null - new_pool() - block = find_block_with_size(block_size) - return block + return block Se intenta reiteradas veces conseguir un bloque del tamaño correcto libre, realizando diferentes acciones si no se tiene éxito. Primero se intenta hacer @@ -777,41 +777,41 @@ pidiendo memoria al *low level allocator* (el sistema operativo generalmente). Para intentar buscar un bloque de memoria libre se realiza lo siguiente:: - function find_block_with_size(block_size) is + function find_block_with_size(block_size) is + block = free_lists[block_size].pop_first() + if block is null + assign_page(block_size) block = free_lists[block_size].pop_first() - if block is null - assign_page(block_size) - block = free_lists[block_size].pop_first() - return block + return block Si no se puede obtener un bloque de la lista de libres correspondiente, se busca asignar una página libre al tamaño de bloque deseado de forma de *alimentar* la lista de libres con dicho tamaño:: - function assign_page(block_size) is - foreach pool in heap - foreach page in pool - if page.block_size is FREE - page.block_size = block_size - foreach block in page - free_lists[page.block_size].link(block) + function assign_page(block_size) is + foreach pool in heap + foreach page in pool + if page.block_size is FREE + page.block_size = block_size + foreach block in page + free_lists[page.block_size].link(block) Cuando todo ello falla, el último recurso consiste en pedir memoria al sistema operativo, creando un nuevo *pool*:: - funciones new_pool(number_of_pages = 1) is - pool = alloc(pool.sizeof) - if pool is null - return null - pool.number_of_pages = number_of_pages - pool.pages = alloc(number_of_pages * PAGE_SIZE) - if pool.pages is null - free(pool) - return null - heap.add(pool) - foreach page in pool - page.block_size = FREE - return pool + function new_pool(number_of_pages = 1) is + pool = alloc(pool.sizeof) + if pool is null + return null + pool.number_of_pages = number_of_pages + pool.pages = alloc(number_of_pages * PAGE_SIZE) + if pool.pages is null + free(pool) + return null + heap.add(pool) + foreach page in pool + page.block_size = FREE + return pool Se recuerda que la función ``alloc()`` es un :ref:`servicio ` provisto por el *low level allocator* y en la @@ -827,22 +827,22 @@ Si el tamaño de bloque necesario para cumplir con la asignación de memoria es de una página, entonces se utiliza otro algoritmo para alocar un objeto grande:: - function new_big(size) is - number_of_pages = ceil(size / PAGE_SIZE) + function new_big(size) is + number_of_pages = ceil(size / PAGE_SIZE) + pages = find_pages(number_of_pages) + if pages is null + collect() pages = find_pages(number_of_pages) if pages is null - collect() - pages = find_pages(number_of_pages) - if pages is null - minimize() - pool = new_pool(number_of_pages) - if pool is null - return null - pages = assign_pages(pool, number_of_pages) - pages[0].block_size = PAGE - foreach page in pages[1..end] - page.block_size = CONTINUATION - return pages[0] + minimize() + pool = new_pool(number_of_pages) + if pool is null + return null + pages = assign_pages(pool, number_of_pages) + pages[0].block_size = PAGE + foreach page in pages[1..end] + page.block_size = CONTINUATION + return pages[0] De forma similar a la asignación de objetos pequeños, se intenta encontrar una serie de páginas contiguas, dentro de un mismo *pool*, suficientes para @@ -868,34 +868,34 @@ completamente libres:: Volviendo a la función ``new_big()``, para hallar una serie de páginas contiguas se utiliza el siguiente algoritmo:: - function find_pages(number_of_pages) is - foreach pool in heap - pages = assign_pages(pool, number_of_pages) - if pages - return pages - return null + function find_pages(number_of_pages) is + foreach pool in heap + pages = assign_pages(pool, number_of_pages) + if pages + return pages + return null Como se dijo, las páginas deben estar contenidas en un mismo *pool* (para tener la garantía de que sean contiguas), por lo tanto se busca *pool* por *pool* dicha cantidad de páginas libres consecutivas a través del siguiente algoritmo:: - function assign_pages(pool, number_of_pages) is - pages_found = 0 - first_page = null - foreach page in pool - if page.block_size is FREE - if pages_found is 0 - pages_found = 1 - first_page = page - else - pages_found = pages_found + 1 - if pages_found is number_of_pages - return [first_page .. page] + function assign_pages(pool, number_of_pages) is + pages_found = 0 + first_page = null + foreach page in pool + if page.block_size is FREE + if pages_found is 0 + pages_found = 1 + first_page = page else - pages_found = 0 - first_page = null - return null + pages_found = pages_found + 1 + if pages_found is number_of_pages + return [first_page .. page] + else + pages_found = 0 + first_page = null + return null Una vez más, cuando todo ello falla (incluso luego de una recolección), se intenta alocar un nuevo *pool*, esta vez con una cantidad de páginas -- 2.43.0