xref: /csrg-svn/sys/kern/subr_rmap.c (revision 27)
1*27Sbill /*	subr_rmap.c	3.1	10/14/12	*/
2*27Sbill 
3*27Sbill #include "../h/param.h"
4*27Sbill #include "../h/systm.h"
5*27Sbill #include "../h/map.h"
6*27Sbill #include "../h/dir.h"
7*27Sbill #include "../h/user.h"
8*27Sbill #include "../h/proc.h"
9*27Sbill #include "../h/mtpr.h"
10*27Sbill #include "../h/text.h"
11*27Sbill 
12*27Sbill /*
13*27Sbill  * Allocate 'size' units from the given
14*27Sbill  * map. Return the base of the allocated
15*27Sbill  * space.
16*27Sbill  * In a map, the addresses are increasing and the
17*27Sbill  * list is terminated by a 0 size.
18*27Sbill  * The swap map unit is 512 bytes.
19*27Sbill  * Algorithm is first-fit.
20*27Sbill  */
21*27Sbill malloc(mp, size)
22*27Sbill struct map *mp;
23*27Sbill {
24*27Sbill 	register int a;
25*27Sbill 	register struct map *bp;
26*27Sbill 
27*27Sbill 	if (size <= 0)
28*27Sbill 		panic("malloc");
29*27Sbill 	for (bp=mp; bp->m_size; bp++) {
30*27Sbill 		if (bp->m_size >= size) {
31*27Sbill 			a = bp->m_addr;
32*27Sbill 			bp->m_addr += size;
33*27Sbill 			if ((bp->m_size -= size) == 0) {
34*27Sbill 				do {
35*27Sbill 					bp++;
36*27Sbill 					(bp-1)->m_addr = bp->m_addr;
37*27Sbill 				} while ((bp-1)->m_size = bp->m_size);
38*27Sbill 			}
39*27Sbill 			if (mp == swapmap && a % CLSIZE)
40*27Sbill 				panic("malloc swapmap");
41*27Sbill 			return(a);
42*27Sbill 		}
43*27Sbill 	}
44*27Sbill 	return(0);
45*27Sbill }
46*27Sbill 
47*27Sbill /*
48*27Sbill  * Free the previously allocated space aa
49*27Sbill  * of size units into the specified map.
50*27Sbill  * Sort aa into map and combine on
51*27Sbill  * one or both ends if possible.
52*27Sbill  */
53*27Sbill mfree(mp, size, a)
54*27Sbill struct map *mp;
55*27Sbill register int size, a;
56*27Sbill {
57*27Sbill 	register struct map *bp;
58*27Sbill 	register int t;
59*27Sbill 
60*27Sbill 	if (a <= 0)
61*27Sbill 		panic("mfree addr");
62*27Sbill 	if (size <= 0)
63*27Sbill 		panic("mfree size");
64*27Sbill 	bp = mp;
65*27Sbill 	for (; bp->m_addr<=a && bp->m_size!=0; bp++)
66*27Sbill 		continue;
67*27Sbill 	if (bp>mp && (bp-1)->m_addr+(bp-1)->m_size > a)
68*27Sbill 		panic("mfree begov");
69*27Sbill 	if (a+size > bp->m_addr && bp->m_size)
70*27Sbill 		panic("mfree endov");
71*27Sbill 	if (bp>mp && (bp-1)->m_addr+(bp-1)->m_size == a) {
72*27Sbill 		(bp-1)->m_size += size;
73*27Sbill 		if (a+size == bp->m_addr) {
74*27Sbill 			(bp-1)->m_size += bp->m_size;
75*27Sbill 			while (bp->m_size) {
76*27Sbill 				bp++;
77*27Sbill 				(bp-1)->m_addr = bp->m_addr;
78*27Sbill 				(bp-1)->m_size = bp->m_size;
79*27Sbill 			}
80*27Sbill 		}
81*27Sbill 	} else {
82*27Sbill 		if (a+size == bp->m_addr && bp->m_size) {
83*27Sbill 			bp->m_addr -= size;
84*27Sbill 			bp->m_size += size;
85*27Sbill 		} else if (size) {
86*27Sbill 			do {
87*27Sbill 				t = bp->m_addr;
88*27Sbill 				bp->m_addr = a;
89*27Sbill 				a = t;
90*27Sbill 				t = bp->m_size;
91*27Sbill 				bp->m_size = size;
92*27Sbill 				bp++;
93*27Sbill 			} while (size = t);
94*27Sbill 		}
95*27Sbill 	}
96*27Sbill 	if ((mp == kernelmap) && kmapwnt) {
97*27Sbill 		kmapwnt = 0;
98*27Sbill 		wakeup((caddr_t)kernelmap);
99*27Sbill 	}
100*27Sbill }
101