Annotation of researchv10no/sys/os/rmap.c, revision 1.1

1.1     ! root        1: #include "sys/param.h"
        !             2: #include "sys/map.h"
        !             3: #include "sys/dmap.h"
        !             4: 
        !             5: /*
        !             6:  * resource maps, for dishing out pieces of things
        !             7:  * that can be described by integers
        !             8:  *
        !             9:  * to use them:
        !            10:  * declare struct map xxmap[N]
        !            11:  * where N is the largest number of pieces free parts of the resource may be
        !            12:  * fragmented into
        !            13:  *     rminit to set up the map
        !            14:  *     rmalloc to allocate pieces
        !            15:  *     rmfree to give them back
        !            16:  *
        !            17:  * the map is an array of (size, address) pairs,
        !            18:  * ordered by address.
        !            19:  * allocation is first-fit.
        !            20:  * if the map becomes very fragmented,
        !            21:  * and therefore too big to fit,
        !            22:  * some of the resource may be lost.
        !            23:  * the first piece of the map is magic, and holds an end-marker;
        !            24:  * the last piece is kept empty
        !            25:  */
        !            26: 
        !            27: /*
        !            28:  * initialize struct map mp[mapsize]
        !            29:  * to hold size pieces starting at addr
        !            30:  */
        !            31: rminit(mp, mapsize, size, addr)
        !            32:        register struct map *mp;
        !            33:        int mapsize;
        !            34:        int size, addr;
        !            35: {
        !            36: 
        !            37:        if (mapsize < 3)
        !            38:                panic("rminit");
        !            39:        mp->m_end = mapsize - 1;        /* leave an end-marker */
        !            40:        mp++;
        !            41:        mp->m_size = size;
        !            42:        mp->m_addr = addr;
        !            43:        mp++;
        !            44:        mp->m_size = 0;
        !            45:        mp->m_addr = 0;
        !            46: }
        !            47: 
        !            48: rmalloc(mp, size)
        !            49:        register struct map *mp;
        !            50: {
        !            51:        register int addr;
        !            52:        register struct map *bp;
        !            53: 
        !            54:        if (size <= 0)
        !            55:                panic("rmalloc");
        !            56:        for (bp = mp+1; bp->m_size; bp++) {
        !            57:                if (bp->m_size >= size) {
        !            58:                        addr = bp->m_addr;
        !            59:                        bp->m_addr += size;
        !            60:                        if ((bp->m_size -= size) == 0) {
        !            61:                                do {
        !            62:                                        bp++;
        !            63:                                        (bp-1)->m_addr = bp->m_addr;
        !            64:                                } while ((bp-1)->m_size = bp->m_size);
        !            65:                        }
        !            66:                        return (addr);
        !            67:                }
        !            68:        }
        !            69:        return (0);
        !            70: }
        !            71: 
        !            72: /*
        !            73:  * special version of rmalloc, to handle swapmap silliness
        !            74:  * historical; get rid of it later
        !            75:  */
        !            76: srmalloc(mp, size)
        !            77:        register struct map *mp;
        !            78: {
        !            79:        register int addr;
        !            80:        register struct map *bp;
        !            81:        swblk_t first, rest;
        !            82: 
        !            83:        if (size <= 0 || size > dmmax)
        !            84:                panic("rmalloc");
        !            85:        for (bp = mp+1; bp->m_size; bp++) {
        !            86:                if (bp->m_size >= size) {
        !            87:                        /*
        !            88:                         * If allocating from swapmap,
        !            89:                         * then have to respect interleaving
        !            90:                         * boundaries.
        !            91:                         */
        !            92:                        first = dmmax - bp->m_addr%dmmax;
        !            93:                        if (first<bp->m_size && first<size) {
        !            94:                                if (bp->m_size - first < size)
        !            95:                                        continue;
        !            96:                                addr = bp->m_addr + first;
        !            97:                                rest = bp->m_size - first - size;
        !            98:                                bp->m_size = first;
        !            99:                                if (rest)
        !           100:                                        rmfree(mp, rest, addr+size);
        !           101:                                return (addr);
        !           102:                        }
        !           103:                        addr = bp->m_addr;
        !           104:                        bp->m_addr += size;
        !           105:                        if ((bp->m_size -= size) == 0) {
        !           106:                                do {
        !           107:                                        bp++;
        !           108:                                        (bp-1)->m_addr = bp->m_addr;
        !           109:                                } while ((bp-1)->m_size = bp->m_size);
        !           110:                        }
        !           111:                        if (addr % CLSIZE)
        !           112:                                panic("rmalloc swapmap");
        !           113:                        return (addr);
        !           114:                }
        !           115:        }
        !           116:        return (0);
        !           117: }
        !           118: 
        !           119: /*
        !           120:  * free a chunk
        !           121:  * hack: if we need to create a new map entry
        !           122:  * and there aren't any left,
        !           123:  * discard the next-to-last,
        !           124:  * as the last one tends to be larger
        !           125:  */
        !           126: rmfree(mp, size, addr)
        !           127:        register struct map *mp;
        !           128:        register int size, addr;
        !           129: {
        !           130:        register struct map *bp, *xp;
        !           131: 
        !           132:        if (addr <= 0 || size <= 0)
        !           133:                panic("rmfree");
        !           134:        for (bp = mp + 1; bp->m_addr <= addr && bp->m_size != 0; bp++)
        !           135:                continue;
        !           136:        /*
        !           137:         * can merge into previous block, or both sides?
        !           138:         */
        !           139:        xp = bp - 1;
        !           140:        if (bp > mp + 1 && xp->m_addr + xp->m_size >= addr) {
        !           141:                if (xp->m_addr + xp->m_size > addr)
        !           142:                        panic("dup rmfree");
        !           143:                xp->m_size += size;
        !           144:                if (bp->m_addr && addr+size >= bp->m_addr) {
        !           145:                        if (addr+size > bp->m_addr)
        !           146:                                panic("dup rmfree");
        !           147:                        xp->m_size += bp->m_size;
        !           148:                        while (bp->m_size) {
        !           149:                                bp[0] = bp[1];
        !           150:                                bp++;
        !           151:                        }
        !           152:                }
        !           153:                return;
        !           154:        }
        !           155:        /*
        !           156:         * can merge into next block?
        !           157:         */
        !           158:        if (addr+size >= bp->m_addr && bp->m_size) {
        !           159:                if (addr+size > bp->m_addr)
        !           160:                        panic("dup rmfree");
        !           161:                bp->m_addr -= size;
        !           162:                bp->m_size += size;
        !           163:                return;
        !           164:        }
        !           165:        /*
        !           166:         * can't merge; make a new entry before bp
        !           167:         */
        !           168:        xp = bp;
        !           169:        while (bp->m_size)
        !           170:                bp++;
        !           171:        if (bp-mp >= mp->m_end) {       /* overflow? */
        !           172:                printf("rmfree: map %x overflow, lost %d-%d\n", mp,
        !           173:                        bp[-2].m_addr, bp[-2].m_size+bp[-2].m_addr);
        !           174:                bp[-2] = bp[-1];
        !           175:                bp[-1] = bp[0];
        !           176:                bp--;
        !           177:        }
        !           178:        do {
        !           179:                bp[1] = bp[0];
        !           180:                bp--;
        !           181:        } while (bp >= xp);
        !           182:        xp->m_size = size;
        !           183:        xp->m_addr = addr;
        !           184: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.