Annotation of coherent/d/PS2_KERNEL/coh.386/seg.c, revision 1.1.1.1

1.1       root        1: /* $Header: /v4a/coh/RCS/seg.c,v 1.2 92/01/06 12:00:15 hal 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:  * Segment manipulation.
                     18:  *
                     19:  */
                     20: #include <sys/coherent.h>
                     21: #include <sys/buf.h>
                     22: #include <errno.h>
                     23: #include <sys/ino.h>
                     24: #include <sys/inode.h>
                     25: #include <sys/proc.h>
                     26: #include <sys/sched.h>
                     27: #include <sys/seg.h>
                     28: #include <a.out.h>
                     29: 
                     30: 
                     31: #define        min(a, b)       ((a) < (b) ? (a) : (b))
                     32: 
                     33: /*
                     34:  * Initialisation code.
                     35:  */
                     36: seginit()
                     37: {
                     38:        /*
                     39:         * Create empty circular-list of memory segments.
                     40:         */
                     41:        segmq.s_forw = &segmq;
                     42:        segmq.s_back = &segmq;
                     43: 
                     44:        /*
                     45:         * Create empty circular-list of disk segments.
                     46:         */
                     47:        segdq.s_forw = &segdq;
                     48:        segdq.s_back = &segdq;
                     49: }
                     50: 
                     51: /*
                     52:  * Given an inode, `ip', and flags, `ff', describing a segment associated
                     53:  * with the inode, see if the segment already exists and if so, return a
                     54:  * copy.  If the segment does not exist, allocate the segment having size
                     55:  * `ss', and read the segment using the inode at seek offset `dq' with a
                     56:  * size of `ds'.
                     57:  */
                     58: SEG *
                     59: ssalloc(ip, ff, ss)
                     60: register INODE *ip;
                     61: {
                     62:        register SEG *sp;
                     63:        register int f;
                     64: 
                     65:        lock(seglink);
                     66:        f = ff & (SFSHRX|SFTEXT);
                     67: 
                     68:        /*
                     69:         * Look for the segment in the memory queue.
                     70:         */
                     71:        for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
                     72:                if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
                     73:                        unlock(seglink);
                     74:                        if ((sp = segdupl(sp)) != NULL)
                     75:                                segfinm(sp);
                     76:                        return (sp);
                     77:                }
                     78:        }
                     79: 
                     80:        /*
                     81:         * Look for the segment on the disk queue.
                     82:         */
                     83:        for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
                     84:                if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
                     85:                        unlock(seglink);
                     86:                        if ((sp = segdupl(sp)) != NULL)
                     87:                                segfinm(sp);
                     88:                        return (sp);
                     89:                }
                     90:        }
                     91:        unlock(seglink);
                     92: 
                     93:        /*
                     94:         * Allocate and create the segment.
                     95:         */
                     96:        return salloc(roundu(ss, NBPC), ff);
                     97: }
                     98: 
                     99: /*
                    100:  * Given a pointer to a newly created process, copy all of our segments
                    101:  * into the given process.
                    102:  */
                    103: segadup(cpp)
                    104: register PROC *cpp;
                    105: {
                    106:        register SEG *sp;
                    107:        register int n;
                    108:        register PROC *pp;
                    109: 
                    110:        pp = SELF;
                    111:        cpp->p_flags |= PFSWIO;
                    112:        for (n=0; n<NUSEG; n++) {
                    113:                if ((sp=pp->p_segp[n]) == NULL)
                    114:                        continue;
                    115:                if ((sp=segdupl(sp)) == NULL)
                    116:                        break;
                    117:                cpp->p_segp[n] = sp;
                    118:                if ((sp->s_flags&SFCORE) == 0)
                    119:                        cpp->p_flags &= ~PFCORE;
                    120:        }
                    121:        if (n < NUSEG) {
                    122:                while (n > 0) {
                    123:                        if ((sp=cpp->p_segp[--n]) != NULL) {
                    124:                                cpp->p_segp[n] = NULL;
                    125:                                sfree(sp);
                    126:                        }
                    127:                }
                    128:        }
                    129:        cpp->p_flags &= ~PFSWIO;
                    130:        return (n);
                    131: }
                    132: 
                    133: /*
                    134:  * Duplicate a segment.
                    135:  */
                    136: SEG *
                    137: segdupl(sp)
                    138: register SEG *sp;
                    139: {
                    140:        register SEG *sp1;
                    141: 
                    142:        if ((sp->s_flags&SFSHRX) != 0) {
                    143:                sp->s_urefc++;
                    144:                sp->s_lrefc++;
                    145:                return (sp);
                    146:        }
                    147:        if ((sp->s_flags&SFCORE) == 0)
                    148:                panic("Cannot duplicate non shared swapped segment");
                    149:        if ((sp1=salloc(sp->s_size, sp->s_flags|SFNSWP|SFNCLR)) == NULL)
                    150:                sp1 = segdupd(sp);
                    151:        else {
                    152:                sp1->s_flags = sp->s_flags;
                    153:                dmacopy( btoc(sp->s_size), sp->s_vmem, sp1->s_vmem) ;
                    154:        }
                    155:        return sp1;
                    156: }
                    157: 
                    158: /*
                    159:  * Allocate a segment `bytes_wanted' bytes long.
                    160:  * `flags' contains some pseudo flags.
                    161:  */
                    162: SEG *
                    163: salloc(bytes_wanted, flags)
                    164: int bytes_wanted, flags;
                    165: {
                    166:        register SEG *sp;
                    167:        register int r;
                    168: 
                    169:        r = (flags & (SFSYST|SFTEXT|SFSHRX|SFDOWN)) | SFCORE;
                    170: 
                    171: /*
                    172: #ifdef _I386
                    173:        bytes_wanted += (sizeof(char *) - 1);
                    174:        bytes_wanted &= ~(sizeof(char *) - 1);
                    175: #else
                    176:        bytes_wanted += (BSIZE - 1);
                    177:        bytes_wanted &= ~(BSIZE - 1);
                    178: #endif
                    179: */
                    180: 
                    181:        lock(seglink);
                    182:        sp = smalloc(bytes_wanted);
                    183:        unlock(seglink);
                    184: 
                    185:        if (sp) {
                    186:                sp->s_flags = r;
                    187:        } else {
                    188: #if 0
                    189:                /* no room now - let the swapper try to grow it */
                    190:                if (flags & SFNSWP)
                    191:                        return 0;
                    192:                if ((sp=kalloc(sizeof(SEG))) == NULL)
                    193:                        return 0;
                    194:                sp->s_forw = sp;
                    195:                sp->s_back = sp;
                    196:                sp->s_flags = r;
                    197:                sp->s_urefc = 1;
                    198:                sp->s_lrefc = 1;
                    199:                if (segsext(sp, bytes_wanted) == NULL) {
                    200:                        kfree(sp);
                    201:                        return 0;
                    202:                }
                    203: #else
                    204:                return 0;
                    205: #endif
                    206:        }
                    207:        if ((flags&SFNCLR) == 0)
                    208:                dmaclear(sp->s_size, MAPIO(sp->s_vmem, 0), 0L);
                    209:        return sp;
                    210: }
                    211: 
                    212: /*
                    213:  * Free the given segment pointer.
                    214:  */
                    215: sfree(sp)
                    216: register SEG *sp;
                    217: {
                    218:        register INODE *ip;
                    219: 
                    220:        if ( sp->s_urefc != 1 ) {
                    221:                sp->s_urefc--;
                    222:                sp->s_lrefc--;
                    223:                return;
                    224:        }
                    225: 
                    226:        lock(seglink);
                    227:        --sp->s_lrefc;
                    228:        if (--sp->s_urefc != 0) {
                    229:                unlock(seglink);
                    230:                return;
                    231:        }
                    232: 
                    233:        sp->s_back->s_forw = sp->s_forw;
                    234:        sp->s_forw->s_back = sp->s_back;
                    235: 
                    236:        c_free(sp->s_vmem, btoc(sp->s_size));
                    237: 
                    238:        unlock(seglink);
                    239: 
                    240:        if (sp->s_lrefc != 0)
                    241:                panic("Bad segment count");
                    242:        if ((ip=sp->s_ip) != NULL)
                    243:                ldetach(ip);
                    244:        kfree(sp);
                    245: }
                    246: 
                    247: /*
                    248:  * Grow or shrink the segment `sp' so that it has size `new_bytes' bytes.
                    249:  * 
                    250:  * downward growing segments not done yet!
                    251:  */
                    252: seggrow(sp, new_bytes)
                    253: register SEG *sp;
                    254: unsigned int new_bytes;
                    255: {
                    256:        register SEG *sp1;
                    257:        register int dowflag;
                    258:        unsigned int    old_bytes, common_clicks;
                    259: 
                    260:        dowflag = sp->s_flags & SFDOWN;
                    261:        old_bytes = sp->s_size;
                    262: 
                    263:        T_HAL(0x20, goto dont_c_grow);
                    264:        /*
                    265:         * If we want a larger segment AND c_grow() succeeds
                    266:         *      boost segment size to new_bytes
                    267:         */
                    268:        if (new_bytes >= old_bytes && c_grow(sp, new_bytes)==0) {
                    269:                T_HAL(0x100, printf("c_grow(%d) ", new_bytes));
                    270:                sp->s_size = new_bytes;
                    271:                dmaclear(new_bytes - old_bytes,
                    272:                  MAPIO(sp->s_vmem, old_bytes), 0);
                    273:                return 1;
                    274:        }
                    275: dont_c_grow:
                    276: 
                    277:        if (sp1 = salloc(new_bytes, (sp->s_flags|SFNSWP|SFNCLR))) {
                    278:                T_HAL(0x100, printf("salloc(%d) ", new_bytes));
                    279:                if (dowflag == 0) {
                    280:                        common_clicks = btoc(min(new_bytes, old_bytes));
                    281:                        dmacopy(common_clicks, sp->s_vmem, sp1->s_vmem);
                    282:                        if (new_bytes > old_bytes) {
                    283:                                dmaclear(new_bytes - old_bytes,
                    284:                                  MAPIO(sp1->s_vmem, old_bytes), 0);
                    285:                        }
                    286:                } else
                    287:                        panic("downflag");
                    288:                lock(seglink);
                    289:                c_free(sp->s_vmem, btoc(old_bytes));
                    290:                satcopy(sp, sp1);
                    291:                unlock(seglink);
                    292: 
                    293:                return 1;
                    294:        }
                    295: 
                    296: #if 1
                    297:        return 0;
                    298: #else
                    299:        /*
                    300:         * Last chance.  Extend the segment by swapping it.
                    301:         */
                    302:        if (!segsext(sp, new_bytes))
                    303:                return 0;
                    304: 
                    305:        if (dowflag == 0) {
                    306:                if (new_bytes > old_bytes)
                    307:                        dmaclear(new_bytes - old_bytes, MAPIO(sp->s_vmem,old_bytes), 0);
                    308:        } else
                    309:                panic("downflag");
                    310: 
                    311:        return (1);
                    312: #endif
                    313: }
                    314: 
                    315: /*
                    316:  * Given a segment pointer, `sp' and a segment size, grow the given segment
                    317:  * to the given size.
                    318:  */
                    319: segsize(sp, s2)
                    320: register SEG *sp;
                    321: vaddr_t s2;
                    322: {
                    323:        register vaddr_t s1;
                    324: 
                    325:        s1 = (vaddr_t) sp->s_size;
                    326:        if (s2 == 0 || seggrow(sp, (off_t)s2) == 0) {
                    327:                SET_U_ERROR( ENOMEM, "can not grow segment" );
                    328:                return;
                    329:        }
                    330:        if (sproto(0) == 0) {
                    331:                if (seggrow(sp, (off_t)s1)==0 || sproto(0)==0) {
                    332:                        T_PIGGY( 0x2000000, printf("auto SEGV\n"); );
                    333:                        sendsig(SIGSEGV, SELF);
                    334:                }
                    335:        }
                    336:        segload();
                    337: }
                    338: 
                    339: /*
                    340:  * Grow the segment `sp1' to the size `s' in bytes by swapping it out
                    341:  * and back in.  The segment may not be locked.
                    342:  */
                    343: SEG *
                    344: segsext(sp1, s)
                    345: register SEG *sp1;
                    346: register off_t s;
                    347: {
                    348: #if 0
                    349:        register SEG *sp2;
                    350: 
                    351: #if    MONITOR
                    352:        if (swmflag)
                    353:                printf("Segsext(%p, %u)\n", SELF, SELF->p_pid);
                    354: #endif
                    355:        if (sexflag == 0) {
                    356:                SET_U_ERROR( ENOMEM, "can not extend, swapping is off" );
                    357:                return (NULL);
                    358:        }
                    359:        lock(seglink);
                    360:        if ((sp2=sdalloc(s)) == NULL) {
                    361:                unlock(seglink);
                    362:                return (NULL);
                    363:        }
                    364:        unlock(seglink);
                    365:        sp1->s_lrefc++;
                    366:        if (sp1->s_size != 0)
                    367:                swapio(1, MAPIO(sp1->s_vmem, 0), sp2->s_daddr, sp1->s_size);
                    368:        lock(seglink);
                    369:        satcopy(sp1, sp2);
                    370:        unlock(seglink);
                    371:        sp1->s_flags &= ~SFCORE;
                    372:        sp1->s_lrefc--;
                    373:        segfinm(sp1);
                    374:        return (sp1);
                    375: #else
                    376:        return 0;
                    377: #endif
                    378: }
                    379: 
                    380: /*
                    381:  * Force the given segment to be in memory.  One can only force
                    382:  * one segment to be in memory at a time.
                    383:  */
                    384: segfinm(sp)
                    385: register SEG *sp;
                    386: {
                    387:        register PROC *pp;
                    388:        register int s;
                    389: 
                    390:        if ((sp->s_flags&SFCORE) != 0)
                    391:                return;
                    392:        pp = SELF;
                    393:        sp->s_urefc++;
                    394:        sp->s_lrefc++;
                    395:        pp->p_segp[SIAUXIL] = sp;
                    396:        pp->p_flags &= ~PFCORE;
                    397: #ifndef QWAKEUP
                    398:        s = sphi();
                    399: #endif
                    400:        setrun(pp);
                    401:        dispatch();
                    402: #ifndef QWAKEUP
                    403:        spl(s);
                    404: #endif
                    405:        pp->p_segp[SIAUXIL] = NULL;
                    406:        sfree(sp);
                    407: }
                    408: 
                    409: /*
                    410:  * Make a copy of the segment `sp1' which is in memory by writing
                    411:  * it out to disk.
                    412:  */
                    413: SEG *
                    414: segdupd(sp1)
                    415: register SEG *sp1;
                    416: {
                    417:        register SEG *sp2;
                    418: 
                    419:        if (sexflag == 0)
                    420:                return (NULL);
                    421:        lock(seglink);
                    422:        if ((sp2=sdalloc(sp1->s_size)) == NULL) {
                    423:                unlock(seglink);
                    424:                return (NULL);
                    425:        }
                    426:        sp1->s_lrefc++;
                    427:        unlock(seglink);
                    428:        swapio(1, MAPIO(sp1->s_vmem, 0), sp2->s_daddr, sp1->s_size);
                    429:        sp1->s_lrefc--;
                    430:        sp2->s_flags = sp1->s_flags & ~SFCORE;
                    431:        sp2->s_size  = sp1->s_size;
                    432:        return (sp2);
                    433: }
                    434: 
                    435: /*
                    436:  * Given a flag, a physical core address, a disk address and a count in
                    437:  * bytes, perform an I/O operation between core and disk.  If `flag' is
                    438:  * set, the transfer is to the disk otherwise it is to memory.  As you may
                    439:  * have guessed, this is used by the swapper.
                    440:  *
                    441:  */
                    442: swapio(f, p, d, n)
                    443: paddr_t p;
                    444: daddr_t d;
                    445: off_t  n;
                    446: {
                    447:        register BUF * bp;
                    448:        register SEG * sp;
                    449:        register int s;
                    450:        register int nb;
                    451: 
                    452: #if    MONITOR
                    453:        if (swmflag > 1)
                    454:                printf("swapio(%s,%x,%x,%x)\n",f?"out":"in",(int)p,(int)d,n);
                    455: #endif
                    456:        if (d < swapbot || d+(n/BSIZE) > swaptop)
                    457:                panic("Swapio bad parameter");
                    458: 
                    459:        bp = &swapbuf;
                    460:        lock(bp->b_gate);
                    461:        SELF->p_flags |= PFSWIO;
                    462:        bp->b_paddr = p;
                    463: 
                    464:        while (n != 0) {
                    465:                nb = (n > SCHUNK) ? SCHUNK : n;
                    466:                /*
                    467:                 * Prevent I/O transfer from crossing 64 Kbyte boundary.
                    468:                 */
                    469:                if ( (p & 0xFFFF0000L) != ((p+nb) & 0xFFFF0000L) )
                    470:                        nb = 0x10000L - (p & 0x0000FFFFL);
                    471:                bp->b_flag  = BFNTP;
                    472:                bp->b_req   = f ? BWRITE : BREAD;
                    473:                bp->b_dev   = swapdev;
                    474:                bp->b_bno   = d;
                    475:                bp->b_paddr = p;
                    476:                bp->b_count = nb;
                    477:                s = sphi();
                    478:                dblock(swapdev, bp);
                    479:                while ((bp->b_flag&BFNTP) != 0) {
                    480:                        v_sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO, "swap");
                    481:                        /* Sleeping in the swapper.  */
                    482:                }
                    483:                spl(s);
                    484:                if ((bp->b_flag&BFERR) != 0)
                    485:                        panic("Swapio error");
                    486:                bp->b_vaddr += nb;
                    487:                p += nb;
                    488:                d += nb / BSIZE;
                    489:                n -= nb;
                    490:        }
                    491:        unlock(bp->b_gate);
                    492:        SELF->p_flags &= ~PFSWIO;
                    493: }
                    494: 
                    495: /*
                    496:  * Make the segment descriptor pointed to by `sp1' have the attributes
                    497:  * of `sp2' including it's position in the segment queue and release
                    498:  * `sp2'.  `seglink' must be locked when this routine is called.
                    499:  */
                    500: satcopy(sp1, sp2)
                    501: register SEG *sp1;
                    502: register SEG *sp2;
                    503: {
                    504:        sp1->s_back->s_forw = sp1->s_forw;
                    505:        sp1->s_forw->s_back = sp1->s_back;
                    506:        sp2->s_back->s_forw = sp1;
                    507:        sp1->s_back = sp2->s_back;
                    508:        sp2->s_forw->s_back = sp1;
                    509:        sp1->s_forw  = sp2->s_forw;
                    510:        sp1->s_daddr = sp2->s_daddr;
                    511:        sp1->s_size = sp2->s_size;
                    512:        sp1->s_vmem = sp2->s_vmem;
                    513:        kfree(sp2);
                    514: }
                    515: 
                    516: /*
                    517:  * Allocate a segment on disk that is `n' bytes long.
                    518:  * The `seglink' gate should be locked before this routine is called.
                    519:  */
                    520: SEG *
                    521: sdalloc( s )
                    522: off_t s;
                    523: {
                    524:        register SEG *sp1;
                    525:        register SEG *sp2;
                    526:        register daddr_t d;
                    527:        register daddr_t d1;
                    528:        register daddr_t d2;
                    529: 
                    530:        d  = s / BSIZE;
                    531:        d1 = swapbot;
                    532:        sp1 = &segdq;
                    533:        do {
                    534:                if (d1 >= swaptop)
                    535:                        return (NULL);
                    536:                if ((sp1=sp1->s_forw) != &segdq)
                    537:                        d2 = sp1->s_daddr;
                    538:                else
                    539:                        d2 = swaptop;
                    540:                if (d2-d1 >= d) {
                    541:                        if ((sp2=kalloc(sizeof(SEG))) == NULL)
                    542:                                return (NULL);
                    543:                        sp1->s_back->s_forw = sp2;
                    544:                        sp2->s_back = sp1->s_back;
                    545:                        sp1->s_back = sp2;
                    546:                        sp2->s_forw = sp1;
                    547:                        sp2->s_urefc = 1;
                    548:                        sp2->s_lrefc = 1;
                    549:                        sp2->s_size  = s;
                    550:                        sp2->s_daddr = d1;
                    551:                        return (sp2);
                    552:                }
                    553:                d1 = sp1->s_daddr + (sp1->s_size / BSIZE);
                    554:        } while (sp1 != &segdq);
                    555:        return (NULL);
                    556: }
                    557: 
                    558: /*
                    559:  * Allocate a segment in memory that is `bytes_wanted' bytes long.
                    560:  * The `seglink' gate should be locked before this routine is called.
                    561:  *
                    562:  * if successful, return allocated SEG *
                    563:  * else, return 0
                    564:  */
                    565: SEG *
                    566: smalloc(bytes_wanted)
                    567: off_t bytes_wanted;
                    568: {
                    569:        register SEG *sp1;
                    570:        register SEG *new_seg;
                    571:        unsigned        clicks_wanted;
                    572: 
                    573:        clicks_wanted = btoc(bytes_wanted);
                    574: 
                    575:        /*
                    576:         * Estimate space needed for new segment and its overhead.
                    577:         * Fail if not enough free RAM available.
                    578:         */
                    579:        if (countsize(clicks_wanted) > allocno())
                    580:                return 0;
                    581:        /*
                    582:         * Allocate a new SEG struct to keep track of the segment, if possible.
                    583:         */
                    584:        if ((new_seg = kalloc(sizeof (SEG))) == NULL)
                    585:                return 0;
                    586: 
                    587:        if ((new_seg->s_vmem = c_alloc(clicks_wanted)) == 0) {
                    588:                kfree(new_seg);
                    589:                return 0;
                    590:        }
                    591: 
                    592:        /* link new_seg in at start of segmq */
                    593:        sp1 = segmq.s_forw;
                    594:        sp1->s_back->s_forw = new_seg;
                    595:        new_seg->s_back = sp1->s_back;
                    596:        sp1->s_back = new_seg;
                    597:        new_seg->s_forw = sp1;
                    598: 
                    599:        new_seg->s_urefc = 1;
                    600:        new_seg->s_lrefc = 1;
                    601:        new_seg->s_size  = bytes_wanted;
                    602: 
                    603:        return new_seg;
                    604: }
                    605: 
                    606: /*
                    607:  * Set up `SR' structure in user area from segments descriptors in
                    608:  * process structure.  Also set up the user segmentation registers.
                    609:  */
                    610: sproto(xhp)
                    611: struct xechdr *xhp;
                    612: {
                    613:        register int n;
                    614:        register SEG *sp;
                    615: 
                    616:        for (n=0; n<NUSEG; n++) {
                    617:                u.u_segl[n].sr_flag = u.u_segl[n].sr_size = 0;
                    618:                u.u_segl[n].sr_segp = 0;
                    619:                if ((sp=SELF->p_segp[n]) == NULL)
                    620:                        continue;
                    621:                if (n == SIUSERP)
                    622:                        u.u_segl[n].sr_base = &u;
                    623:                else {
                    624:                        if (xhp)
                    625:                                u.u_segl[n].sr_base = xhp->segs[n].mbase;
                    626:                        u.u_segl[n].sr_flag |= SRFPMAP;
                    627:                }
                    628:                if (n!=SISTEXT)
                    629:                        u.u_segl[n].sr_flag |= SRFDUMP;
                    630:                if (n!=SIUSERP && n!=SISTEXT)
                    631:                        u.u_segl[n].sr_flag |= SRFDATA;
                    632:                u.u_segl[n].sr_size = sp->s_size;
                    633:                u.u_segl[n].sr_segp = sp;
                    634:        }
                    635:        return (mproto());
                    636: }
                    637: 
                    638: /*
                    639:  * Search for a busy text inode.
                    640:  */
                    641: sbusy(ip)
                    642: register INODE *ip;
                    643: {
                    644:        register SEG *sp;
                    645: 
                    646:        lock(seglink);
                    647:        /*
                    648:         * Look for the segment in the memory queue.
                    649:         */
                    650:        for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
                    651:                if (sp->s_ip==ip
                    652:                 && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
                    653:                        unlock(seglink);
                    654:                        return (1);
                    655:                }
                    656:        }
                    657: 
                    658:        /*
                    659:         * Look for the segment on the disk queue.
                    660:         */
                    661:        for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
                    662:                if (sp->s_ip==ip
                    663:                 && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
                    664:                        unlock(seglink);
                    665:                        return (1);
                    666:                }
                    667:        }
                    668:        unlock(seglink);
                    669:        return 0;
                    670: }
                    671: 
                    672: /*
                    673:  * Segment consistency checks for the paranoid.
                    674: segchk()
                    675: {
                    676:        register SEG *sp;
                    677:        register int nbad;
                    678:        off_t s;
                    679:        daddr_t d;
                    680: 
                    681:        nbad = 0;
                    682:        sp = &segdq;
                    683:        d = swapbot;
                    684:        while ((sp=sp->s_forw) != &segdq) {
                    685:                if (sp->s_daddr < d)
                    686:                        nbad += badseg("disk", (int)sp->s_daddr, 0);
                    687:                d = sp->s_daddr + (sp->s_size / BSIZE);
                    688:        }
                    689:        if (swaptop < d)
                    690:                nbad += badseg("disk", sp->s_back->s_daddr, sp->s_back->s_size);
                    691: }
                    692: 
                    693: badseg(t, b, s)
                    694: char *t;
                    695: daddr_t b;
                    696: off_t s;
                    697: {
                    698:        printf( "Bad %s segment at %X of len %X\n", t, b, s );
                    699:        return (1);
                    700: }
                    701: */

unix.superglobalmegacorp.com

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