Annotation of coherent/b/kernel/ldrv/ldswap.c, revision 1.1.1.1

1.1       root        1: /* $Header: /kernel/kersrc/ldrv/RCS/ldswap.c,v 1.1 92/07/17 15:27:54 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:       ldswap.c,v $
                     20:  * Revision 1.1  92/07/17  15:27:54  bin
                     21:  * Initial revision
                     22:  * 
                     23:  * Revision 1.1        88/03/24  16:30:50      src
                     24:  * Initial revision
                     25:  * 
                     26:  * 87/11/05    Allan Cornish           /usr/src/sys/ldrv/ldswap.c
                     27:  * New seg struct now used to allow extended addressing.
                     28:  *
                     29:  * 87/10/26    Allan Cornish           /usr/src/sys/ldrv/ldswap.c
                     30:  * Modified to support loadable drivers - temporary modification.
                     31:  * Now requires SIGKILL signal in order to terminate.
                     32:  *
                     33:  * 87/01/05    Allan Cornish           /usr/src/sys/ker/swap.c
                     34:  * Swap() now waits for all processes to be swapped in before exit on signal.
                     35:  */
                     36: #include <sys/coherent.h>
                     37: #include <sys/proc.h>
                     38: #include <sys/sched.h>
                     39: #include <sys/seg.h>
                     40: #include <sys/uproc.h>
                     41: #include <sys/buf.h>
                     42: 
                     43: /*
                     44:  * Functions.
                     45:  */
                     46: SEG    *xmalloc();
                     47: SEG    *xdalloc();
                     48: void   Kwakeup();
                     49: void   Ktimeout();
                     50: 
                     51: main()
                     52: {
                     53:        register SEG *sp;
                     54:        register PROC *pp1;
                     55:        register PROC *pp2;
                     56:        register PROC *pp3;
                     57:        register unsigned s;
                     58:        register unsigned n;
                     59:        register unsigned t;
                     60:        register unsigned v;
                     61:        register unsigned m;
                     62:        register int i;
                     63:        static unsigned ltimer;
                     64: 
                     65:        if (sexflag != 0)
                     66:                uexit(1);
                     67:        sexflag++;
                     68: 
                     69:        while (1) {
                     70:                lock( pnxgate );
                     71:                t = (utimer - ltimer) / NSUTICK;
                     72:                v = t * SVCLOCK;
                     73:                ltimer += t * NSUTICK;
                     74: 
                     75:                /*
                     76:                 * Search for process to swap into memory.
                     77:                 */
                     78:                pp2 = NULL;
                     79:                m   = 0;
                     80:                s   = 0;
                     81:                for (pp1 = procq.p_nback; pp1 != &procq; pp1 = pp1->p_nback) {
                     82: 
                     83:                        /*
                     84:                         * Process resides in memory.
                     85:                         */
                     86:                        if ( (pp1->p_flags & PFCORE) != 0 ) {
                     87:                                pp1->p_sval >>= t;
                     88:                                pp1->p_ival  -= t;
                     89:                                if (pp1->p_ival < -30000)
                     90:                                        pp1->p_ival = -30000;
                     91:                                continue;
                     92:                        }
                     93: 
                     94:                        /*
                     95:                         * Update swap value - high values swapped in first.
                     96:                         */
                     97:                        addu( pp1->p_sval, v );
                     98:                        s = 1;
                     99: 
                    100:                        /*
                    101:                         * Process is not runnable.
                    102:                         */
                    103:                        if ( pp1->p_state != PSRUN )
                    104:                                continue;
                    105: 
                    106:                        /*
                    107:                         * Calculate disk usage in Kbytes.
                    108:                         */
                    109:                        s = 0;
                    110:                        for ( i = 0; i < NUSEG+1; i++ )
                    111:                                if ( (sp = pp1->p_segp[i]) != NULL )
                    112:                                        if ( (sp->s_flags & SFCORE) == 0 )
                    113:                                                s += sp->s_size / 1024;
                    114:                        if ( s == 0 )
                    115:                                s = 1;
                    116: 
                    117:                        /*
                    118:                         * Compute importance:
                    119:                         *
                    120:                         *      swap value + response value
                    121:                         *      ---------------------------
                    122:                         *        Kbytes to be swapped in
                    123:                         */
                    124:                        n = (pp1->p_sval + pp1->p_rval) / s;
                    125: 
                    126:                        /*
                    127:                         * More important.
                    128:                         */
                    129:                        if ( n > m ) {
                    130:                                m = n;
                    131:                                pp2 = pp1;
                    132:                        }
                    133:                }
                    134:                unlock( pnxgate );
                    135: 
                    136:                /*
                    137:                 * No runnable processes swapped out.
                    138:                 */
                    139:                if ( pp2 == NULL ) {
                    140:                        /*
                    141:                         * No processes swapped out, and KILL signal received.
                    142:                         */
                    143:                        if ( (s == 0) && (SELF->p_ssig & 0x0100) )
                    144:                                break;
                    145:                        goto con;
                    146:                }
                    147: 
                    148: #ifndef        NOMONITOR
                    149:                if (swmflag)
                    150:                        printf("Swapin(%p, %d)\n", pp2, pp2->p_pid);
                    151: #endif
                    152:        xxx:
                    153:                /*
                    154:                 * Try to swap process into memory.
                    155:                 */
                    156:                while ( (testcore(pp2) == 0) || (proccore(pp2) != 0) ) {
                    157: 
                    158:                        /*
                    159:                         * Swap process out.
                    160:                         */
                    161:                        procdisk(pp2);
                    162:                        i   = 32767;
                    163:                        pp3 = NULL;
                    164: 
                    165:                        /*
                    166:                         * Search for process to swap out.
                    167:                         */
                    168:                        lock( pnxgate );
                    169:                        for (pp1=procq.p_nforw; pp1!=&procq; pp1=pp1->p_nforw){
                    170: 
                    171:                                if ( pp1->p_flags & (PFSWIO|PFLOCK|PFKERN) )
                    172:                                        continue;
                    173: 
                    174:                                /*
                    175:                                 * Process is not totally memory resident.
                    176:                                 */
                    177:                                if ( (pp1->p_flags&PFCORE) == 0 ) {
                    178:                                        /*
                    179:                                         * Swap segments out to disk.
                    180:                                         */
                    181:                                        if ( procdisk(pp1) != 0 ) {
                    182:                                                unlock( pnxgate );
                    183:                                                goto xxx;
                    184:                                        }
                    185:                                        continue;
                    186:                                }
                    187: 
                    188:                                /*
                    189:                                 * Process too important to swap out.
                    190:                                 */
                    191:                                if ((pp1->p_ival > -64) && (pp1->p_sval != 0))
                    192:                                        continue;
                    193: 
                    194:                                /*
                    195:                                 * Less important.
                    196:                                 */
                    197:                                if ( pp1->p_ival < i ) {
                    198:                                        i = pp1->p_ival;
                    199:                                        pp3 = pp1;
                    200:                                }
                    201:                        }
                    202:                        unlock( pnxgate );
                    203: 
                    204:                        /*
                    205:                         * No processes to swap out.
                    206:                         */
                    207:                        if ( pp3 == NULL ) {
                    208: #ifndef NOMONITOR
                    209:                                if (swmflag)
                    210:                                        printf("No one to swap out\n");
                    211: #endif
                    212:                                break;
                    213:                        }
                    214: 
                    215:                        /*
                    216:                         * Process is too important to swap out.
                    217:                         */
                    218:                        if ( i > 0 ) {
                    219: #ifndef NOMONITOR
                    220:                                if (swmflag)
                    221:                                        printf("Dispatch(%p, %d)\n",
                    222:                                                pp3, pp3->p_pid);
                    223: #endif
                    224:                                pp3->p_flags |= PFDISP;
                    225:                                break;
                    226:                        }
                    227: #ifndef NOMONITOR
                    228:                        if (swmflag)
                    229:                                printf("Swapout(%p, %d)\n", pp3, pp3->p_pid);
                    230: #endif
                    231:                        /*
                    232:                         * Swap process out to disk.
                    233:                         */
                    234:                        procdisk( pp3 );
                    235:                }
                    236: 
                    237: #ifndef NOMONITOR
                    238:                if (swmflag)
                    239:                        printf("Swapdone\n");
                    240: #endif
                    241:        con:
                    242:                kcall( Ktimeout, &stimer, NSRTICK, Kwakeup, (char *)&stimer );
                    243:                sleep( (char *)&stimer, CVSWAP, IVSWAP, SVSWAP );
                    244:        }
                    245:        sexflag--;
                    246:        uexit( 1 );
                    247: }
                    248: 
                    249: /*
                    250:  * See if the given process may fit in core.
                    251:  */
                    252: testcore( pp )
                    253: register PROC *pp;
                    254: {
                    255:        register SEG *sp;
                    256:        register fsize_t s;
                    257:        register paddr_t s1;
                    258:        register paddr_t s2;
                    259:        register int i;
                    260: 
                    261:        /*
                    262:         * Find largest segment in process.
                    263:         */
                    264:        s = 0;
                    265:        for ( i = 0; i < NUSEG+1; i++ ) {
                    266: 
                    267:                if ( (sp = pp->p_segp[i]) == NULL )
                    268:                        continue;
                    269: 
                    270:                /*
                    271:                 * Segment is memory resident.
                    272:                 */
                    273:                if ( (sp->s_flags & SFCORE) != 0 )
                    274:                        continue;
                    275: 
                    276:                /*
                    277:                 * Largest segment so far.
                    278:                 */
                    279:                if ( sp->s_size > s )
                    280:                        s = sp->s_size;
                    281:        }
                    282: 
                    283:        /*
                    284:         * See if largest segment will fit in memory.
                    285:         */
                    286:        s1 = corebot;
                    287:        sp = &segmq;
                    288:        do {
                    289:                /*
                    290:                 * Advance to next memory segment.
                    291:                 */
                    292:                sp = sp->s_forw;
                    293:                s2 = sp->s_paddr;
                    294: 
                    295:                /*
                    296:                 * It fits!
                    297:                 */
                    298:                if ( s2 - s1 >= s )
                    299:                        return (1);
                    300: 
                    301:                /*
                    302:                 * Compute start of next hole.
                    303:                 */
                    304:                s1 = sp->s_paddr + sp->s_size;
                    305: 
                    306:        } while ( sp != &segmq );
                    307: 
                    308:        return( 0 );
                    309: }
                    310: 
                    311: /*
                    312:  * Swap all segments associated with a particular process into core.
                    313:  * The number of segments still swapped out is returned.
                    314:  */
                    315: proccore( pp )
                    316: register PROC *pp;
                    317: {
                    318:        register SEG *sp;
                    319:        register int i;
                    320:        register int n;
                    321:        register int f;
                    322: 
                    323:        f = pp->p_flags & PFSWAP;
                    324: 
                    325:        /*
                    326:         * Try to swap in all user segments and the auxiliary segment.
                    327:         */
                    328:        for ( n = 0, i = 0; i < NUSEG+1; i++ ) {
                    329: 
                    330:                if ( (sp = pp->p_segp[i]) == NULL )
                    331:                        continue;
                    332: 
                    333:                /*
                    334:                 * Process was swapped out.
                    335:                 */
                    336:                if ( f != 0 )
                    337:                        sp->s_lrefc++;
                    338: 
                    339:                /*
                    340:                 * Segment is disk resident - try to swap it in.
                    341:                 */
                    342:                if ( (sp->s_flags & SFCORE) == 0 )
                    343:                        if ( segcore(sp) == 0 )
                    344:                                n++;
                    345:        }
                    346: 
                    347:        /*
                    348:         * No segments left on disk - mark process as being memory resident.
                    349:         */
                    350:        if ( n == 0 )
                    351:                pp->p_flags |= PFCORE;
                    352: 
                    353:        /*
                    354:         * Mark process as no longer being disk resident.
                    355:         */
                    356:        pp->p_flags &= ~PFSWAP;
                    357: 
                    358:        return( n );
                    359: }
                    360: 
                    361: /*
                    362:  * Swap out all segments associated with a given process.
                    363:  */
                    364: procdisk( pp )
                    365: register PROC *pp;
                    366: {
                    367:        register SEG *sp;
                    368:        register int i;
                    369:        register int f;
                    370:        int n;
                    371: 
                    372:        f = pp->p_flags & PFSWAP;
                    373: 
                    374:        /*
                    375:         * Mark process as no longer being memory resident BEFORE swapping.
                    376:         */
                    377:        pp->p_flags &= ~PFCORE;
                    378: 
                    379:        /*
                    380:         * Try to swap out all user segments and the auxiliary segment.
                    381:         */
                    382:        for ( n = 0, i = 0; i < NUSEG+1; i++ ) {
                    383: 
                    384:                if ( (sp = pp->p_segp[i]) == NULL )
                    385:                        continue;
                    386: 
                    387:                /*
                    388:                 * Process not already swapped out.
                    389:                 */
                    390:                if ( f == 0 )
                    391:                        sp->s_lrefc--;
                    392: 
                    393:                /*
                    394:                 * Segment already swapped out.
                    395:                 */
                    396:                if ( (sp->s_flags & SFCORE) == 0 )
                    397:                        continue;
                    398: 
                    399:                /*
                    400:                 * Segment no longer referenced by a memory-resident process.
                    401:                 */
                    402:                if ( (sp->s_lrefc == 0) && (segdisk(sp) != 0) )
                    403:                        n++;
                    404:        }
                    405: 
                    406:        /*
                    407:         * Mark process as being disk resident.
                    408:         */
                    409:        pp->p_flags |= PFSWAP;
                    410: 
                    411:        return( n );
                    412: }
                    413: 
                    414: /*
                    415:  * Swap the given segment into core.
                    416:  * NOTE: Although swapped out, the segment may have a descriptor table entry,
                    417:  *      and therefore have a valid s_faddr field.
                    418:  */
                    419: segcore( sp1 )
                    420: register SEG *sp1;
                    421: {
                    422:        register SEG *sp2;
                    423: 
                    424:        /*
                    425:         * Lock segmentation.
                    426:         */
                    427:        lock( seglink );
                    428: 
                    429:        /*
                    430:         * Segment has been moved to memory while we waited to lock.
                    431:         */
                    432:        if ( (sp1->s_flags & SFCORE) != 0 ) {
                    433:                unlock(seglink);
                    434:                return( 1 );
                    435:        }
                    436: 
                    437:        /*
                    438:         * Allocate a memory segment sp2.
                    439:         */
                    440:        if ((sp2 = xmalloc( sp1->s_size )) == NULL ) {
                    441:                unlock( seglink );
                    442:                return( 0 );
                    443:        }
                    444: 
                    445:        /*
                    446:         * Copy the disk segment sp1 into the memory segment sp2.
                    447:         */
                    448:        sp1->s_lrefc++;
                    449:        swapio(0, sp2->s_paddr, sp1->s_daddr, sp2->s_size );
                    450:        sp1->s_lrefc--;
                    451: 
                    452:        /*
                    453:         * Remove segment sp1 from the disk queue.
                    454:         */
                    455:        sp1->s_back->s_forw = sp1->s_forw;
                    456:        sp1->s_forw->s_back = sp1->s_back;
                    457: 
                    458:        /*
                    459:         * Insert segment sp1 into memory queue replacing segment sp2.
                    460:         */
                    461:        sp2->s_back->s_forw = sp1;
                    462:        sp1->s_back = sp2->s_back;
                    463:        sp2->s_forw->s_back = sp1;
                    464:        sp1->s_forw = sp2->s_forw;
                    465: 
                    466:        /*
                    467:         * Enable access to memory segment sp1.
                    468:         */
                    469:        sp1->s_flags |= SFCORE;
                    470:        sp1->s_paddr = sp2->s_paddr;
                    471:        vremap( sp1 );
                    472: 
                    473:        /*
                    474:         * Unlock segmentation.
                    475:         */
                    476:        unlock( seglink );
                    477: 
                    478:        return( 1 );
                    479: }
                    480: 
                    481: /*
                    482:  * Swap the given segment out onto disk.
                    483:  */
                    484: segdisk( sp1 )
                    485: register SEG *sp1;
                    486: {
                    487:        register SEG *sp2;
                    488: 
                    489:        /*
                    490:         * Lock segmentation.
                    491:         */
                    492:        lock( seglink );
                    493: 
                    494:        /*
                    495:         * Verify segment sp1 did not become busy while we waited to lock.
                    496:         * IE: raw disk i/o, or shared code fork.
                    497:         */
                    498:        if ( sp1->s_lrefc != 0 ) {
                    499:                unlock( seglink );
                    500:                return( 0 );
                    501:        }
                    502: 
                    503:        /*
                    504:         * Segment has been moved to disk while we waited to lock.
                    505:         */
                    506:        if ( (sp1->s_flags & SFCORE) == 0 ) {
                    507:                unlock(seglink);
                    508:                return( 1 );
                    509:        }
                    510: 
                    511:        /*
                    512:         * Allocate a disk segment sp2.
                    513:         */
                    514:        if ( (sp2 = xdalloc( sp1->s_size )) == NULL ) {
                    515:                unlock( seglink );
                    516:                return( 0 );
                    517:        }
                    518: 
                    519:        /*
                    520:         * Disable access to memory segment sp1.
                    521:         */
                    522:        sp1->s_flags &= ~SFCORE;
                    523:        sp1->s_daddr = sp2->s_daddr;
                    524:        vremap( sp1 );
                    525: 
                    526:        /*
                    527:         * Copy the memory segment sp1 into the disk segment sp2.
                    528:         */
                    529:        sp1->s_lrefc++;
                    530:        swapio( 1, sp1->s_paddr, sp2->s_daddr, sp1->s_size );
                    531:        sp1->s_lrefc--;
                    532: 
                    533:        /*
                    534:         * Remove segment sp1 from the memory queue.
                    535:         */
                    536:        sp1->s_back->s_forw = sp1->s_forw;
                    537:        sp1->s_forw->s_back = sp1->s_back;
                    538: 
                    539:        /*
                    540:         * Insert segment sp1 into disk queue replacing segment sp2.
                    541:         */
                    542:        sp2->s_back->s_forw = sp1;
                    543:        sp1->s_back = sp2->s_back;
                    544:        sp2->s_forw->s_back = sp1;
                    545:        sp1->s_forw = sp2->s_forw;
                    546: 
                    547:        /*
                    548:         * Unlock segmentation.
                    549:         */
                    550:        unlock( seglink );
                    551: 
                    552:        return( 1 );
                    553: }
                    554: 
                    555: /*
                    556:  * Allocate a segment on disk that is `n' bytes long.
                    557:  * The `seglink' gate should be locked before this routine is called.
                    558:  * This routine is the same as `sdalloc' except that we can't run out of
                    559:  * alloc space to allocate the segment and we allocate in high regions.
                    560:  * NOTE: descriptor table entries are not released.
                    561:  */
                    562: SEG *
                    563: xdalloc( s )
                    564: fsize_t s;
                    565: {
                    566:        register SEG *sp1;
                    567:        register SEG *sp2;
                    568:        register daddr_t d;
                    569:        register daddr_t d1;
                    570:        register daddr_t d2;
                    571: 
                    572:        d  = s / BSIZE;
                    573:        d2 = swaptop;
                    574:        sp1 = &segdq;
                    575:        do {
                    576:                if ( (sp1 = sp1->s_back) != &segdq )
                    577:                        d1 = sp1->s_daddr + (sp1->s_size / BSIZE);
                    578:                else
                    579:                        d1 = swapbot;
                    580: 
                    581:                if ( d2 - d1 >= d ) {
                    582:                        sp2 = &segswap;
                    583:                        kclear( (char *)sp2, sizeof(SEG) );
                    584:                        sp1->s_forw->s_back = sp2;
                    585:                        sp2->s_forw  = sp1->s_forw;
                    586:                        sp1->s_forw  = sp2;
                    587:                        sp2->s_back  = sp1;
                    588:                        sp2->s_urefc = 1;
                    589:                        sp2->s_lrefc = 1;
                    590:                        sp2->s_size  = s;
                    591:                        sp2->s_daddr = d2 - d;
                    592:                        return( sp2 );
                    593:                }
                    594: 
                    595:                d2 = sp1->s_daddr;
                    596: 
                    597:        } while ( sp1 != &segdq );
                    598: 
                    599:        return( NULL );
                    600: }
                    601: 
                    602: /*
                    603:  * Allocate a segment in memory that is `n' bytes long.
                    604:  * The `seglink' gate should be locked before this routine is called.
                    605:  * This routine is the same as `smalloc' except that we can't run out of
                    606:  * alloc space to allocate the segment.
                    607:  * NOTE: Do NOT remap virtual descriptor table entry.
                    608:  *      This is a scratch entry, and the s_faddr field is not retained.
                    609:  */
                    610: SEG *
                    611: xmalloc( s )
                    612: register fsize_t s;
                    613: {
                    614:        register SEG *sp1;
                    615:        register SEG *sp2;
                    616:        register paddr_t s1;
                    617:        register paddr_t s2;
                    618: 
                    619:        s1  = corebot;
                    620:        sp1 = &segmq;
                    621:        do {
                    622:                if ( (sp1 = sp1->s_forw) != &segmq )
                    623:                        s2 = sp1->s_paddr;
                    624:                else
                    625:                        s2 = coretop;
                    626: 
                    627:                if ( s2 - s1 >= s ) {
                    628:                        sp2 = &segswap;
                    629:                        kclear( (char *)sp2, sizeof(SEG) );
                    630:                        sp1->s_back->s_forw = sp2;
                    631:                        sp2->s_back = sp1->s_back;
                    632:                        sp1->s_back = sp2;
                    633:                        sp2->s_forw = sp1;
                    634:                        sp2->s_urefc = 1;
                    635:                        sp2->s_lrefc = 1;
                    636:                        sp2->s_size  = s;
                    637:                        sp2->s_paddr = s1;
                    638:                        return( sp2 );
                    639:                }
                    640: 
                    641:                s1 = sp1->s_paddr + sp1->s_size;
                    642: 
                    643:        } while ( sp1 != &segmq );
                    644: 
                    645:        return( NULL );
                    646: }

unix.superglobalmegacorp.com

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