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

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

unix.superglobalmegacorp.com

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