Annotation of coherent/d/PS2_KERNEL/coh.286/seg.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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