|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.