xref: /csrg-svn/sys/kern/subr_rmap.c (revision 307)
1*307Sbill /*	subr_rmap.c	3.3	06/24/80	*/
227Sbill 
327Sbill #include "../h/param.h"
427Sbill #include "../h/systm.h"
527Sbill #include "../h/map.h"
627Sbill #include "../h/dir.h"
727Sbill #include "../h/user.h"
827Sbill #include "../h/proc.h"
927Sbill #include "../h/mtpr.h"
1027Sbill #include "../h/text.h"
1127Sbill 
1227Sbill /*
1327Sbill  * Allocate 'size' units from the given
1427Sbill  * map. Return the base of the allocated
1527Sbill  * space.
1627Sbill  * In a map, the addresses are increasing and the
1727Sbill  * list is terminated by a 0 size.
1827Sbill  * The swap map unit is 512 bytes.
1927Sbill  * Algorithm is first-fit.
2027Sbill  */
2127Sbill malloc(mp, size)
2227Sbill struct map *mp;
2327Sbill {
2427Sbill 	register int a;
2527Sbill 	register struct map *bp;
26*307Sbill 	swblk_t first, rest;
2727Sbill 
28*307Sbill 	if (size <= 0 || mp == swapmap && size > DMMAX)
2927Sbill 		panic("malloc");
3027Sbill 	for (bp=mp; bp->m_size; bp++) {
3127Sbill 		if (bp->m_size >= size) {
32*307Sbill 			if (mp == swapmap &&
33*307Sbill 			    (first = DMMAX - bp->m_addr%DMMAX) < bp->m_size) {
34*307Sbill 				if (bp->m_size - first < size)
35*307Sbill 					continue;
36*307Sbill 				a = bp->m_addr + first;
37*307Sbill 				rest = bp->m_size - first - size;
38*307Sbill 				bp->m_size = first;
39*307Sbill 				if (rest)
40*307Sbill 					mfree(swapmap, rest, a+size);
41*307Sbill 				return (a);
42*307Sbill 			}
4327Sbill 			a = bp->m_addr;
4427Sbill 			bp->m_addr += size;
4527Sbill 			if ((bp->m_size -= size) == 0) {
4627Sbill 				do {
4727Sbill 					bp++;
4827Sbill 					(bp-1)->m_addr = bp->m_addr;
4927Sbill 				} while ((bp-1)->m_size = bp->m_size);
5027Sbill 			}
5127Sbill 			if (mp == swapmap && a % CLSIZE)
5227Sbill 				panic("malloc swapmap");
5327Sbill 			return(a);
5427Sbill 		}
5527Sbill 	}
5627Sbill 	return(0);
5727Sbill }
5827Sbill 
5927Sbill /*
6027Sbill  * Free the previously allocated space aa
6127Sbill  * of size units into the specified map.
6227Sbill  * Sort aa into map and combine on
6327Sbill  * one or both ends if possible.
6427Sbill  */
6527Sbill mfree(mp, size, a)
6627Sbill struct map *mp;
6727Sbill register int size, a;
6827Sbill {
6927Sbill 	register struct map *bp;
7027Sbill 	register int t;
7127Sbill 
7227Sbill 	if (a <= 0)
7327Sbill 		panic("mfree addr");
7427Sbill 	if (size <= 0)
7527Sbill 		panic("mfree size");
7627Sbill 	bp = mp;
7727Sbill 	for (; bp->m_addr<=a && bp->m_size!=0; bp++)
7827Sbill 		continue;
7927Sbill 	if (bp>mp && (bp-1)->m_addr+(bp-1)->m_size > a)
8027Sbill 		panic("mfree begov");
8127Sbill 	if (a+size > bp->m_addr && bp->m_size)
8227Sbill 		panic("mfree endov");
8327Sbill 	if (bp>mp && (bp-1)->m_addr+(bp-1)->m_size == a) {
8427Sbill 		(bp-1)->m_size += size;
8527Sbill 		if (a+size == bp->m_addr) {
8627Sbill 			(bp-1)->m_size += bp->m_size;
8727Sbill 			while (bp->m_size) {
8827Sbill 				bp++;
8927Sbill 				(bp-1)->m_addr = bp->m_addr;
9027Sbill 				(bp-1)->m_size = bp->m_size;
9127Sbill 			}
9227Sbill 		}
9327Sbill 	} else {
9427Sbill 		if (a+size == bp->m_addr && bp->m_size) {
9527Sbill 			bp->m_addr -= size;
9627Sbill 			bp->m_size += size;
9727Sbill 		} else if (size) {
9827Sbill 			do {
9927Sbill 				t = bp->m_addr;
10027Sbill 				bp->m_addr = a;
10127Sbill 				a = t;
10227Sbill 				t = bp->m_size;
10327Sbill 				bp->m_size = size;
10427Sbill 				bp++;
10527Sbill 			} while (size = t);
10627Sbill 		}
10727Sbill 	}
10827Sbill 	if ((mp == kernelmap) && kmapwnt) {
10927Sbill 		kmapwnt = 0;
11027Sbill 		wakeup((caddr_t)kernelmap);
11127Sbill 	}
11227Sbill }
113