]> git.llucax.com Git - z.facultad/75.00/informe.git/blobdiff - source/dgc.rst
Completar capítulo de Solución adoptada
[z.facultad/75.00/informe.git] / source / dgc.rst
index 46079283f4c5c914e386e78122b9029ff7a5ab67..804d554aae4c6ff22226c0a55a2b08622ee8db2a 100644 (file)
@@ -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,39 +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)
-         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
 <gc_intro_services>` provisto por el *low level allocator* y en la
@@ -825,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
@@ -866,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
@@ -1329,6 +1331,8 @@ a ningún destructor), para el usuario puede ser una garantía muy débil
 y proveer finalización asegurada puede ser muy deseable.
 
 
+.. _dgc_committed:
+
 Memoria *encomendada*
 ^^^^^^^^^^^^^^^^^^^^^
 El algoritmo actual divide un *pool* en dos áreas: memoria *encomendada*
@@ -1481,15 +1485,16 @@ Las opciones más importantes son:
       Esquema de un bloque cuando está activada la opción ``SENTINEL``.
 
       .. aafig::
+         :textual:
 
          |              |              |                              |        |
          +-- Palabra ---+-- Palabra ---+-- Tamaño bloque de usuario --+- Byte -+
          |              |              |                              |        |
 
          +--------------+--------------+------------------------------+--------+
-         |  Tamaño del  |     Pre      |                              |  Post  |
-         |  bloque  de  |              |      Bloque de usuario       |        |
-         |    usuario   |  0xF4F4F4F4  |                              |  0xF5  |
+         | "Tamaño del" |     Pre      |                              |  Post  |
+         |  "bloque de" |              |      Bloque de usuario       |        |
+         |   "usuario"  |  0xF4F4F4F4  |                              |  0xF5  |
          +--------------+--------------+------------------------------+--------+
                                        A
                                        |
@@ -1512,6 +1517,8 @@ participación y observación del grupo de noticias, de donde se obtuvieron los
 principales problemas percibidos por la comunidad que utiliza el lenguaje.
 
 
+.. _dgc_bad_code:
+
 Complejidad del código y documentación
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 El análisis del código fue muy complicado debido a la falta de documentación