new naming convention
[unix-history] / usr / src / sys / kern / subr_rmap.c
index a841721..2aeb82c 100644 (file)
@@ -1,13 +1,18 @@
-/*     subr_rmap.c     4.4     81/03/09        */
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)subr_rmap.c 7.3 (Berkeley) %G%
+ */
 
 
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/map.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/proc.h"
-#include "../h/mtpr.h"
-#include "../h/text.h"
+#include "param.h"
+#include "systm.h"
+#include "map.h"
+#include "user.h"
+#include "proc.h"
+#include "text.h"
+#include "kernel.h"
 
 /*
  * Resource map handling routines.
 
 /*
  * Resource map handling routines.
@@ -43,7 +48,7 @@
  */
 rminit(mp, size, addr, name, mapsize)
        register struct map *mp;
  */
 rminit(mp, size, addr, name, mapsize)
        register struct map *mp;
-       int size, addr;
+       long size, addr;
        char *name;
        int mapsize;
 {
        char *name;
        int mapsize;
 {
@@ -66,6 +71,8 @@ rminit(mp, size, addr, name, mapsize)
         */
        ep->m_size = size;
        ep->m_addr = addr;
         */
        ep->m_size = size;
        ep->m_addr = addr;
+       (++ep)->m_size = 0;
+       ep->m_addr = 0;
 }
 
 /*
 }
 
 /*
@@ -79,15 +86,17 @@ rminit(mp, size, addr, name, mapsize)
  * This routine knows about the interleaving of the swapmap
  * and handles that.
  */
  * This routine knows about the interleaving of the swapmap
  * and handles that.
  */
+long
 rmalloc(mp, size)
        register struct map *mp;
 rmalloc(mp, size)
        register struct map *mp;
+       long size;
 {
        register struct mapent *ep = (struct mapent *)(mp+1);
        register int addr;
        register struct mapent *bp;
        swblk_t first, rest;
 
 {
        register struct mapent *ep = (struct mapent *)(mp+1);
        register int addr;
        register struct mapent *bp;
        swblk_t first, rest;
 
-       if (size <= 0 || mp == swapmap && size > DMMAX)
+       if (size <= 0 || mp == swapmap && size > dmmax)
                panic("rmalloc");
        /*
         * Search for a piece of the resource map which has enough
                panic("rmalloc");
        /*
         * Search for a piece of the resource map which has enough
@@ -100,8 +109,8 @@ rmalloc(mp, size)
                         * then have to respect interleaving
                         * boundaries.
                         */
                         * then have to respect interleaving
                         * boundaries.
                         */
-                       if (mp == swapmap &&
-                           (first = DMMAX - bp->m_addr%DMMAX) < bp->m_size) {
+                       if (mp == swapmap && nswdev > 1 &&
+                           (first = dmmax - bp->m_addr%dmmax) < bp->m_size) {
                                if (bp->m_size - first < size)
                                        continue;
                                addr = bp->m_addr + first;
                                if (bp->m_size - first < size)
                                        continue;
                                addr = bp->m_addr + first;
@@ -141,7 +150,7 @@ rmalloc(mp, size)
  */
 rmfree(mp, size, addr)
        struct map *mp;
  */
 rmfree(mp, size, addr)
        struct map *mp;
-       register int size, addr;
+       long size, addr;
 {
        struct mapent *firstbp;
        register struct mapent *bp;
 {
        struct mapent *firstbp;
        register struct mapent *bp;
@@ -247,3 +256,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 + 1 >= 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);
+}