home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / xplatfrm / tierra / memalloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-26  |  10.2 KB  |  338 lines

  1. /* memalloc.c  28-10-91 memory allocation routines for the Tierra simulator */
  2. /** Tierra Simulator V3.0: Copyright (c) 1991 Thomas S. Ray **/
  3.  
  4. #include "license.h"
  5.  
  6. #ifndef lint
  7. static char     memalloc_sccsid[] = "%W%     %G%";
  8. #endif
  9.  
  10. #include <sys/types.h>
  11. #include "tierra.h"
  12. #include "extern.h"
  13.  
  14. #ifdef SOCKETS
  15.  
  16. #include "allayer.h"
  17. #include "tlayer.h"
  18.  
  19. #endif
  20.  
  21. /* check to see if cell has write privelage at address */
  22. I8s  IsPriv(ce, a)
  23. Pcells  ce;
  24. Ind  a;
  25. {
  26. #ifdef ERROR
  27.     if(a >= SoupSize || a < 0)
  28.     {   sprintf(mes[0],"IsPriv error: address %ld not in soup", a);
  29.         if (!hangup)
  30.             FEMessage(1);
  31.         else
  32.         {   sprintf(mes[1],"system being saved to disk");
  33.             FEMessage(2);
  34.         }
  35.         while(hangup) ;
  36.         WriteSoup(1);
  37.         exit(0);
  38.     }
  39. #endif
  40.     if(IsInsideCell(ce, a)) return 1;
  41.     return IsFree(a);
  42. }
  43.  
  44. I8s IsBitPriv(ce,a,mode,track)
  45. Pcells  ce;
  46. Ind     a; /* address being checked */
  47. I8s     mode, track;
  48.     /* modes: 1 bit = execute, 2 bit = write, 4 bit = read */
  49. {   if(a < 0 || a >= SoupSize)
  50.         return 0;
  51.     if(IsInsideCell(ce,a))
  52.         return 1;
  53.     else
  54.         switch(mode)
  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.             default: return 0;
  60.         }
  61. }
  62.  
  63. /* check to see if address is inside allocated memory cell ce */
  64. I8s  IsInsideCell(ce, a)
  65. Pcells  ce;
  66. Ind  a;
  67. {
  68. #ifdef ERROR
  69.     if(a >= SoupSize || a < 0)
  70.     {   sprintf(mes[0],"IsInsideCell error: address %ld not in soup", a);
  71.         if (!hangup)
  72.             FEMessage(1);
  73.         else
  74.         {   sprintf(mes[1],"system being saved to disk");
  75.             FEMessage(2);
  76.         }
  77.         while(hangup) ;
  78.         WriteSoup(1);
  79.         exit(0);
  80.     }
  81. #endif
  82.     if((ce->mm.p <= a && a < ce->mm.p + ce->mm.s) || (ce->md.s > 0 &&
  83.        (ce->md.p <= a && a < ce->md.p + ce->md.s))) return 1; return 0;
  84. }
  85.  
  86. /* check to see if address is free, not allocated by any cell */
  87. I8s  IsFree(a)
  88. Ind  a;
  89. {   I32s  j;
  90.     I32s  mp;  /* index to element of FreeMem array */
  91.     Pmf   f;
  92.  
  93. #ifdef ERROR
  94.     if(a >= SoupSize || a < 0)
  95.     {   sprintf(mes[0],"IsFree error: address %ld not in soup", a);
  96.         if (!hangup)
  97.             FEMessage(1);
  98.         else
  99.         {   sprintf(mes[1],"system being saved to disk");
  100.             FEMessage(2);
  101.         }
  102.         while(hangup) ;
  103.         WriteSoup(1);
  104.         exit(0);
  105.     }
  106. #endif
  107.     f = FreeMem;     /* abbreviation for FreeMem */
  108.     mp = FreeMem->n; /* this is the first free block */
  109.     if(a < (f + mp)->p) return 0; j = 1;
  110.         /* find block whose end is equal or above a: */
  111.     while((f + mp)->p + (f + mp)->s < a)
  112.     {   mp = (f + mp)->n; j++;
  113.         if(j > FreeBlocks) return 0;
  114.     } /* is a in free block: */
  115.     if((f + mp)->p <= a && a < (f + mp)->p + (f + mp)->s) return 1;
  116.     return 0;
  117. }
  118.  
  119. void  WhichCell(a, ci, md) /* find cell with address a */
  120. Ind  a;      /* note: a must be in a cell!, call IsFree() before */
  121. I32s  *ci;   /* WhichCell() to find out if a is in a cell or not */
  122. I8s   *md;
  123. {   I32s  i;
  124.  
  125.     for(i = 2; i < CellsSize; i++)
  126.     {   if((cells + i)->ld && (cells + i)->mm.p <= a &&
  127.            ((cells + i)->mm.p + (cells + i)->mm.s - 1) >= a)
  128.         { *ci = i; *md = 'm'; break; }
  129.         if((cells + i)->ld && (cells + i)->md.p <= a &&
  130.            ((cells + i)->md.p + (cells + i)->md.s - 1) >= a)
  131.         { *ci = i; *md = 'd'; break; }
  132.     }
  133. }
  134.  
  135. Ind  MemAlloc(size)
  136. I32s  *size;
  137. {   I32s  j; /* counts the physical order of the free block we are indexing */
  138.     I32s  mb; /* memory block index */
  139.     I32s  pb; /* previous memory block index */
  140.     Ind   ti; /* temporary instruction location index, for return value */
  141.  
  142.     if(!*size || !FreeBlocks) { *size = 0; return 0; }
  143.     mb = FreeMem->n; /* this is the first free block */
  144.     pb = 0; /* this is SoupBot */
  145.     j = 1; /* counts the physical order of the free block we are indexing */
  146.     while((FreeMem + mb)->s < *size)  /* find big enough free block */
  147.     {   pb = mb;
  148.         mb = (FreeMem + mb)->n;
  149.         j++;
  150.         if(j > FreeBlocks) /* if memory is very fragmented, reap some: */
  151.         {   if(FreeMemCurrent > 3 * *size) fragment = 1;
  152.             *size = 0; return 0;
  153.         }
  154.     }
  155.     fragment = 0;
  156.     FreeMemCurrent -= *size;
  157.     if((FreeMem + mb)->s == *size)  /* free block is exactly the right size */
  158.     {   (FreeMem + pb)->n = (FreeMem + mb)->n;
  159.         (FreeMem + mb)->o = 0;
  160.         FreeBlocks--;
  161.         if((FreeMem + mb)->p > SoupSize)
  162.         {   sprintf(mes[0],"Tierra memalloc() error 1");
  163.             FEMessage(1);
  164.         }
  165.  
  166. #ifdef SOCKETS
  167.     TRepBirth( (FreeMem + mb)->p, *size );
  168. #endif
  169.  
  170.         return (FreeMem + mb)->p;
  171.     }
  172.     if((FreeMem + mb)->s > *size)  /* free block bigger than needed */
  173.     {   ti = (FreeMem + mb)->p;
  174.         if(ti > SoupSize)
  175.         {   sprintf(mes[0],"Tierra memalloc() error 2");
  176.             FEMessage(1);
  177.         }
  178.         (FreeMem + mb)->p += *size;
  179.         if((FreeMem + mb)->p > SoupSize)
  180.         {   sprintf(mes[0],"Tierra memalloc() error 3");
  181.             FEMessage(1);
  182.         }
  183.         (FreeMem + mb)->s -= *size;
  184.         if((FreeMem + mb)->s > SoupSize)
  185.         {   sprintf(mes[0],"Tierra memalloc() error 4");
  186.             FEMessage(1);
  187.         }
  188.  
  189. #ifdef SOCKETS
  190.     TRepBirth( ti, *size );
  191. #endif
  192.  
  193.         return ti;
  194.     }
  195.     return 0;
  196. }
  197.  
  198. void MemDealloc(p, size)
  199. Ind  p;
  200. I32s  size;
  201. {   I32s  i, j, a, b, ola, olb, bt;
  202.     Ind   bb, ab, at, pt;
  203.     Pmf   f, tf;
  204.  
  205. #ifdef SOCKETS
  206.     TRepDeath( p, size );
  207. #endif
  208.  
  209. #ifdef ERROR
  210.     if(p < 0L || !size || p >= SoupSize)
  211.     {   sprintf(mes[0],"Tierra memory deallocation error 1");
  212.         if (!hangup)
  213.             FEMessage(1);
  214.         else
  215.         {   sprintf(mes[1],"system being saved to disk");
  216.             FEMessage(2);
  217.         }
  218.         while(hangup) ;
  219.         WriteSoup(1);
  220.         exit(0);
  221.     }
  222. #endif
  223.     f = FreeMem;          /* abbreviation for FreeMem */
  224.     a = (f + SoupBot)->n; /* a will index free block above */
  225.     b = SoupBot;          /* b will index free block below */
  226.     j = 1L;
  227.     while(p >= (f + a)->p) /* find free block above block to be deallocated */
  228.     {   if(j > FreeBlocks) break;
  229.         b = a; a = (f + a)->n; j++;
  230.     }
  231. #ifdef ERROR
  232.     if(p > (f + a)->p)
  233.     {   sprintf(mes[0],"Tierra memory deallocation error 2");
  234.         if (!hangup)
  235.             FEMessage(1);
  236.         else
  237.         {   sprintf(mes[1],"system being saved to disk");
  238.             FEMessage(2);
  239.         }
  240.         while(hangup) ;
  241.         WriteSoup(1);
  242.         exit(0);
  243.     }
  244. #endif
  245.     bb = (f + b)->p;                   /* bb is address of bottom of b */
  246.         /* bt is address of top of b */
  247.     bt = (f + b)->p + (f + b)->s - 1L;
  248.     ab = (f + a)->p;                   /* ab is address of bottom of a */
  249.     at = (f + a)->p + (f + a)->s - 1L;  /* at is address of top of a */
  250.     pt = p + size - 1L;                 /* pt is address of top of p */
  251.     if(pt > SoupSize - 1L)
  252.     {   sprintf(mes[0],"Tierra deallocation inconsistency 0");
  253.         FEMessage(1);
  254.         pt = SoupSize - 1L;
  255.         size = pt - p + 1L;
  256.     }
  257.     if(bt > (p - 1L))
  258.     {   sprintf(mes[0],"Tierra deallocation inconsistency 1");
  259.         FEMessage(1);
  260.     }
  261.     if(pt > ab - 1L)
  262.     {   sprintf(mes[0],"Tierra deallocation inconsistency 2");
  263.         FEMessage(1);
  264.     }
  265.     if(bt >= p - 1L) olb = 1L; else olb = 0L;   /* overlap with block below */
  266.     if(pt >= ab - 1L) ola = 1L; else ola = 0L;  /* overlap with block above */
  267.         /* if block to be deallocated overlaps free blocks above and below: */
  268.     if(ola && olb)
  269.     {   if(b == SoupBot)
  270.         {   FreeMemCurrent += ab - p;
  271.             (f + a)->s = at - p + 1L;
  272.             (f + a)->p = p; return ;
  273.         }
  274.         if(a == SoupTop)
  275.         {   FreeMemCurrent += pt - bt;
  276.             (f + b)->s = pt - bb + 1L; return;
  277.         }
  278.         FreeMemCurrent += ab - bt - 1L;
  279.         (f + b)->s = at - bb + 1L;
  280.         (f + b)->n = (f + a)->n;
  281.             /* neutralize f + a: */
  282.         (f + a)->o = (I8s ) 0; (f + a)->p = (f + a)->s = 0L; (f + a)->n = a;
  283.         FreeBlocks--; return;
  284.     }       /* block to be deallocated overlaps only free block above: */
  285.     if(ola && a != SoupTop)
  286.     {   FreeMemCurrent += ab - p;
  287.         (f + a)->s = at - p + 1L;
  288.         (f + a)->p = p; return ;
  289.     }       /* block to be deallocated overlaps only free block below */
  290.     if(olb && b != SoupBot)
  291.     {   FreeMemCurrent += pt - bt;
  292.         (f + b)->s = pt - bb + 1L; return ;
  293.     }
  294.     j = 0L;  /* block to be deallocated does not overlap any free block */
  295.     while((FreeMem + j)->o)
  296.     {   if(++j == MaxFreeBlocks)
  297.         {   MaxFreeBlocks += 10L;
  298.             tf = (Pmf) threalloc((I8s Hp) FreeMem,
  299.                 (I32u) MaxFreeBlocks * sizeof(struct mem_fr));
  300.             if(tf == NULL)
  301.             {   sprintf(mes[0],"Tierra memalloc realloc error, exiting");
  302.                 if (!hangup)
  303.                     FEMessage(1);
  304.                 else
  305.                 {   sprintf(mes[1],"system being saved to disk");
  306.                     FEMessage(2);
  307.                 }
  308.                 while(hangup) ;
  309.                 WriteSoup(1);
  310.                 exit(0);
  311.             }
  312.             else f = FreeMem = tf;
  313.                 if (!hangup)
  314.                     FEMessage(1);
  315.                 else
  316.                 {   sprintf(mes[1],"system being saved to disk");
  317.                     FEMessage(2);
  318.                 }
  319. #ifdef __TURBOC__
  320.             sprintf(mes[0],"coreleft = %lu  MemDealloc (FreeMem)",coreleft());
  321.             FEMessage(1);
  322. #endif
  323.             sprintf(mes[0],"lmemalloc: realloc, MaxFreeBlocks = %ld",
  324.                 MaxFreeBlocks);
  325.             FEMessage(1);
  326.             for(i = MaxFreeBlocks - 10L; i < MaxFreeBlocks; i++)
  327.             {   (f + i)->n = i;
  328.                 (f + i)->o = (I8s ) 0; (f + i)->p = (f + i)->s = 0L;
  329.             }
  330.         }
  331.     }
  332.     (f + j)->o = (I8s ) 1;
  333.     (f + j)->n = a; (f + b)->n = j; FreeBlocks++;
  334.     (f + j)->p = p;
  335.     (f + j)->s = size;
  336.     FreeMemCurrent += size;
  337. }
  338.