put vax headers in their place
[unix-history] / usr / src / sys / kern / subr_rmap.c
index 3c3620a..5180070 100644 (file)
@@ -1,4 +1,4 @@
-/*     subr_rmap.c     4.3     %G%     */
+/*     subr_rmap.c     4.6     82/10/10        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -6,7 +6,6 @@
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/proc.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/proc.h"
-#include "../h/mtpr.h"
 #include "../h/text.h"
 
 /*
 #include "../h/text.h"
 
 /*
@@ -247,3 +246,88 @@ done:
 badrmfree:
        panic("bad rmfree");
 }
 badrmfree:
        panic("bad rmfree");
 }
+
+/*
+ * Allocate 'size' units from the given map, starting at address 'addr'.
+ * Return 'addr' if successful, 0 if not.
+ * This may cause the creation or destruction of a resource map segment.
+ *
+ * This routine will return failure status if there is not enough room
+ * for a required additional map segment.
+ *
+ * An attempt to use this on 'swapmap' will result in
+ * a failure return.  This is due mainly to laziness and could be fixed
+ * to do the right thing, although it probably will never be used.
+ */
+rmget(mp, size, addr)
+       register struct map *mp;
+{
+       register struct mapent *ep = (struct mapent *)(mp+1);
+       register struct mapent *bp, *bp2;
+
+       if (size <= 0)
+               panic("rmget");
+       if (mp == swapmap)
+               return (0);
+       /*
+        * Look for a map segment containing the requested address.
+        * If none found, return failure.
+        */
+       for (bp = ep; bp->m_size; bp++)
+               if (bp->m_addr <= addr && bp->m_addr + bp->m_size > addr)
+                       break;
+       if (bp->m_size == 0)
+               return (0);
+
+       /*
+        * If segment is too small, return failure.
+        * If big enough, allocate the block, compressing or expanding
+        * the map as necessary.
+        */
+       if (bp->m_addr + bp->m_size < addr + size)
+               return (0);
+       if (bp->m_addr == addr)
+               if (bp->m_addr + bp->m_size == addr + size) {
+                       /*
+                        * Allocate entire segment and compress map
+                        */
+                       bp2 = bp;
+                       while (bp2->m_size) {
+                               bp2++;
+                               (bp2-1)->m_addr = bp2->m_addr;
+                               (bp2-1)->m_size = bp2->m_size;
+                       }
+               } else {
+                       /*
+                        * Allocate first part of segment
+                        */
+                       bp->m_addr += size;
+                       bp->m_size -= size;
+               }
+       else
+               if (bp->m_addr + bp->m_size == addr + size) {
+                       /*
+                        * Allocate last part of segment
+                        */
+                       bp->m_size -= size;
+               } else {
+                       /*
+                        * Allocate from middle of segment, but only
+                        * if table can be expanded.
+                        */
+                       for (bp2=bp; bp2->m_size; bp2++)
+                               ;
+                       if (bp2 == mp->m_limit)
+                               return (0);
+                       while (bp2 > bp) {
+                               (bp2+1)->m_addr = bp2->m_addr;
+                               (bp2+1)->m_size = bp2->m_size;
+                               bp2--;
+                       }
+                       (bp+1)->m_addr = addr + size;
+                       (bp+1)->m_size =
+                           bp->m_addr + bp->m_size - (addr + size);
+                       bp->m_size = addr - bp->m_addr;
+               }
+       return (addr);
+}