/* * Copyright (c) 1986 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * * @(#)vm_proc.c 1.2 (2.11BSD GTE) 12/24/92 */ #include "param.h" #include "user.h" #include "proc.h" #include "text.h" #include "map.h" #include "kernel.h" /* * Change the size of the data+stack regions of the process. * If the size is shrinking, it's easy -- just release the extra core. * If it's growing, and there is core, just allocate it and copy the * image, taking care to reset registers to account for the fact that * the system's stack has moved. If there is no core, arrange for the * process to be swapped out after adjusting the size requirement -- when * it comes in, enough core will be allocated. After the expansion, the * caller will take care of copying the user's stack towards or away from * the data area. The data and stack segments are separated from each * other. The second argument to expand specifies which to change. The * stack segment will not have to be copied again after expansion. */ expand(newsize,segment) int newsize, segment; { register struct proc *p; register int i, n; int a1, a2; p = u.u_procp; if (segment == S_DATA) { n = p->p_dsize; p->p_dsize = newsize; a1 = p->p_daddr; if(n >= newsize) { n -= newsize; mfree(coremap, n, a1+newsize); return; } } else { n = p->p_ssize; p->p_ssize = newsize; a1 = p->p_saddr; if(n >= newsize) { n -= newsize; p->p_saddr += n; mfree(coremap, n, a1); /* * Since the base of stack is different, * segmentation registers must be repointed. */ sureg(); return; } } if (setjmp(&u.u_ssave)) { /* * If we had to swap, the stack needs moving up. */ if (segment == S_STACK) { a1 = p->p_saddr; i = newsize - n; a2 = a1 + i; /* * i is the amount of growth. Copy i clicks * at a time, from the top; do the remainder * (n % i) separately. */ while (n >= i) { n -= i; copy(a1+n, a2+n, i); } copy(a1, a2, n); } sureg(); return; } if (u.u_fpsaved == 0) { savfp(&u.u_fps); u.u_fpsaved = 1; } a2 = malloc(coremap, newsize); if (a2 == NULL) { if (segment == S_DATA) swapout(p, X_FREECORE, n, X_OLDSIZE); else swapout(p, X_FREECORE, X_OLDSIZE, n); p->p_flag |= SSWAP; swtch(); /* NOTREACHED */ } if (segment == S_STACK) { p->p_saddr = a2; /* * Make the copy put the stack at the top of the new area. */ a2 += newsize - n; } else p->p_daddr = a2; copy(a1, a2, n); mfree(coremap, n, a1); sureg(); }