📄 vm_text.c
字号:
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 + -