Annotation of researchv10no/sys/vm/vmproc.c, revision 1.1

1.1     ! root        1: /*     vmproc.c        4.5     81/03/08        */
        !             2: 
        !             3: #include "sys/param.h"
        !             4: #include "sys/systm.h"
        !             5: #include "sys/user.h"
        !             6: #include "sys/proc.h"
        !             7: #include "sys/mtpr.h"
        !             8: #include "sys/pte.h"
        !             9: #include "sys/map.h"
        !            10: #include "sys/cmap.h"
        !            11: #include "sys/text.h"
        !            12: #include "sys/inode.h"
        !            13: #include "sys/vm.h"
        !            14: 
        !            15: struct pte *Forkmap;
        !            16: struct user *forkutl;
        !            17: 
        !            18: struct dmap zdmap;             /* well, it has to be somewhere */
        !            19: 
        !            20: /*
        !            21:  * Get virtual memory resources for a new process.
        !            22:  * Called after page tables are allocated, but before they
        !            23:  * are initialized, we initialize the memory management registers,
        !            24:  * and then expand the page tables for the data and stack segments
        !            25:  * creating zero fill pte's there.  Text pte's are set up elsewhere.
        !            26:  *
        !            27:  * SHOULD FREE EXTRA PAGE TABLE PAGES HERE OR SOMEWHERE.
        !            28:  */
        !            29: vgetvm(ts, ds, ss)
        !            30:        clicks_t ts, ds, ss;
        !            31: {
        !            32: 
        !            33:        mtpr(P0LR, ts);
        !            34:        u.u_pcb.pcb_p0lr = ts | AST_NONE;
        !            35:        mtpr(P1LR, P1TOP - UPAGES);
        !            36:        u.u_pcb.pcb_p1lr = P1TOP - UPAGES;
        !            37:        u.u_procp->p_tsize = ts;
        !            38:        u.u_tsize = ts;
        !            39:        expand((int)ss, P1BR);
        !            40:        expand((int)ds, P0BR);
        !            41: }
        !            42: 
        !            43: /*
        !            44:  * Release the virtual memory resources (memory
        !            45:  * pages, and swap area) associated with the current process.
        !            46:  * Caller must not be swappable.  Used at exit or execl.
        !            47:  */
        !            48: vrelvm()
        !            49: {
        !            50:        register struct proc *p = u.u_procp;
        !            51:        
        !            52:        /*
        !            53:         * Release memory; text first, then data and stack pages.
        !            54:         */
        !            55:        xfree();
        !            56:        p->p_rssize -= vmemfree(dptopte(p, 0), p->p_dsize);
        !            57:        p->p_rssize -= vmemfree(sptopte(p, p->p_ssize - 1), p->p_ssize);
        !            58:        if (p->p_rssize != 0)
        !            59:                panic("vrelvm rss");
        !            60:        /*
        !            61:         * Wait for all page outs to complete, then
        !            62:         * release swap space.
        !            63:         */
        !            64:        p->p_swrss = 0;
        !            65:        while (p->p_poip)
        !            66:                sleep((caddr_t)&p->p_poip, PSWP+1);
        !            67:        (void) vsexpand((clicks_t)0, &u.u_dmap, 1);
        !            68:        (void) vsexpand((clicks_t)0, &u.u_smap, 1);
        !            69:        p->p_tsize = 0;
        !            70:        p->p_dsize = 0;
        !            71:        p->p_ssize = 0;
        !            72:        u.u_tsize = 0;
        !            73:        u.u_dsize = 0;
        !            74:        u.u_ssize = 0;
        !            75: }
        !            76: 
        !            77: /*
        !            78:  * Change the size of the data+stack regions of the process.
        !            79:  * If the size is shrinking, it's easy-- just release virtual memory.
        !            80:  * If it's growing, initalize new page table entries as 
        !            81:  * 'zero fill on demand' pages.
        !            82:  */
        !            83: expand(change, region)
        !            84: {
        !            85:        register struct proc *p;
        !            86:        register struct pte *base, *p0, *p1;
        !            87:        struct pte proto;
        !            88:        int a0, a1;
        !            89: 
        !            90:        p = u.u_procp;
        !            91:        if (change == 0)
        !            92:                return;
        !            93:        if (change % CLSIZE)
        !            94:                panic("expand");
        !            95: #ifdef PGINPROF
        !            96:        vmsizmon();
        !            97: #endif
        !            98:        /*
        !            99:         * Update the sizes to reflect the change.  Note that we may
        !           100:         * swap as a result of a ptexpand, but this will work, because
        !           101:         * the routines which swap out will get the current text and data
        !           102:         * sizes from the arguments they are passed, and when the process
        !           103:         * resumes the lengths in the proc structure are used to 
        !           104:         * build the new page tables.
        !           105:         */
        !           106:        if (region == P0BR) {
        !           107:                p->p_dsize += change;
        !           108:                u.u_dsize += change;
        !           109:        } else {
        !           110:                p->p_ssize += change;
        !           111:                u.u_ssize += change;
        !           112:        }
        !           113:        /*
        !           114:         * Compute the end of the text+data regions and the beginning
        !           115:         * of the stack region in the page tables,
        !           116:         * and expand the page tables if necessary.
        !           117:         */
        !           118:        p0 = (struct pte *)mfpr(P0BR) + mfpr(P0LR);
        !           119:        p1 = (struct pte *)mfpr(P1BR) + mfpr(P1LR);
        !           120:        if (change > p1 - p0)
        !           121:                ptexpand(clrnd(ctopt(change - (p1 - p0))));
        !           122:        /* PTEXPAND SHOULD GIVE BACK EXCESS PAGE TABLE PAGES */
        !           123:        /*
        !           124:         * Compute the base of the allocated/freed region.
        !           125:         */
        !           126:        if (region == P0BR) {
        !           127:                base = (struct pte *)mfpr(P0BR);
        !           128:                base += (a0 = mfpr(P0LR)) + (change > 0 ? 0 : change);
        !           129:        } else {
        !           130:                base = (struct pte *)mfpr(P1BR);
        !           131:                base += (a1 = mfpr(P1LR)) - (change > 0 ? change : 0);
        !           132:        }
        !           133: 
        !           134:        /*
        !           135:         * If we shrunk, give back the virtual memory.
        !           136:         */
        !           137:        if (change < 0)
        !           138:                p->p_rssize -= vmemfree(base, -change);
        !           139: 
        !           140:        /*
        !           141:         * Update the processor length registers and copies in the pcb.
        !           142:         */
        !           143:        if (region == P0BR)  {
        !           144:                mtpr(P0LR, a0 + change);
        !           145:                u.u_pcb.pcb_p0lr = a0 + change | (u.u_pcb.pcb_p0lr & AST_CLR);
        !           146:        } else {
        !           147:                mtpr(P1LR, a1 - change);
        !           148:                u.u_pcb.pcb_p1lr = a1 - change;
        !           149:        }
        !           150:        *(int *)&proto = PG_UW;
        !           151:        if (change < 0)
        !           152:                change = -change;
        !           153:        else {
        !           154:                proto.pg_fod = 1;
        !           155:                ((struct fpte *)&proto)->pg_source = PG_FZERO;
        !           156:                cnt.v_nzfod += change;
        !           157:        }
        !           158:        while (--change >= 0)
        !           159:                *base++ = proto;
        !           160:        mtpr(TBIA,0);
        !           161: }
        !           162: 
        !           163: /*
        !           164:  * Create a duplicate copy of the current process
        !           165:  * in process slot p, which has been partially initialized
        !           166:  * by newproc().
        !           167:  *
        !           168:  * Could deadlock here if two large proc's get page tables
        !           169:  * and then each gets part of his UPAGES if they then have
        !           170:  * consumed all the available memory.  This can only happen when
        !           171:  *     USRPTSIZE + UPAGES * NPROC > maxmem
        !           172:  * which happens only when large procs fork on machines with tiny real memories
        !           173:  */
        !           174: procdup(p)
        !           175:        register struct proc *p;
        !           176: {
        !           177:        extern struct map kernelmap[];
        !           178: 
        !           179:        /*
        !           180:         * allocate page tables and a user block;
        !           181:         * copy parent's user to child
        !           182:         */
        !           183:        while (vgetpt(p, vmemall) == 0) {
        !           184:                kmapwnt++;
        !           185:                sleep((caddr_t)kernelmap, PSWP+4);
        !           186:        }
        !           187:        resume(pcbb(u.u_procp));
        !           188:        (void) vgetu(p, vmemall, Forkmap, forkutl, &u);
        !           189:        /*
        !           190:         * child: return here when scheduled and returns 1
        !           191:         */
        !           192:        forkutl->u_pcb.pcb_sswap = u.u_ssav;
        !           193:        if (savectx(forkutl->u_ssav))
        !           194:                return (1);
        !           195:        /*
        !           196:         * parent:
        !           197:         * finish setting up child:
        !           198:         * clear vm counters, attach text, copy data and stack
        !           199:         * return 0
        !           200:         */
        !           201:        forkutl->u_vm = zvms;
        !           202:        forkutl->u_cvm = zvms;
        !           203:        forkutl->u_dmap = u.u_cdmap;
        !           204:        forkutl->u_smap = u.u_csmap;
        !           205:        forkutl->u_outime = 0;
        !           206:        if (p->p_textp && ((p->p_textp->x_flag&XTRC) == 0 || vmxdup(p))) {
        !           207:                p->p_textp->x_count++;
        !           208:                xlink(p);
        !           209:        }
        !           210:        vmdup(p, dptopte(p, 0), dptov(p, 0), p->p_dsize, CDATA);
        !           211:        vmdup(p, sptopte(p, p->p_ssize - 1), sptov(p, p->p_ssize - 1), p->p_ssize, CSTACK);
        !           212:        return (0);
        !           213: }
        !           214: 
        !           215: /*
        !           216:  * Duplicate text segment (cf. xalloc).
        !           217:  */
        !           218: vmxdup(p)
        !           219: register struct proc *p;
        !           220: {
        !           221:        register struct text *xp, *uxp;
        !           222:        register clicks_t ts;
        !           223: 
        !           224:        if ((uxp = u.u_procp->p_textp) == 0)
        !           225:                return 0;
        !           226: 
        !           227:        for (xp = text; xp < textNTEXT && xp->x_iptr; xp++)
        !           228:                /* void */ ;
        !           229:        if (xp >= textNTEXT)
        !           230:                return 1;
        !           231: 
        !           232:        xp->x_flag = XLOCK|XTRC|XLOAD;
        !           233:        xp->x_size = ts = uxp->x_size;
        !           234:        if (vsxalloc(xp) == NULL)
        !           235:                return 1;
        !           236: 
        !           237:        xp->x_count = 1;
        !           238:        xp->x_ccount = 0;
        !           239:        xp->x_rssize = 0;
        !           240:        (xp->x_iptr = uxp->x_iptr)->i_count++;
        !           241:        p->p_textp = xp;
        !           242:        xlink(p);
        !           243:        vmdup(p, tptopte(p, 0), tptov(p, 0), ts, CTEXT);
        !           244:        xp->x_flag |= XWRIT;
        !           245:        xp->x_flag &= ~XLOAD;
        !           246:        xunlock(xp);
        !           247: 
        !           248:        return 0;
        !           249: }
        !           250: 
        !           251: vmdup(p, pte, v, count, type)
        !           252:        struct proc *p;
        !           253:        register struct pte *pte;
        !           254:        register unsigned v;
        !           255:        register clicks_t count;
        !           256:        int type;
        !           257: {
        !           258:        register struct pte *opte = vtopte(u.u_procp, v);
        !           259:        register int i;
        !           260: 
        !           261:        while (count != 0) {
        !           262:                count -= CLSIZE;
        !           263:                if (opte->pg_fod && type != CTEXT) {
        !           264:                        v += CLSIZE;
        !           265:                        for (i = 0; i < CLSIZE; i++)
        !           266:                                *(int *)pte++ = *(int *)opte++;
        !           267:                        continue;
        !           268:                }
        !           269:                opte += CLSIZE;
        !           270:                (void) vmemall(pte, CLSIZE, p, type);
        !           271:                if (type == CTEXT)
        !           272:                        p->p_textp->x_rssize += CLSIZE;
        !           273:                else
        !           274:                        p->p_rssize += CLSIZE;
        !           275:                for (i = 0; i < CLSIZE; i++) {
        !           276:                        copyseg((caddr_t)ctob(v+i), (pte+i)->pg_pfnum);
        !           277:                        *(int *)(pte+i) |= (type == CTEXT) ?
        !           278:                            ((PG_V|PG_M) + PG_URKR) : ((PG_V|PG_M) + PG_UW);
        !           279:                }
        !           280:                v += CLSIZE;
        !           281:                munlock(pte->pg_pfnum);
        !           282:                pte += CLSIZE;
        !           283:        }
        !           284: }
        !           285: 
        !           286: /*
        !           287:  * Check that a process will not be too large.
        !           288:  */
        !           289: chksize(ts, ds, ss)
        !           290:        clicks_t ts, ds, ss;
        !           291: {
        !           292: 
        !           293:        if (ts>maxtsize || ds>maxdsize || ss>maxssize) {
        !           294:                u.u_error = ENOMEM;
        !           295:                return(1);
        !           296:        }
        !           297:        return (0);
        !           298: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.