Annotation of coherent/d/PS2_KERNEL/coh.386/seg.c, revision 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.