Annotation of coherent/d/286_KERNEL/USRSRC/coh/seg.c, revision 1.1

1.1     ! root        1: /* $Header: /newbits/286_KERNEL/USRSRC/coh/RCS/seg.c,v 1.1 92/01/09 13:29:05 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:  * $Log:       seg.c,v $
        !            20:  * Revision 1.1  92/01/09  13:29:05  bin
        !            21:  * Initial revision
        !            22:  * 
        !            23:  * Revision 1.1        88/03/24  16:14:20      src
        !            24:  * Initial revision
        !            25:  * 
        !            26:  * 88/02/26    Allan Cornish   /usr/src/sys/coh/seg.c
        !            27:  * swapio() now avoids 64 Kbyte page [dma] straddles.
        !            28:  *
        !            29:  * 88/01/22    Allan Cornish   /usr/src/sys/coh/seg.c
        !            30:  * salloc() now invokes krunch(1000) if initial allocation fails.
        !            31:  * sfree() now invokes krunch(0).
        !            32:  *
        !            33:  * 88/01/21    Allan Cornish   /usr/src/sys/coh/seg.c
        !            34:  * sfree() modified to eliminate critical race on ref cnts and segment gate.
        !            35:  * segfinm() now properly maintains segment reference counts.
        !            36:  *
        !            37:  * 87/11/13    Allan Cornish   /usr/src/sys/coh/seg.c
        !            38:  * Support for protected mode segmentation added.
        !            39:  */
        !            40: #include <sys/coherent.h>
        !            41: #include <sys/buf.h>
        !            42: #include <errno.h>
        !            43: #include <sys/ino.h>
        !            44: #include <sys/inode.h>
        !            45: #include <sys/proc.h>
        !            46: #include <sys/sched.h>
        !            47: #include <sys/seg.h>
        !            48: #include <sys/uproc.h>
        !            49: 
        !            50: /*
        !            51:  * Initialisation code.
        !            52:  */
        !            53: seginit()
        !            54: {
        !            55:        /*
        !            56:         * Create empty circular-list of memory segments.
        !            57:         */
        !            58:        segmq.s_forw = &segmq;
        !            59:        segmq.s_back = &segmq;
        !            60: 
        !            61:        /*
        !            62:         * Create empty circular-list of disk segments.
        !            63:         */
        !            64:        segdq.s_forw = &segdq;
        !            65:        segdq.s_back = &segdq;
        !            66: 
        !            67:        if ( holebot != holetop ) {
        !            68:                /*
        !            69:                 * Define the I/O mem hole between low memory and extended mem.
        !            70:                 * NOTE: Setting lrefc to urefc+1 stopx segment from moving.
        !            71:                 */
        !            72:                segiom.s_paddr = holebot;
        !            73:                segiom.s_size  = holetop - holebot;
        !            74:                segiom.s_flags = SFCORE | SFSYST;
        !            75:                segiom.s_urefc = 1;
        !            76:                segiom.s_lrefc = 2;
        !            77: 
        !            78:                /*
        !            79:                 * Insert I/O memory segment into memory list.
        !            80:                 */
        !            81:                segiom.s_forw = &segmq;
        !            82:                segiom.s_back = &segmq;
        !            83:                segmq.s_forw  = &segiom;
        !            84:                segmq.s_back  = &segiom;
        !            85:        }
        !            86: }
        !            87: 
        !            88: /*
        !            89:  * Given an inode, `ip', and flags, `ff', describing a segment associated
        !            90:  * with the inode, see if the segment already exists and if so, return a
        !            91:  * copy.  If the segment does not exists, allocate the segment having size
        !            92:  * `ss', and read the segment using the inode at seek offset `dq' with a
        !            93:  * size of `ds'.
        !            94:  */
        !            95: SEG *
        !            96: ssalloc(rp, ip, ff, ss, dq, ds)
        !            97: int *rp;
        !            98: register INODE *ip;
        !            99: fsize_t ss;
        !           100: fsize_t dq;
        !           101: fsize_t ds;
        !           102: {
        !           103:        register SEG *sp;
        !           104:        register int f;
        !           105: 
        !           106:        *rp = -1;
        !           107:        if (ss == 0) {
        !           108:                *rp = 1;
        !           109:                return (NULL);
        !           110:        }
        !           111:        lock(seglink);
        !           112:        f = ff & (SFSHRX|SFTEXT);
        !           113: 
        !           114:        /*
        !           115:         * Look for the segment in the memory queue.
        !           116:         */
        !           117:        for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
        !           118:                if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
        !           119:                        unlock(seglink);
        !           120:                        if ((sp = segdupl(sp)) != NULL) {
        !           121:                                segfinm(sp);
        !           122:                                *rp = 1;
        !           123:                        }
        !           124:                        return (sp);
        !           125:                }
        !           126:        }
        !           127: 
        !           128:        /*
        !           129:         * Look for the segment on the disk queue.
        !           130:         */
        !           131:        for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
        !           132:                if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
        !           133:                        unlock(seglink);
        !           134:                        if ((sp = segdupl(sp)) != NULL) {
        !           135:                                segfinm(sp);
        !           136:                                *rp = 1;
        !           137:                        }
        !           138:                        return (sp);
        !           139:                }
        !           140:        }
        !           141:        unlock(seglink);
        !           142: 
        !           143:        /*
        !           144:         * Allocate and create the segment.
        !           145:         */
        !           146:        if ((sp=salloc(ss, ff)) == NULL)
        !           147:                return (NULL);
        !           148:        if (exsread(sp, ip, ds, dq, (fsize_t)0) == 0) {
        !           149:                sfree(sp);
        !           150:                return (NULL);
        !           151:        }
        !           152:        if ((ff&SFSHRX) != 0) {
        !           153:                sp->s_ip = ip;
        !           154:                ip->i_refc++;
        !           155:        }
        !           156:        *rp = 0;
        !           157:        return (sp);
        !           158: }
        !           159: 
        !           160: /*
        !           161:  * Given a pointer to a newly created process, copy all of our segments
        !           162:  * into the given process.
        !           163:  */
        !           164: segadup(cpp)
        !           165: register PROC *cpp;
        !           166: {
        !           167:        register SEG *sp;
        !           168:        register int n;
        !           169:        register PROC *pp;
        !           170: 
        !           171:        pp = SELF;
        !           172:        cpp->p_flags |= PFSWIO;
        !           173:        for (n=0; n<NUSEG; n++) {
        !           174:                if ((sp=pp->p_segp[n]) == NULL)
        !           175:                        continue;
        !           176:                if ((sp=segdupl(sp)) == NULL)
        !           177:                        break;
        !           178:                cpp->p_segp[n] = sp;
        !           179:                if ((sp->s_flags&SFCORE) == 0)
        !           180:                        cpp->p_flags &= ~PFCORE;
        !           181:        }
        !           182:        if (n < NUSEG) {
        !           183:                while (n > 0) {
        !           184:                        if ((sp=cpp->p_segp[--n]) != NULL) {
        !           185:                                cpp->p_segp[n] = NULL;
        !           186:                                sfree(sp);
        !           187:                        }
        !           188:                }
        !           189:        }
        !           190:        cpp->p_flags &= ~PFSWIO;
        !           191:        return (n);
        !           192: }
        !           193: 
        !           194: /*
        !           195:  * Duplicate a segment.
        !           196:  */
        !           197: SEG *
        !           198: segdupl(sp)
        !           199: register SEG *sp;
        !           200: {
        !           201:        register SEG *sp1;
        !           202: 
        !           203:        if ((sp->s_flags&SFSHRX) != 0) {
        !           204:                sp->s_urefc++;
        !           205:                sp->s_lrefc++;
        !           206:                return (sp);
        !           207:        }
        !           208:        if ((sp->s_flags&SFCORE) == 0)
        !           209:                panic("Cannot duplicate non shared swapped segment");
        !           210:        if ((sp1=salloc(sp->s_size, sp->s_flags|SFNSWP|SFNCLR)) == NULL)
        !           211:                sp1 = segdupd(sp);
        !           212:        else {
        !           213:                sp1->s_flags = sp->s_flags;
        !           214:                plrcopy( sp->s_paddr, sp1->s_paddr, sp->s_size );
        !           215:        }
        !           216:        return (sp1);
        !           217: }
        !           218: 
        !           219: /*
        !           220:  * Allocate a segment `n' bytes long.  `f' contains some pseudo flags.
        !           221:  */
        !           222: SEG *
        !           223: salloc(n, f)
        !           224: fsize_t n;
        !           225: {
        !           226:        register SEG *sp;
        !           227:        register int r;
        !           228: 
        !           229:        r = (f&(SFSYST|SFHIGH|SFTEXT|SFSHRX|SFDOWN)) | SFCORE;
        !           230:        n +=  (BSIZE-1);
        !           231:        n &= ~(BSIZE-1);
        !           232: 
        !           233:        lock(seglink);
        !           234:        sp = sxalloc(n, f);
        !           235:        unlock(seglink);
        !           236: 
        !           237:        if ( sp == NULL ) {
        !           238:                krunch(1000);
        !           239:                lock(seglink);
        !           240:                sp = sxalloc(n, f);
        !           241:                unlock(seglink);
        !           242:        }
        !           243: 
        !           244:        if (sp != NULL) {
        !           245:                sp->s_flags = r;
        !           246:                vremap( sp );
        !           247:        }
        !           248:        else {
        !           249:                if ((f&SFNSWP) != 0)
        !           250:                        return (NULL);
        !           251:                if ((sp=kalloc(sizeof(SEG))) == NULL)
        !           252:                        return (NULL);
        !           253:                sp->s_forw = sp;
        !           254:                sp->s_back = sp;
        !           255:                sp->s_flags = r;
        !           256:                sp->s_urefc = 1;
        !           257:                sp->s_lrefc = 1;
        !           258:                if (segsext(sp, n) == NULL) {
        !           259:                        kfree(sp);
        !           260:                        return (NULL);
        !           261:                }
        !           262:        }
        !           263:        if ((f&SFNCLR) == 0)
        !           264:                pclear( sp->s_paddr, n );
        !           265:        return (sp);
        !           266: }
        !           267: 
        !           268: /*
        !           269:  * Free the given segment pointer.
        !           270:  */
        !           271: sfree(sp)
        !           272: register SEG *sp;
        !           273: {
        !           274:        register INODE *ip;
        !           275: 
        !           276:        if ( sp->s_urefc != 1 ) {
        !           277:                sp->s_urefc--;
        !           278:                sp->s_lrefc--;
        !           279:                return;
        !           280:        }
        !           281: 
        !           282:        lock(seglink);
        !           283:        --sp->s_lrefc;
        !           284:        if (--sp->s_urefc != 0) {
        !           285:                unlock(seglink);
        !           286:                return;
        !           287:        }
        !           288: 
        !           289:        sp->s_back->s_forw = sp->s_forw;
        !           290:        sp->s_forw->s_back = sp->s_back;
        !           291:        unlock(seglink);
        !           292: 
        !           293:        if (sp->s_lrefc != 0)
        !           294:                panic("Bad segment count");
        !           295:        if ((ip=sp->s_ip) != NULL)
        !           296:                ldetach(ip);
        !           297:        vrelse( sp->s_faddr );
        !           298:        kfree(sp);
        !           299:        krunch(0);
        !           300: }
        !           301: 
        !           302: /*
        !           303:  * Grow or shrink the segment `sp' so that it has size `n'.
        !           304:  */
        !           305: seggrow(sp, n)
        !           306: register SEG *sp;
        !           307: fsize_t n;
        !           308: {
        !           309:        register SEG *sp1;
        !           310:        register fsize_t  d;
        !           311:        register paddr_t pb;
        !           312:        register paddr_t nb;
        !           313:        register int dowflag;
        !           314: 
        !           315:        dowflag = sp->s_flags&SFDOWN;
        !           316: 
        !           317:        /*
        !           318:         * Size of new segment is smaller or the same size as the old
        !           319:         * segment.
        !           320:         */
        !           321:        lock(seglink);
        !           322:        d = n - sp->s_size;
        !           323:        if (n <= sp->s_size) {
        !           324:                sp->s_size = n;
        !           325:                if (dowflag)
        !           326:                        sp->s_paddr -= d;
        !           327: 
        !           328:                vremap( sp );
        !           329:                unlock(seglink);
        !           330:                return (1);
        !           331:        }
        !           332: 
        !           333:        if ((sp1=sp->s_back) == &segmq)
        !           334:                pb = corebot;
        !           335:        else
        !           336:                pb = sp1->s_paddr + sp1->s_size;
        !           337: 
        !           338:        if ((sp1=sp->s_forw) == &segmq)
        !           339:                nb = coretop;
        !           340:        else
        !           341:                nb = sp1->s_paddr;
        !           342: 
        !           343:        /*
        !           344:         * If the segment does not grow down, see if there is enough
        !           345:         * space after the segment.
        !           346:         */
        !           347:        if (dowflag==0 && nb-sp->s_paddr>=n) {
        !           348:                pclear(sp->s_paddr+sp->s_size, d);
        !           349:                sp->s_size = n;
        !           350:                vremap( sp );
        !           351:                unlock(seglink);
        !           352:                return (1);
        !           353:        }
        !           354: 
        !           355:        /*
        !           356:         * If the segment grows down, see if there is enough space
        !           357:         * before the segment.
        !           358:         */
        !           359:        if (dowflag!=0 && sp->s_paddr+sp->s_size-pb>=n) {
        !           360:                sp->s_paddr -= d;
        !           361:                sp->s_size   = n;
        !           362:                pclear( sp->s_paddr, d );
        !           363:                vremap( sp );
        !           364:                unlock(seglink);
        !           365:                return (1);
        !           366:        }
        !           367: 
        !           368:        /*
        !           369:         * Is there enough space in total counting the gaps on either
        !           370:         * side of us?
        !           371:         */
        !           372:        if (nb-pb >= n) {
        !           373:                if (dowflag == 0) {
        !           374:                        plrcopy(sp->s_paddr, pb, sp->s_size);
        !           375:                        pclear(pb+sp->s_size, d);
        !           376:                        sp->s_paddr = pb;
        !           377:                } else {
        !           378:                        prlcopy( sp->s_paddr, nb-sp->s_size, sp->s_size );
        !           379:                        pclear(nb-n, d);
        !           380:                        sp->s_paddr = nb-n;
        !           381:                }
        !           382:                sp->s_size  = n;
        !           383:                vremap( sp );
        !           384:                unlock(seglink);
        !           385:                return (1);
        !           386:        }
        !           387: 
        !           388:        /*
        !           389:         * Try to allocate a segment somewhere else on the segment queue
        !           390:         * and copy ourselves there.
        !           391:         */
        !           392:        unlock(seglink);
        !           393:        if ((sp1=salloc((fsize_t)n, sp->s_flags|SFNSWP|SFNCLR)) != NULL) {
        !           394:                if (dowflag == 0) {
        !           395:                        plrcopy(sp->s_paddr, sp1->s_paddr, sp->s_size);
        !           396:                        pclear(sp1->s_paddr+sp->s_size, d);
        !           397:                } else {
        !           398:                        plrcopy(sp->s_paddr, sp1->s_paddr+d, sp->s_size);
        !           399:                        pclear(sp1->s_paddr, d);
        !           400:                }
        !           401:                lock(seglink);
        !           402:                satcopy(sp, sp1);
        !           403:                unlock(seglink);
        !           404:                return (1);
        !           405:        }
        !           406: 
        !           407:        /*
        !           408:         * Last chance.  Extend the segment by swapping it.
        !           409:         */
        !           410:        if (segsext(sp, n) != NULL) {
        !           411:                if (dowflag == 0)
        !           412:                        pclear(sp->s_paddr+n-d, d);
        !           413:                else {
        !           414:                        prlcopy(sp->s_paddr, sp->s_paddr+d, n-d);
        !           415:                        pclear(sp->s_paddr, d);
        !           416:                }
        !           417:                return (1);
        !           418:        }
        !           419: 
        !           420:        /*
        !           421:         * At least we tried.
        !           422:         */
        !           423:        return (0);
        !           424: }
        !           425: 
        !           426: /*
        !           427:  * Given a segment pointer, `sp' and a segment size, grow the given segment
        !           428:  * to the given size.
        !           429:  */
        !           430: segsize(sp, s2)
        !           431: register SEG *sp;
        !           432: vaddr_t s2;
        !           433: {
        !           434:        register vaddr_t s1;
        !           435: 
        !           436:        s1 = (vaddr_t) sp->s_size;
        !           437:        if (seggrow(sp, (fsize_t)s2) == 0) {
        !           438:                u.u_error = ENOMEM;
        !           439:                return;
        !           440:        }
        !           441:        if (sproto() == 0)
        !           442:                if (seggrow(sp, (fsize_t)s1)==0 || sproto()==0)
        !           443:                        sendsig(SIGSEGV, SELF);
        !           444:        segload();
        !           445: }
        !           446: 
        !           447: /*
        !           448:  * Grow the segment `sp1' to the size `s' in bytes by swapping it out
        !           449:  * and back in.  The segment may not be locked.
        !           450:  */
        !           451: SEG *
        !           452: segsext(sp1, s)
        !           453: register SEG *sp1;
        !           454: register fsize_t s;
        !           455: {
        !           456:        register SEG *sp2;
        !           457: 
        !           458: #ifndef NOMONITOR
        !           459:        if (swmflag)
        !           460:                printf("Segsext(%p, %u)\n", SELF, SELF->p_pid);
        !           461: #endif
        !           462:        if (sexflag == 0) {
        !           463:                u.u_error = ENOMEM;
        !           464:                return (NULL);
        !           465:        }
        !           466:        lock(seglink);
        !           467:        if ((sp2=sdalloc(s)) == NULL) {
        !           468:                unlock(seglink);
        !           469:                return (NULL);
        !           470:        }
        !           471:        unlock(seglink);
        !           472:        sp1->s_lrefc++;
        !           473:        if (sp1->s_size != 0)
        !           474:                swapio(1, sp1->s_paddr, sp2->s_daddr, sp1->s_size);
        !           475:        lock(seglink);
        !           476:        satcopy(sp1, sp2);
        !           477:        unlock(seglink);
        !           478:        sp1->s_flags &= ~SFCORE;
        !           479:        sp1->s_lrefc--;
        !           480:        vremap(sp1);
        !           481:        segfinm(sp1);
        !           482:        return (sp1);
        !           483: }
        !           484: 
        !           485: /*
        !           486:  * Force the given segment to be in memory.  One can only force
        !           487:  * one segment to be in memory at a time.
        !           488:  */
        !           489: segfinm(sp)
        !           490: register SEG *sp;
        !           491: {
        !           492:        register PROC *pp;
        !           493:        register int s;
        !           494: 
        !           495:        if ((sp->s_flags&SFCORE) != 0)
        !           496:                return;
        !           497:        pp = SELF;
        !           498:        sp->s_urefc++;
        !           499:        sp->s_lrefc++;
        !           500:        pp->p_segp[SIAUXIL] = sp;
        !           501:        pp->p_flags &= ~PFCORE;
        !           502: #ifndef QWAKEUP
        !           503:        s = sphi();
        !           504: #endif
        !           505:        setrun(pp);
        !           506:        dispatch();
        !           507: #ifndef QWAKEUP
        !           508:        spl(s);
        !           509: #endif
        !           510:        pp->p_segp[SIAUXIL] = NULL;
        !           511:        sfree(sp);
        !           512: }
        !           513: 
        !           514: /*
        !           515:  * Make a copy of the segment `sp1' which is in memory by writing
        !           516:  * it out to disk.
        !           517:  */
        !           518: SEG *
        !           519: segdupd(sp1)
        !           520: register SEG *sp1;
        !           521: {
        !           522:        register SEG *sp2;
        !           523: 
        !           524:        if (sexflag == 0)
        !           525:                return (NULL);
        !           526:        lock(seglink);
        !           527:        if ((sp2=sdalloc(sp1->s_size)) == NULL) {
        !           528:                unlock(seglink);
        !           529:                return (NULL);
        !           530:        }
        !           531:        sp1->s_lrefc++;
        !           532:        unlock(seglink);
        !           533:        swapio(1, sp1->s_paddr, sp2->s_daddr, sp1->s_size);
        !           534:        sp1->s_lrefc--;
        !           535:        sp2->s_flags = sp1->s_flags & ~SFCORE;
        !           536:        sp2->s_size  = sp1->s_size;
        !           537:        vremap( sp2 );
        !           538:        return (sp2);
        !           539: }
        !           540: 
        !           541: /*
        !           542:  * Given a flag, a physical core address, a disk address and a count in
        !           543:  * bytes, perform an I/O operation between core and disk.  If `flag' is
        !           544:  * set, the transfer is to the disk otherwise it is to memory.  As you may
        !           545:  * have guessed, this is used by the swapper.
        !           546:  */
        !           547: swapio(f, p, d, n)
        !           548: paddr_t p;
        !           549: daddr_t d;
        !           550: fsize_t  n;
        !           551: {
        !           552:        register BUF * bp;
        !           553:        register SEG * sp;
        !           554:        register int s;
        !           555:        register int nb;
        !           556:        static SEG swapseg;     /* NOTE: FP_SEL(swapseg.s_faddr) must stay */
        !           557: 
        !           558: #ifndef NOMONITOR
        !           559:        if (swmflag > 1)
        !           560:                printf("swapio(%s,%x,%x,%x)\n",f?"out":"in",(int)p,(int)d,n);
        !           561: #endif
        !           562:        if (d < swapbot || d+(n/BSIZE) > swaptop
        !           563:         || p < corebot || p+n > coretop)
        !           564:                panic("Swapio bad parameter");
        !           565: 
        !           566:        bp = &swapbuf;
        !           567:        sp = &swapseg;
        !           568:        lock(bp->b_gate);
        !           569:        SELF->p_flags |= PFSWIO;
        !           570:        sp->s_flags = SFCORE;
        !           571:        sp->s_paddr = p;
        !           572:        sp->s_size  = n;
        !           573:        vremap( sp );
        !           574:        bp->b_faddr = sp->s_faddr;
        !           575: 
        !           576:        while (n != 0) {
        !           577:                nb = (n > SCHUNK) ? SCHUNK : n;
        !           578:                /*
        !           579:                 * Prevent I/O transfer from crossing 64 Kbyte boundary.
        !           580:                 */
        !           581:                if ( (p & 0xFFFF0000L) != ((p+nb) & 0xFFFF0000L) )
        !           582:                        nb = 0x10000L - (p & 0x0000FFFFL);
        !           583:                bp->b_flag  = BFNTP;
        !           584:                bp->b_req   = f ? BWRITE : BREAD;
        !           585:                bp->b_dev   = swapdev;
        !           586:                bp->b_bno   = d;
        !           587:                bp->b_paddr = p;
        !           588:                bp->b_count = nb;
        !           589:                s = sphi();
        !           590:                dblock(swapdev, bp);
        !           591:                while ((bp->b_flag&BFNTP) != 0)
        !           592:                        sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
        !           593:                spl(s);
        !           594:                if ((bp->b_flag&BFERR) != 0)
        !           595:                        panic("Swapio error");
        !           596:                FP_OFF(bp->b_faddr) += nb;
        !           597:                p += nb;
        !           598:                d += nb / BSIZE;
        !           599:                n -= nb;
        !           600:        }
        !           601:        sp->s_flags = 0;
        !           602:        vremap( sp );
        !           603:        unlock(bp->b_gate);
        !           604:        SELF->p_flags &= ~PFSWIO;
        !           605: }
        !           606: 
        !           607: /*
        !           608:  * Make the segment descriptor pointed to by `sp1' have the attributes
        !           609:  * of `sp2' including it's position in the segment queue and release
        !           610:  * `sp2'.  `seglink' must be locked when this routine is called.
        !           611:  */
        !           612: satcopy(sp1, sp2)
        !           613: register SEG *sp1;
        !           614: register SEG *sp2;
        !           615: {
        !           616:        if ( FP_SEL(sp2->s_faddr) != 0 )
        !           617:                vrelse( sp2->s_faddr );
        !           618: 
        !           619:        sp1->s_back->s_forw = sp1->s_forw;
        !           620:        sp1->s_forw->s_back = sp1->s_back;
        !           621:        sp2->s_back->s_forw = sp1;
        !           622:        sp1->s_back = sp2->s_back;
        !           623:        sp2->s_forw->s_back = sp1;
        !           624:        sp1->s_forw  = sp2->s_forw;
        !           625:        sp1->s_size  = sp2->s_size;
        !           626:        sp1->s_paddr = sp2->s_paddr;
        !           627:        sp1->s_daddr = sp2->s_daddr;
        !           628:        vremap(sp1);
        !           629:        kfree(sp2);
        !           630: }
        !           631: 
        !           632: /*
        !           633:  * Allocate a segment on disk that is `n' bytes long.
        !           634:  * The `seglink' gate should be locked before this routine is called.
        !           635:  */
        !           636: SEG *
        !           637: sdalloc( s )
        !           638: fsize_t s;
        !           639: {
        !           640:        register SEG *sp1;
        !           641:        register SEG *sp2;
        !           642:        register daddr_t d;
        !           643:        register daddr_t d1;
        !           644:        register daddr_t d2;
        !           645: 
        !           646:        d  = s / BSIZE;
        !           647:        d1 = swapbot;
        !           648:        sp1 = &segdq;
        !           649:        do {
        !           650:                if (d1 >= swaptop)
        !           651:                        return (NULL);
        !           652:                if ((sp1=sp1->s_forw) != &segdq)
        !           653:                        d2 = sp1->s_daddr;
        !           654:                else
        !           655:                        d2 = swaptop;
        !           656:                if (d2-d1 >= d) {
        !           657:                        if ((sp2=kalloc(sizeof(SEG))) == NULL)
        !           658:                                return (NULL);
        !           659:                        sp1->s_back->s_forw = sp2;
        !           660:                        sp2->s_back = sp1->s_back;
        !           661:                        sp1->s_back = sp2;
        !           662:                        sp2->s_forw = sp1;
        !           663:                        sp2->s_urefc = 1;
        !           664:                        sp2->s_lrefc = 1;
        !           665:                        sp2->s_size  = s;
        !           666:                        sp2->s_daddr = d1;
        !           667:                        return (sp2);
        !           668:                }
        !           669:                d1 = sp1->s_daddr + (sp1->s_size / BSIZE);
        !           670:        } while (sp1 != &segdq);
        !           671:        return (NULL);
        !           672: }
        !           673: 
        !           674: /*
        !           675:  * Allocate a segment in memory that is `n' bytes long.
        !           676:  * The `seglink' gate should be locked before this routine is called.
        !           677:  */
        !           678: SEG *
        !           679: smalloc(s)
        !           680: fsize_t s;
        !           681: {
        !           682:        register SEG *sp1;
        !           683:        register SEG *sp2;
        !           684:        paddr_t p1;
        !           685:        paddr_t p2;
        !           686: 
        !           687:        p1  = corebot;
        !           688:        sp1 = &segmq;
        !           689:        do {
        !           690:                if ((sp1=sp1->s_forw) != &segmq)
        !           691:                        p2 = sp1->s_paddr;
        !           692:                else
        !           693:                        p2 = coretop;
        !           694: 
        !           695:                if (p2-p1 >= s) {
        !           696:                        if ((sp2=kalloc(sizeof (SEG))) == NULL)
        !           697:                                return (NULL);
        !           698:                        sp1->s_back->s_forw = sp2;
        !           699:                        sp2->s_back = sp1->s_back;
        !           700:                        sp1->s_back = sp2;
        !           701:                        sp2->s_forw = sp1;
        !           702:                        sp2->s_urefc = 1;
        !           703:                        sp2->s_lrefc = 1;
        !           704:                        sp2->s_size  = s;
        !           705:                        sp2->s_paddr = p1;
        !           706:                        /*   s_faddr = 0; */
        !           707:                        /*   s_flags = 0; */
        !           708:                        vremap( sp2 );
        !           709:                        return (sp2);
        !           710:                }
        !           711:                p1 = sp1->s_paddr + sp1->s_size;
        !           712:        } while (sp1 != &segmq);
        !           713:        return (NULL);
        !           714: }
        !           715: 
        !           716: /*
        !           717:  * Allocate a segment from the high end of memory that is `n' bytes long.
        !           718:  * The `seglink' gate should be locked before this routine is called.
        !           719:  */
        !           720: SEG *
        !           721: shalloc( s )
        !           722: fsize_t s;
        !           723: {
        !           724:        register SEG *sp1;
        !           725:        register SEG *sp2;
        !           726:        paddr_t p1;
        !           727:        paddr_t p2;
        !           728: 
        !           729:        sp1 = &segmq;
        !           730:        p2  = coretop;
        !           731:        do {
        !           732:                if ((sp1=sp1->s_back) != &segmq)
        !           733:                        p1 = sp1->s_paddr + sp1->s_size;
        !           734:                else
        !           735:                        p1 = corebot;
        !           736: 
        !           737:                if (p2-p1 >= s) {
        !           738:                        if ((sp2=kalloc(sizeof (SEG))) == NULL)
        !           739:                                return (NULL);
        !           740:                        sp1->s_forw->s_back = sp2;
        !           741:                        sp2->s_forw = sp1->s_forw;
        !           742:                        sp1->s_forw = sp2;
        !           743:                        sp2->s_back = sp1;
        !           744:                        sp2->s_urefc = 1;
        !           745:                        sp2->s_lrefc = 1;
        !           746:                        sp2->s_size  = s;
        !           747:                        sp2->s_paddr = p2-s;
        !           748:                        /*   s_faddr = 0; */
        !           749:                        /*   s_flags = 0; */
        !           750:                        vremap( sp2 );
        !           751:                        return (sp2);
        !           752:                }
        !           753:                p2 = sp1->s_paddr;
        !           754:        } while (sp1 != &segmq);
        !           755:        return (NULL);
        !           756: }
        !           757: 
        !           758: /*
        !           759:  * Set up `SR' structure in user area from segments descriptors in
        !           760:  * process structure.  Also set up the user segmentation registers.
        !           761:  */
        !           762: sproto()
        !           763: {
        !           764:        register int n;
        !           765:        register SEG *sp;
        !           766: 
        !           767:        kclear(u.u_segl, sizeof(u.u_segl));
        !           768:        for (n=0; n<NUSEG; n++) {
        !           769:                if ((sp=SELF->p_segp[n]) == NULL)
        !           770:                        continue;
        !           771:                if (n == SIUSERP)
        !           772:                        u.u_segl[n].sr_base = &u;
        !           773:                else
        !           774:                        u.u_segl[n].sr_flag |= SRFPMAP;
        !           775:                if (n!=SISTEXT && n!=SISDATA)
        !           776:                        u.u_segl[n].sr_flag |= SRFDUMP;
        !           777:                if (n!=SIUSERP && n!=SISTEXT && n!=SIPTEXT)
        !           778:                        u.u_segl[n].sr_flag |= SRFDATA;
        !           779:                u.u_segl[n].sr_size = sp->s_size;
        !           780:                u.u_segl[n].sr_segp = sp;
        !           781:        }
        !           782:        return (mproto());
        !           783: }
        !           784: 
        !           785: /*
        !           786:  * Search for a busy text inode.
        !           787:  */
        !           788: sbusy(ip)
        !           789: register INODE *ip;
        !           790: {
        !           791:        register SEG *sp;
        !           792: 
        !           793:        lock(seglink);
        !           794:        /*
        !           795:         * Look for the segment in the memory queue.
        !           796:         */
        !           797:        for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
        !           798:                if (sp->s_ip==ip
        !           799:                 && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
        !           800:                        unlock(seglink);
        !           801:                        return (1);
        !           802:                }
        !           803:        }
        !           804: 
        !           805:        /*
        !           806:         * Look for the segment on the disk queue.
        !           807:         */
        !           808:        for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
        !           809:                if (sp->s_ip==ip
        !           810:                 && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
        !           811:                        unlock(seglink);
        !           812:                        return (1);
        !           813:                }
        !           814:        }
        !           815:        unlock(seglink);
        !           816:        return (0);
        !           817: }
        !           818: 
        !           819: /*
        !           820:  * Segment consistency checks for the paranoid.
        !           821: segchk()
        !           822: {
        !           823:        register SEG *sp;
        !           824:        register int nbad;
        !           825:        fsize_t s;
        !           826:        daddr_t d;
        !           827: 
        !           828:        nbad = 0;
        !           829:        sp = &segmq;
        !           830:        s = corebot;
        !           831:        while ((sp=sp->s_forw) != &segmq) {
        !           832:                if (sp->s_paddr < s)
        !           833:                        nbad += badseg("mem", sp->s_paddr, 0);
        !           834:                s = sp->s_paddr + sp->s_size;
        !           835:        }
        !           836:        if (coretop < s)
        !           837:                nbad += badseg("mem", sp->s_back->s_paddr, sp->s_back->s_size);
        !           838:        sp = &segdq;
        !           839:        d = swapbot;
        !           840:        while ((sp=sp->s_forw) != &segdq) {
        !           841:                if (sp->s_daddr < d)
        !           842:                        nbad += badseg("disk", (int)sp->s_daddr, 0);
        !           843:                d = sp->s_daddr + (sp->s_size / BSIZE);
        !           844:        }
        !           845:        if (swaptop < d)
        !           846:                nbad += badseg("disk", sp->s_back->s_daddr, sp->s_back->s_size);
        !           847: }
        !           848: 
        !           849: badseg(t, b, s)
        !           850: char *t;
        !           851: daddr_t b;
        !           852: fsize_t s;
        !           853: {
        !           854:        printf( "Bad %s segment at %X of len %X\n", t, b, s );
        !           855:        return (1);
        !           856: }
        !           857: */

unix.superglobalmegacorp.com

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