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

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

unix.superglobalmegacorp.com

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