Annotation of coherent/d/286_KERNEL/USRSRC/coh/swap.c, revision 1.1.1.1

1.1       root        1: /* $Header: /newbits/286_KERNEL/USRSRC/coh/RCS/swap.c,v 1.1 92/01/09 13:29:13 bin Exp Locker: bin $ */
                      2: /* (lgl-
                      3:  *     The information contained herein is a trade secret of Mark Williams
                      4:  *     Company, and  is confidential information.  It is provided  under a
                      5:  *     license agreement,  and may be  copied or disclosed  only under the
                      6:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
                      7:  *     material without the express written authorization of Mark Williams
                      8:  *     Company or persuant to the license agreement is unlawful.
                      9:  *
                     10:  *     COHERENT Version 2.3.37
                     11:  *     Copyright (c) 1982, 1983, 1984.
                     12:  *     An unpublished work by Mark Williams Company, Chicago.
                     13:  *     All rights reserved.
                     14:  -lgl) */
                     15: /*
                     16:  * Coherent.
                     17:  * Swapper.
                     18:  *
                     19:  * $Log:       swap.c,v $
                     20:  * Revision 1.1  92/01/09  13:29:13  bin
                     21:  * Initial revision
                     22:  * 
                     23:  * Revision 1.1        88/03/24  16:19:51      src
                     24:  * Initial revision
                     25:  * 
                     26:  * 87/01/05    Allan Cornish           /usr/src/sys/ker/swap.c
                     27:  * Swap() now waits for all processes to be swapped in before exit on signal.
                     28:  */
                     29: #include <coherent.h>
                     30: #include <proc.h>
                     31: #include <sched.h>
                     32: #include <sys/seg.h>
                     33: #include <sys/uproc.h>
                     34: #include <sys/buf.h>
                     35: 
                     36: /*
                     37:  * Functions.
                     38:  */
                     39: SEG    *xmalloc();
                     40: SEG    *xdalloc();
                     41: 
                     42: swap()
                     43: {
                     44:        register SEG *sp;
                     45:        register PROC *pp1;
                     46:        register PROC *pp2;
                     47:        register PROC *pp3;
                     48:        register unsigned s;
                     49:        register unsigned n;
                     50:        register unsigned t;
                     51:        register unsigned v;
                     52:        register unsigned m;
                     53:        register int i;
                     54:        static unsigned ltimer;
                     55: 
                     56:        if (sexflag != 0)
                     57:                uexit(1);
                     58:        sexflag++;
                     59:        while (1) {
                     60:                lock(pnxgate);
                     61:                t = (utimer-ltimer)/NSUTICK;
                     62:                v = t*SVCLOCK;
                     63:                ltimer += t*NSUTICK;
                     64:                m = 0;
                     65:                pp2 = NULL;
                     66:                for (pp1=procq.p_nback; pp1!=&procq; pp1=pp1->p_nback) {
                     67:                        if ((pp1->p_flags&PFCORE) != 0) {
                     68:                                pp1->p_sval >>= t;
                     69:                                pp1->p_ival -= t;
                     70:                                if (pp1->p_ival < -30000)
                     71:                                        pp1->p_ival = -30000;
                     72:                                continue;
                     73:                        }
                     74:                        addu(pp1->p_sval, v);
                     75:                        if (pp1->p_state != PSRUN)
                     76:                                continue;
                     77:                        s = 0;
                     78:                        for (i=0; i<NUSEG+1; i++)
                     79:                                if ((sp=pp1->p_segp[i]) != NULL)
                     80:                                        if ((sp->s_flags&SFCORE) == 0)
                     81:                                                s += sp->s_size;
                     82:                        if ((s=ctokrd(s)) == 0)
                     83:                                s = 1;
                     84:                        n = (pp1->p_sval+pp1->p_rval)/s;
                     85:                        if (n > m) {
                     86:                                m = n;
                     87:                                pp2 = pp1;
                     88:                        }
                     89:                }
                     90:                unlock(pnxgate);
                     91:                if (pp2 == NULL) {
                     92:                        if ( SELF->p_ssig != 0 )
                     93:                                break;
                     94:                        goto con;
                     95:                }
                     96: #ifndef        NOMONITOR
                     97:                if (swmflag)
                     98:                        printf("Swapin(%p, %d)\n", pp2, pp2->p_pid);
                     99: #endif
                    100:        xxx:
                    101:                while (testcore(pp2)==0 || proccore(pp2)!=0) {
                    102:                        if ((pp2->p_flags&PFAUXM) != 0) {
                    103:                                auxmdisk(pp2);
                    104:                                goto xxx;
                    105:                        }
                    106:                        procdisk(pp2);
                    107:                        i = 32767;
                    108:                        pp3 = NULL;
                    109:                        lock(pnxgate);
                    110:                        for (pp1=procq.p_nforw; pp1!=&procq; pp1=pp1->p_nforw){
                    111:                                if (pp1->p_flags&(PFSWIO|PFLOCK|PFKERN))
                    112:                                        continue;
                    113:                                if ((pp1->p_flags&PFAUXM) != 0) {
                    114:                                        auxmdisk(pp1);
                    115:                                        unlock(pnxgate);
                    116:                                        goto xxx;
                    117:                                }
                    118:                                if ((pp1->p_flags&PFCORE) == 0) {
                    119:                                        if (procdisk(pp1) != 0) {
                    120:                                                unlock(pnxgate);
                    121:                                                goto xxx;
                    122:                                        }
                    123:                                        continue;
                    124:                                }
                    125:                                if (pp1->p_ival>-64 && pp1->p_sval!=0)
                    126:                                        continue;
                    127:                                if (pp1->p_ival < i) {
                    128:                                        i = pp1->p_ival;
                    129:                                        pp3 = pp1;
                    130:                                }
                    131:                        }
                    132:                        unlock(pnxgate);
                    133:                        if (pp3 == NULL) {
                    134: #ifndef NOMONITOR
                    135:                                if (swmflag)
                    136:                                        printf("No one to swap out\n");
                    137: #endif
                    138:                                break;
                    139:                        }
                    140:                        if (i > 0) {
                    141: #ifndef NOMONITOR
                    142:                                if (swmflag)
                    143:                                        printf("Dispatch(%p, %d)\n",
                    144:                                                pp3, pp3->p_pid);
                    145: #endif
                    146:                                pp3->p_flags |= PFDISP;
                    147:                                break;
                    148:                        }
                    149: #ifndef NOMONITOR
                    150:                        if (swmflag)
                    151:                                printf("Swapout(%p, %d)\n", pp3, pp3->p_pid);
                    152: #endif
                    153:                        procdisk(pp3);
                    154:                }
                    155: #ifndef NOMONITOR
                    156:                if (swmflag)
                    157:                        printf("Swapdone\n");
                    158: #endif
                    159:        con:
                    160:                timeout(&stimer, NSRTICK, wakeup, (char *)&stimer);
                    161:                sleep((char *)&stimer, CVSWAP, IVSWAP, SVSWAP);
                    162:        }
                    163:        --sexflag;
                    164:        uexit(1);
                    165: }
                    166: 
                    167: /*
                    168:  * See if the given process may fit in core.
                    169:  */
                    170: testcore(pp)
                    171: register PROC *pp;
                    172: {
                    173:        register SEG *sp;
                    174:        register saddr_t s;
                    175:        register saddr_t s1;
                    176:        register saddr_t s2;
                    177:        register int i;
                    178: 
                    179:        s = 0;
                    180:        for (i=0; i<NUSEG+1; i++) {
                    181:                if ((sp=pp->p_segp[i]) == NULL)
                    182:                        continue;
                    183:                if ((sp->s_flags&SFCORE) != 0)
                    184:                        continue;
                    185:                if (sp->s_size > s)
                    186:                        s = sp->s_size;
                    187:        }
                    188:        s1 = corebot;
                    189:        sp = &segmq;
                    190:        do {
                    191:                sp = sp->s_forw;
                    192:                s2 = sp->s_mbase;
                    193:                if (s2-s1 >= s)
                    194:                        return (1);
                    195:                s1 = sp->s_mbase + sp->s_size;
                    196:        } while (sp != &segmq);
                    197:        return (0);
                    198: }
                    199: 
                    200: /*
                    201:  * Swap all segments associated with a particular process into core.
                    202:  * The number of segments still swapped out is returned.
                    203:  */
                    204: proccore(pp)
                    205: register PROC *pp;
                    206: {
                    207:        register SEG *sp;
                    208:        register int i;
                    209:        register int n;
                    210:        register int f;
                    211: 
                    212:        n = 0;
                    213:        f = pp->p_flags&PFSWAP;
                    214:        for (i=0; i<NUSEG+1; i++) {
                    215:                if ((sp=pp->p_segp[i]) == NULL)
                    216:                        continue;
                    217:                if (f != 0)
                    218:                        sp->s_lrefc++;
                    219:                if ((sp->s_flags&SFCORE)==0 && segcore(sp)==0)
                    220:                        n++;
                    221:        }
                    222:        if (n == 0)
                    223:                pp->p_flags |= PFCORE;
                    224:        pp->p_flags &= ~PFSWAP;
                    225:        return (n);
                    226: }
                    227: 
                    228: /*
                    229:  * Swap out all segments associated with a given process.
                    230:  */
                    231: procdisk(pp)
                    232: register PROC *pp;
                    233: {
                    234:        register SEG *sp;
                    235:        register int i;
                    236:        register int f;
                    237:        int n;
                    238: 
                    239:        n = 0;
                    240:        f = pp->p_flags&PFSWAP;
                    241:        pp->p_flags &= ~PFCORE;
                    242:        for (i=0; i<NUSEG+1; i++) {
                    243:                if ((sp=pp->p_segp[i]) == NULL)
                    244:                        continue;
                    245:                if (f == 0)
                    246:                        --sp->s_lrefc;
                    247:                if ((sp->s_flags&SFCORE) == 0)
                    248:                        continue;
                    249:                if (sp->s_lrefc == 0)
                    250:                        if (segdisk(sp) != 0)
                    251:                                n++;
                    252:        }
                    253:        pp->p_flags |= PFSWAP;
                    254:        return (n);
                    255: }
                    256: 
                    257: /*
                    258:  * Swap out all auxiliary segments used by a process.
                    259:  */
                    260: auxmdisk(pp)
                    261: register PROC *pp;
                    262: {
                    263:        register SEG *sp;
                    264:        register int i;
                    265:        register int f;
                    266:        register int m;
                    267:        SEG *segl[NUSEG];
                    268: 
                    269: #ifndef NOMONITOR
                    270:        if (swmflag)
                    271:                printf("Auxiliary(%p, %d)\n", pp, pp->p_pid);
                    272: #endif
                    273:        sp = pp->p_segp[SIUSERP];
                    274:        if ((sp->s_flags&SFCORE) == 0) {
                    275:                panic("We may be in trouble");
                    276:                return;
                    277:        }
                    278:        m = pp->p_flags&PFCORE;
                    279:        f = pp->p_flags&PFAUXM;
                    280:        pp->p_flags &= ~(PFAUXM|PFCORE);
                    281:        skcopy(sp, offset(uproc, u_sege[0]), segl, sizeof(u.u_sege));
                    282:        for (i=0; i<NUSEG; i++) {
                    283:                if ((sp=segl[i]) == NULL)
                    284:                        continue;
                    285:                if (f != 0)
                    286:                        --sp->s_lrefc;
                    287:                if ((sp->s_flags&SFCORE) == 0)
                    288:                        continue;
                    289:                if (sp->s_lrefc == 0)
                    290:                        segdisk(sp);
                    291:        }
                    292:        pp->p_flags |= m;
                    293: }
                    294: 
                    295: /*
                    296:  * Swap the given segment into core.
                    297:  */
                    298: segcore(sp1)
                    299: register SEG *sp1;
                    300: {
                    301:        register SEG *sp2;
                    302: 
                    303:        lock(seglink);
                    304:        sp2 = xmalloc(sp1->s_size);
                    305:        unlock(seglink);
                    306:        if (sp2 == NULL)
                    307:                return (0);
                    308:        sp1->s_lrefc++;
                    309:        swapio(0, sp2->s_mbase, sp1->s_dbase, sp2->s_size);
                    310:        lock(seglink);
                    311:        sp1->s_back->s_forw = sp1->s_forw;
                    312:        sp1->s_forw->s_back = sp1->s_back;
                    313:        sp2->s_back->s_forw = sp1;
                    314:        sp1->s_back = sp2->s_back;
                    315:        sp2->s_forw->s_back = sp1;
                    316:        sp1->s_forw = sp2->s_forw;
                    317:        sp1->s_flags |= SFCORE;
                    318:        sp1->s_mbase = sp2->s_mbase;
                    319:        --sp1->s_lrefc;
                    320:        unlock(seglink);
                    321:        return (1);
                    322: }
                    323: 
                    324: /*
                    325:  * Swap the given segment out onto disk.
                    326:  */
                    327: segdisk(sp1)
                    328: register SEG *sp1;
                    329: {
                    330:        register SEG *sp2;
                    331: 
                    332:        lock(seglink);
                    333:        sp2 = xdalloc(sp1->s_size);
                    334:        unlock(seglink);
                    335:        if (sp2 == NULL)
                    336:                return (0);
                    337:        sp1->s_lrefc++;
                    338:        swapio(1, sp1->s_mbase, sp2->s_dbase, sp1->s_size);
                    339:        lock(seglink);
                    340:        sp1->s_back->s_forw = sp1->s_forw;
                    341:        sp1->s_forw->s_back = sp1->s_back;
                    342:        sp2->s_back->s_forw = sp1;
                    343:        sp1->s_back = sp2->s_back;
                    344:        sp2->s_forw->s_back = sp1;
                    345:        sp1->s_forw = sp2->s_forw;
                    346:        sp1->s_flags &= ~SFCORE;
                    347:        sp1->s_dbase = sp2->s_dbase;
                    348:        --sp1->s_lrefc;
                    349:        unlock(seglink);
                    350:        return (1);
                    351: }
                    352: 
                    353: /*
                    354:  * Allocate a segment on disk that is `n' clicks long.
                    355:  * The `seglink' gate should be locked before this routine is called.
                    356:  * This routine is the same as `sdalloc' except that we can't run out of
                    357:  * alloc space to allocate the segment and we allocate in high regions.
                    358:  */
                    359: SEG *
                    360: xdalloc(s)
                    361: saddr_t s;
                    362: {
                    363:        register SEG *sp1;
                    364:        register SEG *sp2;
                    365:        register daddr_t d;
                    366:        register daddr_t d1;
                    367:        register daddr_t d2;
                    368: 
                    369:        d = stod(s);
                    370:        d2 = swaptop;
                    371:        sp1 = &segdq;
                    372:        do {
                    373:                if ((sp1=sp1->s_back) != &segdq)
                    374:                        d1 = sp1->s_dbase + stod(sp1->s_size);
                    375:                else
                    376:                        d1 = swapbot;
                    377:                if (d2-d1 >= d) {
                    378:                        sp2 = &segswap;
                    379:                        kclear((char *)sp2, sizeof(SEG));
                    380:                        sp1->s_forw->s_back = sp2;
                    381:                        sp2->s_forw = sp1->s_forw;
                    382:                        sp1->s_forw = sp2;
                    383:                        sp2->s_back = sp1;
                    384:                        sp2->s_urefc = 1;
                    385:                        sp2->s_lrefc = 1;
                    386:                        sp2->s_size = s;
                    387:                        sp2->s_dbase = d2 - d;
                    388:                        return (sp2);
                    389:                }
                    390:                d2 = sp1->s_dbase;
                    391:        } while (sp1 != &segdq);
                    392:        return (NULL);
                    393: }
                    394: 
                    395: /*
                    396:  * Allocate a segment in memory that is `n' clicks long.
                    397:  * The `seglink' gate should be locked before this routine is called.
                    398:  * This routine is the same as `smalloc' except that we can't run out of
                    399:  * alloc space to allocate the segment.
                    400:  */
                    401: SEG *
                    402: xmalloc(s)
                    403: register saddr_t s;
                    404: {
                    405:        register SEG *sp1;
                    406:        register SEG *sp2;
                    407:        register saddr_t s1;
                    408:        register saddr_t s2;
                    409: 
                    410:        s1 = corebot;
                    411:        sp1 = &segmq;
                    412:        do {
                    413:                if ((sp1=sp1->s_forw) != &segmq)
                    414:                        s2 = sp1->s_mbase;
                    415:                else
                    416:                        s2 = coretop;
                    417:                if (s2-s1 >= s) {
                    418:                        sp2 = &segswap;
                    419:                        kclear((char *)sp2, sizeof(SEG));
                    420:                        sp1->s_back->s_forw = sp2;
                    421:                        sp2->s_back = sp1->s_back;
                    422:                        sp1->s_back = sp2;
                    423:                        sp2->s_forw = sp1;
                    424:                        sp2->s_urefc = 1;
                    425:                        sp2->s_lrefc = 1;
                    426:                        sp2->s_size = s;
                    427:                        sp2->s_mbase = s1;
                    428:                        return (sp2);
                    429:                }
                    430:                s1 = sp1->s_mbase + sp1->s_size;
                    431:        } while (sp1 != &segmq);
                    432:        return (NULL);
                    433: }

unix.superglobalmegacorp.com

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