home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / TIERRA40.ZIP / TIERRA / MEMALLOC.C < prev    next >
C/C++ Source or Header  |  1992-09-09  |  7KB  |  228 lines

  1. /* memalloc.c   9-9-92 memory allocation routines for the Tierra Simulator */
  2. /* Tierra Simulator V4.0: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */
  3.  
  4. #ifndef lint
  5. static char     memalloc_sccsid[] = "@(#)memalloc.c        1.5     7/21/92";
  6. #endif
  7.  
  8. #include <sys/types.h>
  9. #include "license.h"
  10. #include "tierra.h"
  11. #include "extern.h"
  12.  
  13. #ifdef ALCOMM
  14. #include "tmonitor.h"
  15. #include "trequest.h"
  16. #include <mlayer.h>
  17. #endif
  18.  
  19.  
  20. #ifdef MEM_CHK
  21. #include <memcheck.h>
  22. #endif
  23.  
  24. /* check to see if cell has write privelage at address */
  25. I8s  IsPriv(ce, a)
  26. Pcells  ce;
  27. I32s  a;
  28. {
  29. #ifdef ERROR
  30.     if(a >= SoupSize || a < 0)
  31.         FEError(-600,EXIT,WRITE,
  32.             "Tierra IsPriv() error: address %ld not in soup", a);
  33. #endif
  34.     if(IsInsideCell(ce, a)) return 1;
  35.     return IsFree(a);
  36. }
  37.  
  38. I8s IsBitPriv(ce,a,mode,track)
  39. Pcells  ce;
  40. I32s     a; /* address being checked */
  41. I32s    mode, track; /* modes: 1 bit = execute, 2 bit = write, 4 bit = read */
  42. {   if(a < 0 || a >= SoupSize)
  43.         return 0;
  44.     if(IsInsideCell(ce,a))
  45.         return 1;
  46.     else
  47.         switch(mode)
  48.         {
  49. #if PLOIDY == 1
  50.             case 1: return !soup[a].exec;
  51.             case 2: return !soup[a].write;
  52.             case 4: return !soup[a].read;
  53.             case 6: return (!soup[a].read) && (!soup[a].write);
  54. #else /* PLOIDY > 1 */
  55.             case 1: return !soup[a][track].exec;
  56.             case 2: return !soup[a][track].write;
  57.             case 4: return !soup[a][track].read;
  58.             case 6: return (!soup[a][track].read) && (!soup[a][track].write);
  59. #endif /* PLOIDY > 1 */
  60.             default: return 0;
  61.         }
  62. }
  63.  
  64. /* check to see if address is inside allocated memory cell ce */
  65. I8s  IsInsideCell(ce, a)
  66. Pcells  ce;
  67. I32s  a;
  68. {
  69. #ifdef ERROR
  70.     if(a >= SoupSize || a < 0)
  71.         FEError(-601,EXIT,WRITE,
  72.             "Tierra IsInsideCell() error: address %ld not in soup", a);
  73. #endif
  74.     if((ce->mm.p <= a && a < ce->mm.p + ce->mm.s) ||
  75.        (ce->md.s > 0 &&
  76.        (ce->md.p <= a && a < ce->md.p + ce->md.s)))
  77.         return 1;
  78.     return 0;
  79. }
  80.  
  81. void  WhichCell(a, ce, md) /* find cell with address a */
  82. I32s        a;    /* note: a must be in a cell!, call IsFree() before */
  83. Pcells Fp  ce;   /* WhichCell() to find out if a is in a cell or not */
  84. I8s        *md;
  85. {   I32s  ar, ci;
  86.     Pcells  te;
  87.  
  88.     for(ar = 0; ar < NumCelAr; ar++) for(ci = 0; ci < CelArSiz; ci++)
  89.     {   if (ar == 0 && ci < 2)
  90.             continue;
  91.         te = &cells[ar][ci];
  92.         if (te->ld)
  93.         {   if(te->mm.p <= a && (te->mm.p + te->mm.s) > a)
  94.             {   *ce = te; *md = 'm'; return; }
  95.             if(te->md.p <= a && (te->md.p + te->md.s) > a)
  96.             {   *ce = te; *md = 'd'; return; }
  97.         }
  98.     }
  99.     FEError(-601,EXIT,NOWRITE,
  100.         "Tierra WhichCell() error: address %ld not found in a cell", a);
  101. }
  102.  
  103. /* ----------------------------------------------------------------------- */
  104.  /* 1 bit = execute, 2 bit = write, 4 bit = read */
  105.  /* only owner of memory has chmod privelages */
  106.  /* return 0 on success, return 1 on error */
  107.  
  108. I8s chmode(ce, start, size, mode)
  109.     Pcells  ce;
  110.     I32s start, /* where in the soup to start */
  111.          size,  /* how far to go, (will wrap around end of soup) */
  112.          mode;  /* chmod bits, like unix, see above */
  113. {
  114.     I32s a = 0, t;
  115.     I8s exec, write, read, ret = 0;
  116.  
  117.     exec =  IsBit(mode, 0);
  118.     write = IsBit(mode, 1);
  119.     read =  IsBit(mode, 2);
  120.     while (a < size)
  121.     {   t = ad(start + a);
  122.         if (IsInsideCell(ce, t))
  123.         {
  124. #if PLOIDY == 1
  125.             soup[t].exec = exec;
  126.             soup[t].write = write;
  127.             soup[t].read = read;
  128. #else  /* PLOIDY > 1 */
  129.             soup[t][ce->c.tr].exec = exec;
  130.             soup[t][ce->c.tr].write = write;
  131.             soup[t][ce->c.tr].read = read;
  132. #endif  /* PLOIDY > 1 */
  133.         }
  134.         else ret = 1;
  135.         a++;
  136.     }
  137.     return ret;
  138. }
  139.  
  140. /* ----------------------------------------------------------------------- */
  141.  
  142. I32s mal(ce,sug_addr,sug_size,mode) /* allocate space for a new cell */
  143.     Pcells  ce;
  144.     I32s *sug_addr, /* returns actuall address of block, */
  145.                     /* also suggested address for mal */
  146.          sug_size,  /* size of block to get */
  147.                     /* function returns actual size, or 0 on failure */
  148.          mode;      /* which mode to use, see switch below */
  149. {
  150.     I32s p;
  151.     I32s size, osize, sad;
  152.  
  153.     if (sug_size <= 0 || sug_size == ce->md.s || 
  154.         sug_size > MaxMalMult * ce->mm.s)
  155.         return 0;
  156.     size = (I32s) sug_size + flaw(ce);
  157.     if (!size)
  158.         return 0;
  159.     if (ce->md.s)
  160.     {
  161. #ifdef ERROR
  162.         if (ce->md.p < 0 || ce->md.p >= SoupSize)
  163.             FEError(-613,EXIT,WRITE, "Tierra mal() error 1");
  164. #endif  /* DAN should check return val */
  165.         chmode(ce, ce->md.p, ce->md.s, MemModeFree); 
  166.         MemDealloc(ce->md.p, ce->md.s);
  167.         ce->d.mov_daught = 0;
  168.         ce->md.s = 0;
  169.     }
  170.     switch (mode)
  171.     {   case 0: /* first fit */
  172.         {   while ((p = MemAlloc(size, 0, SoupSize - 1)) < 0)
  173.                 reaper(1,0);
  174.             break;
  175.         }
  176.         case 2: /* random preference */
  177.         {   while ((p = MemAlloc(size, sad = tlrand() % (SoupSize - size),
  178.                     MalLimit)) < 0)
  179.                 reaper(1,sad);
  180.             break;
  181.         }
  182.         case 3: /* preference for mother's address */
  183.         {   while ((p = MemAlloc(size, ce->mm.p, MalLimit)) < 0)
  184.                 reaper(1,ce->mm.p);
  185.             break;
  186.         }
  187.         case 4: /* preference for dx address */
  188.         {   while ((p = MemAlloc(size, sad = mo(ce->c.re[3], SoupSize - size),
  189.                     MalLimit)) < 0)
  190.                 reaper(1,sad);
  191.             break;
  192.         }
  193.         case 5: /* preference for top of stack address */
  194.         {   while ((p = MemAlloc(size, sad = mo(ce->c.st[ce->c.sp],
  195.                     SoupSize - size), MalLimit)) < 0)
  196.                 reaper(1,sad);
  197.             break;
  198.         }
  199.         case 6: /* preference for suggested address (*sug_addr) */
  200.         {   while ((p = MemAlloc(size, sad = mo(*sug_addr, SoupSize - size),
  201.                     MalLimit)) < 0)
  202.                 reaper(1,sad);
  203.             break;
  204.         }
  205.         case 1: default: /* better fit */
  206.         {   while ((p = MemAlloc(size, -1, 0)) < 0)
  207.                 reaper(1,-1);
  208.         }
  209.     }
  210. #ifdef ERROR
  211.     if (p < 0 || p >= SoupSize)
  212.         FEError(-614,EXIT,WRITE, "Tierra mal() error 2");
  213. #endif
  214.     if (!size)
  215.         return 0;
  216.  
  217.     /* got a block, pass location (sug_addr) and size back  */
  218.  
  219.     *(sug_addr) = ce->md.p = ad(p);
  220.     ce->md.s = size;
  221.     ce->c.fl = 0;
  222.     DownReperIf(ce);
  223.     return size;
  224. }
  225.  
  226. /* ----------------------------------------------------------------------- */
  227.  
  228.