|
|
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: if ((first = dmmax - bp->m_addr%dmmax) < bp->m_size) {
93: if (bp->m_size - first < size)
94: continue;
95: addr = bp->m_addr + first;
96: rest = bp->m_size - first - size;
97: bp->m_size = first;
98: if (rest)
99: rmfree(mp, rest, addr+size);
100: return (addr);
101: }
102: addr = bp->m_addr;
103: bp->m_addr += size;
104: if ((bp->m_size -= size) == 0) {
105: do {
106: bp++;
107: (bp-1)->m_addr = bp->m_addr;
108: } while ((bp-1)->m_size = bp->m_size);
109: }
110: if (addr % CLSIZE)
111: panic("rmalloc swapmap");
112: return (addr);
113: }
114: }
115: return (0);
116: }
117:
118: /*
119: * free a chunk
120: * hack: if we need to create a new map entry
121: * and there aren't any left,
122: * discard the next-to-last,
123: * as the last one tends to be larger
124: */
125: rmfree(mp, size, addr)
126: register struct map *mp;
127: register int size, addr;
128: {
129: register struct map *bp, *xp;
130:
131: if (addr <= 0 || size <= 0)
132: panic("rmfree");
133: for (bp = mp + 1; bp->m_addr <= addr && bp->m_size != 0; bp++)
134: continue;
135: /*
136: * can merge into previous block, or both sides?
137: */
138: xp = bp - 1;
139: if (bp > mp + 1 && xp->m_addr + xp->m_size >= addr) {
140: if (xp->m_addr + xp->m_size > addr)
141: panic("dup rmfree");
142: xp->m_size += size;
143: if (bp->m_addr && addr+size >= bp->m_addr) {
144: if (addr+size > bp->m_addr)
145: panic("dup rmfree");
146: xp->m_size += bp->m_size;
147: while (bp->m_size) {
148: bp[0] = bp[1];
149: bp++;
150: }
151: }
152: return;
153: }
154: /*
155: * can merge into next block?
156: */
157: if (addr+size >= bp->m_addr && bp->m_size) {
158: if (addr+size > bp->m_addr)
159: panic("dup rmfree");
160: bp->m_addr -= size;
161: bp->m_size += size;
162: return;
163: }
164: /*
165: * can't merge; make a new entry before bp
166: */
167: xp = bp;
168: while (bp->m_size)
169: bp++;
170: if (bp-mp >= mp->m_end) { /* overflow? */
171: printf("rmfree: map %x overflow, lost %d-%d\n", mp,
172: bp[-2].m_addr, bp[-2].m_size+bp[-2].m_addr);
173: bp[-2] = bp[-1];
174: bp[-1] = bp[0];
175: bp--;
176: }
177: do {
178: bp[1] = bp[0];
179: bp--;
180: } while (bp >= xp);
181: xp->m_size = size;
182: xp->m_addr = addr;
183: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.