Annotation of coherent/b/STREAMS/coh.386/seg.c, revision 1.1.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.