Annotation of coherent/b/kernel/coh.386/seg.c, revision 1.1

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

unix.superglobalmegacorp.com

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