Annotation of coherent/d/kernel/USRSRC/coh/seg.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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