📄 vm_text.c
字号:
#ifndef lintstatic char *sccsid = "@(#)vm_text.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 Sep 88 -- jaa * Added error leg to rdwri() in xalloc for mips * * 14 Dec 87 -- jaa * Added new KM_ALLOC/KM_FREE macros * * 04 Sep 87 -- depp * A number of changes, all involved with removing the xflush_free_text() * algorithm, and replacing it with an array (g_hcmap) to hold the * indexes of remote cmap entries that are hashed. Xalloc() now * allocates the g_hcmap array if required. Xflush_free_text() was * removed and replaced by xflush_remote_hash(). * * 18 Aug 86 -- depp, rr * Added a couple of bugfixes and a mechanism for flushing the text * if the remote a.out file has been modified. * * 20 Feb 86 -- depp * Added a tracing flag (GTRC) in the gnode to indicate that one * or more processes are tracing this gnode. * * 15 Dec 86 -- depp * Fixed a number of small problems: * 1. In xalloc(), insured that 0407 processes return normally. * 2. In General, insured that memory unhashing (when a gnode * is written to or the file system is umounted, occurs in a * consistent manner by using the new macro X_FLUSH (text.h). * Currently, X_FLUSH works in the traditional manner, not * flushing local references, only remote. * 3. (from a previous submit) added macros to place/remove text * table entries on/from the free list -- X_QFREE/XDQFREE (text.h) * 4. Removed the obsolete (and unused) mlock/munlock/mwait routines. * * 30 Oct 86 -- depp * Fixed a problem with text table allocation (xalloc()). The x_flag * field of struct text has never been properly cleared on allocation. * This fact was masked until two changes were maded: 1. the use * of a paging threshold to determine whether to demand page a * process from an inode or read in the entire process prior to * execution. 2. The reworking of text management for local execution * of remote files. * * 11 Sep 86 -- koehler * added text management * * 29 Apr 86 -- depp * converted to locking macros from calls routines * * 02 Apr 86 -- depp * Added new parameter to "xalloc", a pointer to the a.out header * data. This data is now on the stack rather than in the "u" * structure. * * 11 Nov 85 -- depp * Removed all conditional compiles for System V IPC. * * 14 Oct 85 -- reilly * Modified user.h * * 18 Sep 85 -- depp * Added reset of x_lcount when new text struct created (xalloc) * *//* vm_text.c 6.1 83/07/29 */#ifdef GFSDEBUGextern short GFS[];#endif#include "../machine/pte.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/map.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/proc.h"#include "../h/buf.h"#include "../h/text.h"#include "../h/gnode.h"#include "../h/mount.h"#include "../h/seg.h"#include "../h/vm.h"#include "../h/cmap.h"#include "../h/exec.h"#include "../h/kmalloc.h"struct xfree freetext;/* * relinquish use of the shared text segment * of a process. */xfree(){ register struct proc *p = u.u_procp; register struct text *xp = p->p_textp; register struct gnode *gp; register int count; register int isbad; #ifdef mips XPRINTF(XPR_VM,"enter xfree",0,0,0,0);#endif mips if(xp == NULL) return; X_LOCK(xp); gp = xp->x_gptr; if((count = --xp->x_count) < 0) { cprintf("xfree: text 0x%x count bad\n", xp); panic("xfree"); } isbad = xp->x_flag & XBAD; if((count == 0) && (((gp->g_mode & GSVTX) == 0) || isbad)) {#ifdef mips /* what a hack ... the textbr is zeroed in xunlink */ /* but we need to free the memory the pte's point to */ /* so we save the pte's then free later */ struct pte *tpte = tptopte(p,0);#endif mips xunlink(p);#ifdef mips xp->x_rssize -= vmemfree(tpte, u.u_tsize);#else ultrix xp->x_rssize -= vmemfree(tptopte(p, 0), u.u_tsize);#endif !mips if (xp->x_rssize != 0) { panic("xfree rssize"); } while (xp->x_poip) sleep((caddr_t)&xp->x_poip, PSWP+1); gp->g_flag &= ~GTRC; vsxfree(xp, (long)xp->x_size); /* * place the text slot on the free text list * note that text slots are taken off the rear * and returned to the front */ X_QFREE(xp); if (isbad || (xp->x_flag & XTRC)) { X_FLUSH(xp); X_CLEAR(xp,gp); GRELE(gp); xp->x_flag &= ~XTRC; } X_UNLOCK(xp); } else { if ((count == 0) && (gp->g_flag & GTRC)) gp->g_flag &= ~GTRC; xp->x_flag &= ~XLOCK; xccdec(xp, p); } p->p_textp = NULL;}/* * Attach to a shared text segment. * If there is no shared text, just return. * If there is, hook up to it: * if it is not currently being used, it has to be read * in from the gnode (gp); the written bit is set to force it * to be written out as appropriate. * If it is being used, but is not currently in core, * a swap has to be done to get it back. */xalloc(gp, ep, pagi) register struct gnode *gp; register struct exec *ep; int pagi;{ register struct text *xp; register size_t ts; register struct proc *p = u.u_procp; int xbad_count = 0; extern int lbolt; #ifdef mips XPRINTF(XPR_VM,"enter xalloc",0,0,0,0);#endif mips /* This accounts for the 0407 case */ if(ep->a_text == 0) return(!NULL);again: if(gp->g_flag & GTEXT) { /* * We have text pointer lets check it * and run. */ xp = gp->g_textp; if (xp->x_gptr != gp) panic("Text Corruption gp != x_gptr"); /* If cleanup occuring, give it a second to complete */ if (xp->x_flag & XBAD) { if (xbad_count++) { uprintf("remote text modified and not yet cleaned up\n"); psignal(p, SIGKILL); return(NULL); } sleep(&lbolt, PZERO); goto again; } if ((xp->x_count > 0) || (gp->g_mode & GSVTX)) { if (xp->x_flag&XLOCK) { X_WAIT(xp); goto again; } X_LOCK(xp); xp->x_count++; p->p_textp = xp; (void) xlink(p); X_UNLOCK(xp); return(!NULL); } else { X_LOCK(xp); X_DQFREE(xp); } } else { /* * find a free text slot, if table is consumed, go * searching for a potentially free slot */ if((xp = freetext.xun_freeb) == (struct text *) &freetext) { tablefull("text"); uprintf("text table full\n"); psignal(p, SIGKILL); p->p_textp = NULL; return(NULL); } X_LOCK(xp); X_DQFREE(xp); if(xp->x_gptr) { struct gnode *xgp; xgp = xp->x_gptr; /* * avoid race condition between gp/xp locking */ if(xgp->g_flag & GLOCKED) { X_QFREE(xp); if(xp->x_freef == (struct text *) &freetext) { /* * we are here because we are * trying to commit the last * text slot but cannot get all * the resources to fulfill the * exec. * N.B. the code assumes that the * X_QFREE() puts things on the * front of the list */ tablefull("text (commit)"); uprintf("text table full\n"); psignal(p, SIGKILL); p->p_textp = NULL; X_UNLOCK(xp) return(NULL); } X_UNLOCK(xp); sleep(&lbolt, PZERO); /* avoid spinning */ goto again; } (void) GLOCK(xgp); X_FLUSH(xp); X_CLEAR(xp,xgp); gput(xgp); } xp->x_flag = 0; } xp->x_flag |= XLOAD; if (pagi) xp->x_flag |= XPAGI; ts = clrnd(btoc(ep->a_text)); xp->x_size = ts; if (p->p_flag & STRC) { gp->g_flag |= GTRC; } X_SET(xp,gp); if (vsxalloc(xp) == NULL) { swkill(p, "xalloc: no swap space"); /* * process is not executable, if this was a * reclaim, then leave enough * context so that text reclaim may be possible * else, simply unwind */ if ((gp->g_flag & GTEXT) == 0) { xp->x_flag = 0; xp->x_size = 0; p->p_textp = NULL; X_CLEAR(xp,gp); } X_QFREE(xp); X_UNLOCK(xp); return(NULL); } if(!(gp->g_flag & GTEXT)) { /* * if the flag is set then the gnode * is already allocated and the count * was already bumped. if not set the * flag and bump the count */ gp->g_flag |= GTEXT; gp->g_count++; if (X_DO_RHASH(xp)) { if (gp->g_hcmap_struct == 0) KM_ALLOC(gp->g_hcmap_struct, struct x_hcmap *, G_HCMAP_SIZE(xp), KM_TEMP, KM_CLEAR); gp->g_xcount++; } } xp->x_count = 1; xp->x_ccount = 0; xp->x_lcount = 0; xp->x_rssize = 0; p->p_textp = xp;#ifdef vax xlink(p);#endif vax#ifdef mips if (xlink(u.u_procp) == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -