home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / tt / vmem11 / vmem_prg / vm_addre.c < prev    next >
C/C++ Source or Header  |  1990-08-06  |  7KB  |  308 lines

  1. #include "vmem.h"
  2.  
  3. /******************************************/
  4. /* Adressierung des virtuellen Speichers: */
  5. /******************************************/
  6.  
  7. char *vm_address (address, window_size, mode)
  8.     V_ADR address;
  9.     long *window_size;
  10.     int mode;
  11. {
  12.     VPAGE    vmempage, lastpage;
  13.     CPAGE    select;
  14.     WORD    start_offset, count, i;
  15.  
  16.     vmempage = GET_PAGE (address);
  17.     start_offset = GET_OFFSET (address);
  18.  
  19. #ifdef DEBUG
  20.     printf ("\nVM_ADDRESS: page: %x  offset: %x", vmempage, start_offset);
  21. #endif
  22.  
  23.     if ((vmempage >= info.count_page) || (flags [vmempage] == FREE))
  24.         return ((char *) ILLEGAL_ADDRESS);
  25.     
  26.     if (*window_size <= 0)
  27.         return ((char *) ILLEGAL_COUNT);
  28.  
  29.     if ((mode != READ_MODE) && (mode != WRITE_MODE))
  30.         return ((char *) ILLEGAL_MODE);
  31.  
  32.     *window_size = MIN (*window_size, info.cache_size - start_offset);
  33.     count = GET_COUNT (*window_size + start_offset);
  34.     lastpage = vmempage + count - 1;
  35.  
  36. /* Sequenz im Cache suchen: Algorithmus 1 */
  37.  
  38.     if ((select = search_sequence (vmempage, lastpage)) == EMPTY_ENTRY)
  39.     {
  40.         ULONG    age, best_age;
  41.  
  42. /* keine geeignete Sequenz im Cache gefunden: Algorithmus 2 starten */
  43.     
  44.         select = 0;
  45.         age = 0;
  46.     
  47. /* Gesamt-Alter der 1. Cache-Sequenz bestimmen: */
  48.     
  49.         for (i = 0; i < count; i++)
  50.             age += (ULONG) cache_age [i];
  51.     
  52.         best_age = age;
  53.     
  54. /* "jüngere" Cache-Sequenz suchen: */
  55.     
  56.         for ( ; i < info.cache_count; i++)
  57.         {
  58.             age = age - (ULONG) cache_age [i-count] + (ULONG) cache_age [i];
  59.             if (age < best_age)
  60.             {
  61.                 best_age = age;
  62.                 select = i - count + 1;
  63.             }
  64.         }
  65.     }
  66.  
  67. #ifdef DEBUG
  68.     printf ("\nVM_ADDRESS: %x PAGES FROM CACHE %x", count, select);
  69. #endif
  70.  
  71. /* Belegte unbrauchbare Seiten innerhalb der Cache-Sequenz auslagern: */
  72.  
  73.     for (i = select; i < (select + count); i++)
  74.     {
  75.         if (cache_flags [i] != CACHE_FREE)
  76.         {
  77.             VPAGE    vpage = cache_page [i];
  78.  
  79.             if (OUTSIDE (vpage, vmempage, lastpage))
  80.             {
  81. #ifdef DEBUG
  82.     printf ("\nVM_ADDRESS: REMOVE CACHE %x (PAGE: %x, Flag: %x)",
  83.     i, cache_page [i], cache_flags [i]);
  84. #endif
  85.                 if (cache_flags [i] == CACHE_WRITE)
  86.                     write_page (CACHE_ADDRESS (i), vpage);
  87.                 else
  88.                     CACHE_TO_FILE (vpage);
  89.                 FREE_CACHE (i);
  90.             }
  91.         }
  92.     }
  93.  
  94. /* Durchsuchen des Caches nach Seiten, die zur Sequenz gehören: */
  95.  
  96.     for (i = 0; i < info.cache_count; i++)
  97.     {
  98.         if (cache_flags [i] != CACHE_FREE)
  99.         {
  100.             VPAGE    vpage = cache_page [i];
  101.  
  102.             if (INSIDE (vpage, vmempage, lastpage))
  103.             {
  104.                 WORD    source, dest;
  105.  
  106.                 dest = vpage - vmempage + select;
  107.                 source = search_cache (vpage);
  108.  
  109.                 if (source != dest)
  110.                 {
  111.                     if (cache_flags [dest] == CACHE_FREE)
  112.                     {
  113.                         COPY_CACHE (CACHE_ADDRESS (dest), CACHE_ADDRESS (source));
  114.                         ALLOC_CACHE (dest, cache_flags [source], vpage);
  115.                         FREE_CACHE (source);
  116.                     }
  117.                     else    /* CACHE is used */
  118.                     {
  119.                         WORD    other = cache_page [dest] - vmempage + select;
  120.                         
  121.                         if (cache_flags [other] == CACHE_FREE)
  122.                         {
  123.                             COPY_CACHE (CACHE_ADDRESS (other), CACHE_ADDRESS (dest));
  124.                             ALLOC_CACHE (other, cache_flags [dest], cache_page [dest]);
  125.                             COPY_CACHE (CACHE_ADDRESS (dest), CACHE_ADDRESS (source));
  126.                             ALLOC_CACHE (dest, cache_flags [source], vpage);
  127.                             FREE_CACHE (source);
  128.                         }
  129.                         else    /* CACHE is used */
  130.                         {
  131.                             if (cache_flags [dest] == CACHE_WRITE)
  132.                                 write_page (CACHE_ADDRESS (dest), cache_page [dest]);
  133.                             else
  134.                                 CACHE_TO_FILE (cache_page [dest]);
  135.  
  136.                             COPY_CACHE (CACHE_ADDRESS (dest), CACHE_ADDRESS (source));
  137.                             ALLOC_CACHE (dest, cache_flags [source], vpage);
  138.                             FREE_CACHE (source);
  139.                         }
  140.                     }
  141.                 }
  142.             }
  143.         }
  144.     }
  145.  
  146. /* restliche Seiten in den Cache einlagern: */
  147.  
  148.     for (i = select; i < (select + count); i++)
  149.     {
  150.         if (cache_flags [i] == CACHE_FREE)
  151.         {
  152.             VPAGE    vpage = vmempage + i - select;
  153.             
  154.             read_page (CACHE_ADDRESS (i), vpage);
  155.             FILE_TO_CACHE (vpage);
  156.             ALLOC_CACHE (i, mode, vpage);
  157.         }
  158.         else
  159.         {
  160.             UPDATE_FLAG (i, mode);
  161. #ifdef DEBUG2
  162.     printf ("\nUPDATE 2: CACHE %x WITH %x", i, mode);
  163. #endif
  164.         }
  165.         ACCESSED (i);
  166.     }
  167.  
  168.     return ((char *) (CACHE_ADDRESS (select) + start_offset));
  169. }
  170.  
  171.  
  172. /* alle Sequenzen im Cache untersuchen: */
  173.  
  174. WORD search_sequence (vmempage, lastpage)
  175.     VPAGE    vmempage, lastpage;
  176. {
  177.     SEQ        *sequences, *seq2;
  178.     WORD    scount, soldpage, border, i;
  179.  
  180.     sequences = (SEQ *) buffer;
  181.     sequences->count = 0;
  182.     scount = 0;
  183.     soldpage = EMPTY_ENTRY;
  184.     border = (lastpage - vmempage + 2) >> 1;
  185.  
  186. /* alle gültigen Sequenzen erstellen: */
  187.  
  188.     for (i = 0; i < info.cache_count; i++)
  189.     {
  190.         if (cache_flags [i] == CACHE_FREE)
  191.         {
  192.             if (scount >= border)
  193.             {
  194.                 sequences->count = scount;
  195.                 sequences++;
  196.                 sequences->count = 0;
  197.             }
  198.  
  199.             scount = 0;
  200.             soldpage = EMPTY_ENTRY;
  201.         }
  202.         else    /* CACHE is used */
  203.         {
  204.             if (OUTSIDE (cache_page [i], vmempage, lastpage))
  205.             {
  206.                 if (scount >= border)
  207.                 {
  208.                     sequences->count = scount;
  209.                     sequences++;
  210.                     sequences->count = 0;
  211.                 }
  212.  
  213.                 scount = 0;
  214.                 soldpage = EMPTY_ENTRY;
  215.             }
  216.             else    /* INSIDE */
  217.             {
  218.                 if (cache_page [i] != (soldpage + scount))
  219.                 {
  220.                     if (scount >= border)
  221.                     {
  222.                         sequences->count = scount;
  223.                         sequences++;
  224.                         sequences->count = 0;
  225.                     }
  226.  
  227.                     scount = 1;
  228.                     sequences->cachepage = i;
  229.                     sequences->vmempage = soldpage = cache_page [i];
  230.                 }
  231.                 else    /* Sequence continues */
  232.                 {
  233.                     scount++;
  234.                 }
  235.             }
  236.         }
  237.     }
  238.  
  239. /* Sequenz suchen, die alle gewünschten Seiten beinhaltet: */
  240.  
  241.     sequences = (SEQ *) buffer;
  242.     while (sequences->count != 0)
  243.     {
  244.         if ((sequences->vmempage <= vmempage)
  245.             && ((sequences->vmempage + sequences->count) > lastpage))
  246.         {
  247.             return (sequences->cachepage - (sequences->vmempage - vmempage));
  248.         }
  249.         sequences++;    /* Zeiger auf nächste gefundene Sequenz */
  250.     }
  251.  
  252. /* Sequenz suchen, bei der am Anfang und am Ende angefügt werden kann: */
  253.  
  254.     for (;;)
  255.     {
  256.         seq2 = sequences = (SEQ *) buffer;
  257.         scount = 0;
  258.         while (seq2->count != 0)
  259.         {
  260.             if (seq2->count > scount)
  261.             {
  262.                 scount = seq2->count;
  263.                 sequences = seq2;
  264.             }
  265.             seq2++;
  266.         }
  267.  
  268. /* War die Suche vergeblich ? */
  269.  
  270.         if (scount <= 1)
  271.             return (EMPTY_ENTRY);
  272.  
  273. /* Können Seiten am Anfang eingelagert werden ? */
  274.  
  275.         if (sequences->vmempage > vmempage)
  276.         {
  277.             if ((sequences->vmempage - vmempage) <= sequences->cachepage)
  278.                 scount = 1;
  279.             else
  280.                 scount = 0;
  281.         }
  282.         else
  283.             scount = 1;
  284.  
  285. /* Können Seiten am Ende eingelagert werden ? */
  286.  
  287.         if ((sequences->vmempage + sequences->count - 1) < lastpage)
  288.         {
  289.             if ((info.cache_count - sequences->cachepage)
  290.                 >= (lastpage + 1 - sequences->vmempage))
  291.             {
  292.                 scount += 2;
  293.             }
  294.         }
  295.         else
  296.             scount += 2;
  297.  
  298. /* Platz am Anfang und am Ende ? */
  299.  
  300.         if (scount == 3)
  301.             return (sequences->cachepage - (sequences->vmempage - vmempage));
  302.  
  303. /* Feld löschen; Suche fortsetzen: */
  304.  
  305.         sequences->count = 1;
  306.     }
  307. }
  308.