⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vm_text.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
		u.u_procp->p_textp = NULL;		xp->x_flag &= ~(XLOAD | XLOCK | XPAGI | XTRC);		xp->x_size = 0;		xp->x_count = 0;		X_CLEAR(xp,gp);		GRELE(gp);		vsxfree(xp, ts);		X_UNLOCK(xp);		swkill(u.u_procp, "xalloc: no memory for page tables");		return (0);	}#endif mips	if (pagi == 0) {		settprot(RW);		p->p_flag |= SKEEP;		u.u_error = rdwri(UIO_READ, gp, 			    (caddr_t)ctob(tptov(p, 0)),			    (int)ep->a_text,#ifdef vax			    (int)(ep->a_magic==0413 ? CLBYTES : sizeof (struct exec)),#endif vax#ifdef mips				(off_t)N_TXTOFF(ep->ex_f, ep->ex_o),#endif mips			    2, (int *)0);		if (u.u_error) {			swkill (p, "xalloc: error reading text");			X_UNLOCK(xp);			settprot(RO);			return(NULL);		}		p->p_flag &= ~SKEEP;	}	settprot(RO);	xp->x_flag |= XWRIT;	xp->x_flag &= ~XLOAD;	if (p->p_flag & STRC) 		gp->g_flag |= GTRC;	X_UNLOCK(xp);	return(!NULL);}/* * Decrement the in-core usage count of a shared text segment. * When it drops to zero, free the core space. */xccdec(xp, p)register struct text *xp;register struct proc *p;{#ifdef mips	XPRINTF(XPR_VM,"enter xccdec",0,0,0,0);#endif mips	if (xp==NULL || xp->x_ccount==0)		return;	X_LOCK(xp);	if (--xp->x_ccount == 0) {		if (xp->x_flag & XWRIT) {			vsswap(p, tptopte(p, 0), CTEXT, 0, xp->x_size,							(struct dmap *)0);			if (xp->x_flag & XPAGI)				swap(p, xp->x_ptdaddr, (caddr_t)tptopte(p, 0),					xp->x_size * sizeof (struct pte),					B_WRITE, B_PAGET, swapdev, 0);			xp->x_flag &= ~XWRIT;		} 		else {			xp->x_rssize -= vmemfree(tptopte(p, 0),xp->x_size);		}		if (xp->x_rssize != 0)			panic("text rssize");	}	xunlink(p);	X_UNLOCK(xp);}/* * free the swap image of all unused saved-text text segments * which are from device dev (used by umount system call). */xumount(dev)register dev;{	register struct text *xp;#ifdef mips	XPRINTF(XPR_VM,"enter xumount",0,0,0,0);#endif mips	for (xp = text; xp < textNTEXT; xp++) {		if (xp->x_gptr && dev == xp->x_gptr->g_dev) 				xuntext(xp);	}}/* * remove a shared text segment from the text table, if possible. */xrele(gp)register struct gnode *gp;{	register struct text *xp;#ifdef mips	XPRINTF(XPR_VM,"enter xrele",0,0,0,0);#endif mips	if((gp->g_flag & GTEXT) == 0)		return;	xp = gp->g_textp;	if (gp != xp->x_gptr)		panic("xrele");	xuntext(xp);}/* * remove text image from the text table. * the use count must be zero. */xuntext(xp)register struct text *xp;{	register struct gnode *gp;#ifdef mips	XPRINTF(XPR_VM,"enter xuntext",0,0,0,0);#endif mips	X_LOCK(xp);	if (xp->x_count) {		X_UNLOCK(xp);		return;	}	gp = xp->x_gptr;	xp->x_flag &= ~XLOCK;	if(gp->g_mode & GSVTX) 		vsxfree(xp, (long)xp->x_size); 	if ((xp->x_flag & XFREE) == 0) 	        X_QFREE(xp);	X_FLUSH(xp);	X_CLEAR(xp, gp);	GRELE(gp);}int xkillcnt = 0;/* * Invalidate the text associated with gp. * Kill all active processes. * Used for remote file systems that can't lock texts from writes. */xinval(gp)	register struct gnode *gp;{	register struct text *xp = gp->g_textp;	register struct proc *p;#ifdef mips	XPRINTF(XPR_VM,"enter xinval",0,0,0,0);#endif mips	/* kill them only if paging in from gnode */	if ((xp->x_flag & XPAGI) && (xp->x_gptr == gp)) {		for (p = xp->x_caddr; p; p = p->p_xlink) {			uprintf("pid %d killed due to text modification\n", p->p_pid);			psignal(p, SIGKILL);			p->p_flag |= SULOCK;			xkillcnt++;		}	}	if (xp->x_count == 0)		xuntext(xp);		/* all done */	else		xp->x_flag |= XBAD;	/* remove on last xfree */}/* * Add a process to those sharing a text segment by * getting the page tables and then linking to x_caddr. */xlink(p)register struct proc *p;{	register struct text *xp = p->p_textp;#ifdef mips	XPRINTF(XPR_VM,"enter xlink ",0,0,0,0);#endif mips	if (xp == 0)		return(0);#ifdef vax	vinitpt(p);#endif vax#ifdef mips        if (vinitpt(p) == 0)                return (0);#endif mips	p->p_xlink = xp->x_caddr;	xp->x_caddr = p;	xp->x_ccount++;	return(1);}xunlink(p)register struct proc *p;{	register struct text *xp = p->p_textp;	register struct proc *q;#ifdef mips	XPRINTF(XPR_VM,"enter xunlink",0,0,0,0);#endif mips	if (xp == 0)		return;	if (xp->x_caddr == p) {		xp->x_caddr = p->p_xlink;		p->p_xlink = 0;#ifdef mips                /*                 * free text page tables                 */                if ((xp->x_count == 0) || (xp->x_ccount == 0)) {if (xp->x_caddr != NULL)        panic("xunlink x_caddr !NULL");                        if (p->p_textpt) {				register int a;                                a = btokmx(p->p_textbr);                                (void) vmemfree(&Usrptmap[a], p->p_textpt);                                rmfree(kernelmap, (long)p->p_textpt, (long)a);                        } else {                                panic("xunlink no text page tables");                        }                }                p->p_textpt = 0;                p->p_textbr = (struct pte *)0;#endif mips		return;	}	for (q = xp->x_caddr; q->p_xlink; q = q->p_xlink)		if (q->p_xlink == p) {			q->p_xlink = p->p_xlink;			p->p_xlink = 0;#ifdef mips                        p->p_textpt = 0;                        p->p_textbr = (struct pte *)0;#endif mips			return;		}	panic("lost text");}/* * Replace p by q in a text incore linked list. * Used by vfork(), internally. */xrepl(p, q)register struct proc *p, *q;{	register struct text *xp = q->p_textp;#ifdef mips	XPRINTF(XPR_VM,"enter xrepl",0,0,0,0);#endif mips	if (xp == 0)		return;#ifdef vax	xunlink(p);	q->p_xlink = xp->x_caddr;	xp->x_caddr = q;#endif vax#ifdef mips	/*	 * actually replace p by q in the text incode linked list instead	 * of removing p and then adding q.	 */	XPRINTF(XPR_TEXT, "xrepl repl pid %d by pid %d", p->p_pid, q->p_pid,	    0, 0);	if (xp->x_caddr == p) {		xp->x_caddr = q;		q->p_xlink = p->p_xlink;		p->p_xlink = 0;	} else {		register struct proc *r;		for (r = xp->x_caddr; r->p_xlink; r = r->p_xlink) {			if (r->p_xlink == p) {				r->p_xlink = q;				q->p_xlink = p->p_xlink;				p->p_xlink = 0;				break;			}		}		if (r->p_xlink == NULL)			panic("xrepl: lost text");	}#endif mips}/* *  This routine will travel down the array containing the text's cmap indexes *  and insure that they are removed from the hash list.  If more than one text *  struct is associated with a given gnode, then the hash is flushed, but the *  array isn't deallocated. */xflush_remote_hash(xp)     register struct text *xp;{        register struct gnode *gp = xp->x_gptr;        register int *hcmap;	register int size_array = xp->x_size >> CLSIZELOG2;        register int j;	register struct cmap *c;	struct cmap *c1;#ifdef mips	XPRINTF(XPR_VM,"enter xflush_remote_hash",0,0,0,0);#endif mips	if (gp->g_hcmap_struct == NULL)	        panic("xflush_remote_hash: x_hcmap == NULL");	hcmap = gp->g_hcmap;        for (j = 0; j < size_array; j++, hcmap++) {	        if (*hcmap == 0)		        continue;				c = &cmap[*hcmap];		if (c->c_blkno)		        maunhash(c);	}	if (--gp->g_xcount > 0)	        return;	/* release the array */	if (gp->g_hcount != 0)	        panic("xflush_remote_hash: g_hcount != NULL");	KM_FREE(gp->g_hcmap_struct, KM_TEMP);	gp->g_hcmap_struct = NULL;}textinit(){		/* 	 * set up the doubly linked list of free text structures	 */		register struct text *xp;	#ifdef mips	XPRINTF(XPR_VM,"enter textinit",0,0,0,0);#endif mips	freetext.xun_freef = freetext.xun_freeb = (struct text *) &freetext;		for(xp = &text[ntext - 1]; xp >= text; xp--) 		X_QFREE(xp);}#ifdef mips/* * Detach a process from the in-core text. * External interface to xccdec, used when swapping out a process. */xdetach(xp, p)	register struct text *xp;	struct proc *p;{XPRINTF(XPR_VM,"enter xdetach",0,0,0,0);	if (xp && xp->x_ccount != 0) {		X_LOCK(xp);		xccdec(xp, p);		xunlink(p);		X_UNLOCK(xp);	}}#endif mips

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -