Annotation of researchv10no/sys/os/rmap.c, revision 1.1.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.