Annotation of coherent/d/286_KERNEL/USRSRC/ldrv/ldswap.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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