home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / tt / vmem11 / vmem_prg / vm_alloc.c < prev    next >
C/C++ Source or Header  |  1990-09-27  |  5KB  |  244 lines

  1. #include "vmem.h"
  2.  
  3. /************************/
  4. /* Speicheranforderung: */
  5. /************************/
  6.  
  7. V_ADR vm_alloc (size)
  8.     long size;
  9. {
  10.     VPAGE    vmempage;
  11.     WORD    count;
  12.     MD        entry;
  13.     int        before, pointer;
  14.  
  15.     if (size < 0)        /* freien Speicher ermitteln */
  16.     {
  17.         count = 0;
  18.         pointer = free_list;
  19.         while (pointer != NIL)
  20.         {
  21.             if (MD_COUNT (pointer) > count)
  22.                 count = MD_COUNT (pointer);
  23.             pointer = MD_NEXT (pointer);
  24.         }
  25.     
  26.         return (PAGE_TO_ADDR (count));
  27.     }
  28.  
  29.     count = GET_COUNT (size);
  30.     if ((count == 0) || (info.free_blocks == 0))
  31.         return (_NULL);
  32.  
  33.     before = NIL;
  34.     pointer = free_list;
  35.     while (pointer != NIL)
  36.     {
  37.         if (MD_COUNT (pointer) >= count)
  38.         {
  39.             vmempage = MD_START (pointer);
  40.  
  41.             if (init_pages (vmempage, count) != OK)
  42.                 return (_NULL);
  43.  
  44.             MD_START (pointer) += count;
  45.             if ((MD_COUNT (pointer) -= count) == 0)
  46.                 md_delete (before, pointer);
  47.  
  48. /* Suchen des Nachfolgers in der Belegtliste: */
  49.  
  50.             before = NIL;
  51.             pointer = used_list;
  52.             while ((pointer != NIL) && (MD_START (pointer) < vmempage))
  53.             {
  54.                 before = pointer;
  55.                 pointer = MD_NEXT (pointer);
  56.             }
  57.  
  58. /* Einhängen des neuen MD in die Belegtliste: */
  59.  
  60.             entry = get_free_md ();
  61.             INSERT_MD (entry, vmempage, count, pointer);
  62.             if (before == NIL)
  63.                 used_list = entry;
  64.             else
  65.                 MD_NEXT (before) = entry;
  66.  
  67. /* Initialisierung der Seiten: */
  68.  
  69.             entry = vmempage;
  70.             do
  71.                 flags [entry++] = (NEW | FILE | USED);
  72.             while (--count > 0);
  73.  
  74.             info.free_blocks--;
  75.  
  76.             return (PAGE_TO_ADDR (vmempage));
  77.         }
  78.         before = pointer;
  79.         pointer = MD_NEXT (pointer);
  80.     }
  81.     return (_NULL);
  82. }
  83.  
  84.  
  85. /*********************/
  86. /* Speicherfreigabe: */
  87. /*********************/
  88.  
  89. int vm_free (address)
  90.     V_ADR address;
  91. {
  92.     VPAGE    vmempage, lastpage;
  93.     WORD    count;
  94.     MD        entry;
  95.     int        before, pointer, before2, pointer2;
  96.  
  97.     vmempage = GET_PAGE (address);
  98.     count = GET_OFFSET (address);
  99.     lastpage = vmempage + count - 1;
  100.     if (count != 0)
  101.         return (NOT_OK);
  102.  
  103.     before = NIL;
  104.     pointer = used_list;
  105.     while (pointer != NIL)
  106.     {
  107.         if (MD_START (pointer) == vmempage)
  108.         {
  109. /* MD aus der Belegtliste ausketten: */
  110.  
  111.             if (sector_flag)
  112.                 free_sector (vmempage, MD_COUNT (pointer));
  113.  
  114.             if (before == NIL)
  115.                 used_list = MD_NEXT (pointer);
  116.             else
  117.                 MD_NEXT (before) = MD_NEXT (pointer);
  118.  
  119. /* Platz des MDs in der Freiliste suchen: */
  120.  
  121.             before2 = NIL;
  122.             pointer2 = free_list;
  123.             while ((pointer2 != NIL) && (MD_START (pointer2) < vmempage))
  124.             {
  125.                 before2 = pointer2;
  126.                 pointer2 = MD_NEXT (pointer2);
  127.             }
  128.  
  129. /* MD in die Freiliste einketten: */
  130.  
  131.             if (before2 == NIL)
  132.                 free_list = pointer;
  133.             else
  134.                 MD_NEXT (before2) = pointer;
  135.  
  136. /* Nachfolger des MD ist nun in der Freiliste: */
  137.             
  138.             MD_NEXT (pointer) = pointer2;
  139.  
  140. /* Speicherkompression: */
  141.  
  142.             md_merge (before2, pointer, pointer2);
  143.  
  144. /* Freigabe der sich im CACHE befindenden Seiten: */
  145.  
  146.             for (entry = 0; entry < info.cache_count; entry++)
  147.             {
  148.                 if (cache_flags [entry] != CACHE_FREE)
  149.                 {
  150.                     if (INSIDE (cache_page [entry], vmempage, lastpage))
  151.                         FREE_CACHE (entry);
  152.                 }
  153.             }
  154.  
  155. /* Seiten initialisieren: */
  156.  
  157.             do
  158.                 flags [vmempage++] = FREE;
  159.             while (--count > 0);
  160.  
  161.             info.free_blocks++;
  162.             if (info.free_blocks == MAX_BLOCKS)
  163.             {
  164.                 for (entry=0; entry < (age_count + 4); entry++)
  165.                 {
  166.                     FREE_CACHE (entry);
  167.                     cache_age [entry] = 0;
  168.                 }
  169.             }
  170.  
  171.             return (OK);
  172.         }
  173.         before = pointer;
  174.         pointer = MD_NEXT (pointer);
  175.     }
  176.     return (NOT_OK);
  177. }
  178.  
  179.  
  180. /********************************************/
  181. /* Ausketten und Löschen einer MD-Struktur: */
  182. /********************************************/
  183.  
  184. void md_delete (before, pointer)
  185.     MD    before, pointer;
  186. {
  187.     if (before == NIL)
  188.         free_list = MD_NEXT (pointer);
  189.     else
  190.         MD_NEXT (before) = MD_NEXT (pointer);
  191.  
  192.     DELETE_MD (pointer);
  193. }
  194.  
  195.  
  196. /****************************/
  197. /* Verketten freier Blöcke: */
  198. /****************************/
  199.  
  200. void md_merge (before, current, next)
  201.     MD    before, current, next;
  202. {
  203.     if (before != NIL)
  204.     {
  205.         if ((MD_START (before) + MD_COUNT (before)) == MD_START (current))
  206.         {
  207.             MD_COUNT (before) += MD_COUNT (current);
  208.             md_delete (before, current);
  209.             current = before;
  210.         }
  211.     }
  212.     
  213.     if (next != NIL)
  214.     {
  215.         if ((MD_START (current) + MD_COUNT (current)) == MD_START (next))
  216.         {
  217.             MD_COUNT (current) += MD_COUNT (next);
  218.             md_delete (current, next);
  219.         }
  220.     }
  221. }
  222.  
  223.  
  224. /******************************************/
  225. /* Suchen eines Eintrags der Belegtliste: */
  226. /******************************************/
  227.  
  228. MD md_find (vmempage)
  229.     VPAGE    vmempage;
  230. {
  231.     MD    before, pointer;
  232.  
  233.     before = used_list;
  234.     pointer = MD_NEXT (before);
  235.  
  236.     while ((pointer != NIL) && (MD_START (pointer) < vmempage))
  237.     {
  238.         before = pointer;
  239.         pointer = MD_NEXT (pointer);
  240.     }
  241.  
  242.     return (before);
  243. }
  244.