📄 vm_proc.c
字号:
#ifndef lintstatic char *sccsid = "@(#)vm_proc.c 4.1 (ULTRIX) 7/2/90";#endif lint/*********************************************************************** * * * Copyright (c) 1986 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * **********************************************************************//*---------------------------------------------------------------------- * Modification History * * 14 Jul 87 -- depp * insured that vfork() shared memory semantics were handled properly * in vpassvm(). * * 15 Dec 86 -- depp * Added fix to shared memory handling, in regards to a process' SM * page table swapping space. * * 11 Sep 86 -- koehler * moved a few things into registers, added more informative print * * 29 Apr 86 -- depp * converted to locking macros from calls routines * * 11 Nov 85 -- depp * Removed all conditional compiles for System V IPC. * * 19 Jul 85 -- depp * fixed bug in SMEXPAND routine, if change < 0, then base += change, * NOT base -= change * * 05-May-85 - Larry Cohen * loop up to u_omax instead of NOFILE * * 001 - March 11 1985 - Larry Cohen * disable mapped in files so NOFILE can be larger than 32 * * 11 Mar 85 -- depp * Added System V shared memory support * * 19 Dec 84 -- jrs * Changed setjmp's to savectx for swap recovery fixes * Derived from 4.2 BSD, labeled: * vm_proc.c 6.1 83/07/29 * * *---------------------------------------------------------------------- */#include "../machine/pte.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/proc.h"#include "../h/map.h"#include "../h/cmap.h"#include "../h/text.h"#include "../h/vm.h"#include "../h/file.h"#ifdef vax#include "../vax/mtpr.h"#endif vax#include "../machine/cpu.h"#include "../h/kmalloc.h"#include "../h/ipc.h"#include "../h/shm.h"extern struct sminfo sminfo;/* * Get virtual memory resources for a new process. * Called after page tables are allocated, but before they * are initialized, we initialize the memory management registers, * and then expand the page tables for the data and stack segments * creating zero fill pte's there. Text pte's are set up elsewhere. * * SHOULD FREE EXTRA PAGE TABLE PAGES HERE OR SOMEWHERE. */vgetvm(ts, ds, ss) size_t ts, ds, ss;{#ifdef mips XPRINTF(XPR_VM,"enter vgetvm",0,0,0,0);#endif mips#ifdef vax u.u_pcb.pcb_p0lr = AST_NONE; setp0lr(ts); setp1lr(P1PAGES - HIGHPAGES);#endif vax#ifdef mips u.u_procp->p_dsize = 0; u.u_procp->p_ssize = 0;#endif mips u.u_procp->p_tsize = ts; u.u_tsize = ts; expand((int)ss, 1); expand((int)ds, 0);}/* * Release the virtual memory resources (memory * pages, and swap area) associated with the current process. * Caller must not be swappable. Used at exit or execl. */vrelvm(){ register struct proc *p = u.u_procp; int prss_orig; #ifdef mips XPRINTF(XPR_VM,"enter vrelvm",0,0,0,0);#endif mips /* * Release memory; text first, shared segments then data/stack pages. */ xfree(); if (p->p_smbeg) { /* SHMEM */ if(p->p_sm == (struct p_sm *) NULL){ panic("vrelvm: p_sm"); } smclean(); } prss_orig = p->p_rssize; /* save it */ p->p_rssize -= vmemfree(dptopte(p, 0), p->p_dsize); p->p_rssize -= vmemfree(sptopte(p, p->p_ssize - 1), p->p_ssize); if (p->p_rssize != 0) { printf("p = %x, p_rssize = %d, p_textp = %x, prss_orig = %d\n", p,p->p_rssize,p->p_textp,prss_orig); panic("vrelvm rss"); } /* * Wait for all page outs to complete, then * release swap space. */ p->p_swrss = 0; while (p->p_poip) sleep((caddr_t)&p->p_poip, PSWP+1); (void) vsexpand((size_t)0, &u.u_dmap, 1); (void) vsexpand((size_t)0, &u.u_smap, 1); p->p_tsize = 0; p->p_dsize = 0; p->p_ssize = 0; u.u_tsize = 0; u.u_dsize = 0; u.u_ssize = 0;}/* * Pass virtual memory resources from p to q. * P's u. area is up, q's is uq. Used internally * when starting/ending a vfork(). */vpassvm(p, q, up, uq, umap) register struct proc *p, *q; register struct user *up, *uq; struct pte *umap;{ int i; register struct p_sm *p_smp, *q_smp; /* SHMEM */#ifdef mips XPRINTF(XPR_VM,"enter vpassvm",0,0,0,0);#endif mips /* * Pass fields related to vm sizes. */ uq->u_tsize = q->p_tsize = p->p_tsize; up->u_tsize = p->p_tsize = 0; uq->u_dsize = q->p_dsize = p->p_dsize; up->u_dsize = p->p_dsize = 0; uq->u_ssize = q->p_ssize = p->p_ssize; up->u_ssize = p->p_ssize = 0; /* * Pass proc table paging statistics. */ q->p_swrss = p->p_swrss; p->p_swrss = 0; q->p_rssize = p->p_rssize; p->p_rssize = 0; q->p_poip = p->p_poip; p->p_poip = 0; /* * Relink text segment. */ q->p_textp = p->p_textp; xrepl(p, q); p->p_textp = 0; /* relink all shared memory segments SHMEM */ uq->u_smsize = q->p_smsize = p->p_smsize; up->u_smsize = p->p_smsize = 0; q->p_smend = p->p_smend; p->p_smend = 0;#ifdef mips q->p_smcount = p->p_smcount; p->p_smcount = 0;#endif mips q->p_smbeg = 0; if(p->p_sm == (struct p_sm *) NULL) { q->p_sm == (struct p_sm *) NULL; } else { if(sminfo.smseg == 0) { panic("vpassvm: parent has smem, smseg == 0"); } KM_ALLOC(q->p_sm, struct p_sm *, SIZEOF_PSM, KM_SHMSEG, KM_CLEAR); if(q->p_sm == (struct p_sm *) NULL) { panic("vpassvm: alloc q->p_sm"); } /* relink all shared memory segments SHMEM */ p_smp = p->p_sm; q_smp = q->p_sm; for(i = 0; i < sminfo.smseg; i++, p_smp++, q_smp++){ q_smp->sm_p = p_smp->sm_p; smrepl(p, q, i); p_smp->sm_p = NULL;#ifdef vax q_smp->sm_spte = p_smp->sm_spte; p_smp->sm_spte = 0;#endif vax#ifdef mips q_smp->sm_saddr = p_smp->sm_saddr; p_smp->sm_saddr = 0; q_smp->sm_eaddr = p_smp->sm_eaddr; p_smp->sm_eaddr = 0;#endif mips q_smp->sm_pflag = p_smp->sm_pflag; p_smp->sm_pflag = 0; q_smp->sm_lock = p_smp->sm_lock; p_smp->sm_lock = 0; } q->p_smbeg = p->p_smbeg; p->p_smbeg = 0; KM_FREE(p->p_sm, KM_SHMSEG); p->p_sm = (struct p_sm *) NULL; } /* * Pass swap space maps. */ uq->u_dmap = up->u_dmap; up->u_dmap = zdmap; uq->u_smap = up->u_smap; up->u_smap = zdmap; /* * Pass u. paging statistics. */ uq->u_outime = up->u_outime; up->u_outime = 0; uq->u_ru = up->u_ru; bzero((caddr_t)&up->u_ru, sizeof (struct rusage)); uq->u_cru = up->u_cru; bzero((caddr_t)&up->u_cru, sizeof (struct rusage)); /* * And finally, pass the page tables themselves. * On return we are running on the other set of * page tables, but still with the same u. area. */ vpasspt(p, q, up, uq, umap);}#ifdef vax/* * Change the size of the data+stack regions of the process. * If the size is shrinking, it's easy-- just release virtual memory. * If it's growing, initalize new page table entries as * 'zero fill on demand' pages. */expand(change, region) register int change; int region;{ register struct proc *p; register struct pte *base, *p0, *p1; struct pte proto; int p0lr, p1lr; struct pte *base0; size_t ods, oss; int size; u_int v; p = u.u_procp; if (change == 0) return; if (change % CLSIZE) panic("expand");#ifdef PGINPROF vmsizmon();#endif /* * Update the sizes to reflect the change. Note that we may * swap as a result of a ptexpand, but this will work, because * the routines which swap out will get the current text and data * sizes from the arguments they are passed, and when the process * resumes the lengths in the proc structure are used to * build the new page tables. */ ods = u.u_dsize; oss = u.u_ssize; if (region == 0) { v = dptov(p, p->p_dsize); p->p_dsize += change; u.u_dsize += change; } else { p->p_ssize += change; v = sptov(p, p->p_ssize-1); u.u_ssize += change; } /* * Compute the end of the text+data regions and the beginning * of the stack region in the page tables, * and expand the page tables if necessary. */ p0 = u.u_pcb.pcb_p0br + (u.u_pcb.pcb_p0lr&~AST_CLR); p1 = u.u_pcb.pcb_p1br + (u.u_pcb.pcb_p1lr&~PME_CLR); if (change > p1 - p0) ptexpand(clrnd(ctopt(change - (p1 - p0))), ods, oss, p->p_smsize); /* SHMEM */ /* PTEXPAND SHOULD GIVE BACK EXCESS PAGE TABLE PAGES */ /* * Compute the base of the allocated/freed region. */ p0lr = u.u_pcb.pcb_p0lr&~AST_CLR; p1lr = u.u_pcb.pcb_p1lr&~PME_CLR; if (region == 0) base = u.u_pcb.pcb_p0br + p0lr + (change > 0 ? 0 : change); else base = u.u_pcb.pcb_p1br + p1lr - (change > 0 ? change : 0); /* * If we shrunk, give back the virtual memory. */ if (change < 0) p->p_rssize -= vmemfree(base, -change); /* * Update the processor length registers and copies in the pcb. */ if (region == 0) setp0lr(p0lr + change); else setp1lr(p1lr - change); /* * If shrinking, clear pte's, otherwise * initialize zero fill on demand pte's. */ *(int *)&proto = PG_UW; if (change < 0) change = -change; else { proto.pg_fod = 1; ((struct fpte *)&proto)->pg_fileno = PG_FZERO; cnt.v_nzfod += change; } base0 = base; size = change; while (--change >= 0) *base++ = proto; /* * We changed mapping for the current process, * so must update the hardware translation */ newptes(base0, v, size);}/* SMEXPAND - shared-memory specific expand routine. Change the *//* size of the data region of the current process. If the *//* size is shrinking, it's easy -- just release virtual *//* memory. If it's growing, initialize new page table *//* entries as 'zero fill on demand' pages. *//* *//* This routine is only called from kern_mman.c/obreak. *//* It provides the same function as EXPAND but: *//* - it only expands data region *//* - it does not grow the page table *//* - it does not reset P0LR *//* LeRoy Fundingsland 3/21/85 DEC SHMEM */smexpand(change) register int change;{ register struct proc *p; register struct pte *base, *base0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -