Annotation of 40BSD/cmd/lisp/Talloc.c, revision 1.1

1.1     ! root        1: 
        !             2: static char *sccsid = "@(#)Talloc.c    34.11 10/31/80";
        !             3: 
        !             4: # include "global.h"
        !             5: # include "structs.h"
        !             6: # ifndef   UNIXTS
        !             7: # include <vadvise.h>
        !             8: # endif
        !             9: 
        !            10: # define NUMWORDS TTSIZE * 128  /*  max number of words in P0 space  */
        !            11: # define BITQUADS TTSIZE * 2   /*  length of bit map in quad words  */
        !            12: 
        !            13: # define ftstbit       asm("   ashl    $-2,r11,r3");\
        !            14:                        asm("   bbcs    r3,_bitmapq,$1");\
        !            15:                        asm("   .byte   4");
        !            16: /*  define ftstbit     if( readbit(p) ) return; oksetbit;  */
        !            17: # define readbit(p)    ((int)bitmap[r=(int)p>>5] & (s=bitmsk[((int)p>>2)&7]))
        !            18: # define lookbit(p)    (bitmap[(int)p>>5] & bitmsk[((int)p>>2) & 7])
        !            19: # define setbit(p)     {bitmap[(int)p>>5] |= bitmsk[((int)p >> 2) & 7];}
        !            20: # define oksetbit      {bitmap[r] |= s;}
        !            21: 
        !            22: # define readchk(p)    ((int)bitfre[(int)p>>5] & bitmsk[((int)p>>2)&7])
        !            23: # define setchk(p)     {bitfre[(int)p>>5] |= bitmsk[((int)p >> 2) & 7];}
        !            24: # define roundup(x,l)  (((x - 1) | (l - 1)) + 1) 
        !            25: 
        !            26: /* METER denotes something added to help meter storage allocation. */
        !            27: 
        !            28: extern struct heads header[];
        !            29: 
        !            30: FILE * chkport;                                /* garbage collection dump file */
        !            31: extern lispval datalim;                        /*  end of data space */
        !            32: double bitmapq[BITQUADS];              /*  the bit map--one bit per long  */
        !            33: #ifdef METER
        !            34: double Mbitmapq[BITQUADS];
        !            35: #endif
        !            36: double zeroq;                          /*  a quad word of zeros  */
        !            37: char *bitmap = (char *) bitmapq;       /*  byte version of bit map array */
        !            38: int  *bitmapi = (int *) bitmapq;       /*  integer version of bit map array */
        !            39: #ifdef METER
        !            40: int  *Mbitmapi = (int *) Mbitmapq;     /*  integer version of bit map array */
        !            41: int  freefree,usedfree,freeused,usedused;
        !            42: #endif
        !            43: #ifndef METER
        !            44: int  freefree,usedfree,freeused,usedused; /* need so external refs will be
        !            45:                                             satisfied, remove when get rid
        !            46:                                             of meter stuff
        !            47:                                         */
        !            48: #endif
        !            49: char bitmsk[8]={1,2,4,8,16,32,64,128};  /*  used by bit-marking macros  */
        !            50: extern int  *bind_lists ;              /*  lisp data for compiled code */
        !            51: 
        !            52: char *xsbrk();
        !            53: char *gethspace();
        !            54: 
        !            55: 
        !            56: int atmlen;
        !            57: 
        !            58: extern struct types atom_str, strng_str, int_str, dtpr_str, doub_str,
        !            59:        array_str, sdot_str, val_str, funct_str, hunk_str[];
        !            60: 
        !            61: lispval hunk_items[7], hunk_pages[7], hunk_name[7];
        !            62: 
        !            63: extern int initflag; /* starts off TRUE: initially gc not allowed */
        !            64: 
        !            65: int gcflag = FALSE;    /*  TRUE during garbage collection  */
        !            66: 
        !            67: int current = 0;       /* number of pages currently allocated */
        !            68: 
        !            69: static struct types *(spaces[NUMSPACES]) = 
        !            70:        {&atom_str, &strng_str, &int_str,
        !            71:         &dtpr_str, &doub_str, &array_str,
        !            72:         &sdot_str, &val_str, &funct_str,
        !            73:         &hunk_str[0], &hunk_str[1], &hunk_str[2],
        !            74:         &hunk_str[3], &hunk_str[4], &hunk_str[5],
        !            75:         &hunk_str[6]};
        !            76: 
        !            77: /* this is a table of pointers to collectable struct types objects
        !            78:  * the index is the type number.
        !            79:  */
        !            80: struct types *gcableptr[] =
        !            81:    { (struct types *) 0,  /* strings not collectable */
        !            82:      (struct types *) 0,  /* atoms not collectable   */
        !            83:      &int_str, &dtpr_str, &doub_str,
        !            84:      (struct types *) 0,  /* binary objects not collectable */
        !            85:      (struct types *) 0,  /* port objects not collectable */
        !            86:      &array_str,
        !            87:      (struct types *) 0,  /* gap in the type number sequence */
        !            88:      &sdot_str,&val_str, 
        !            89:      &hunk_str[0], &hunk_str[1], &hunk_str[2],
        !            90:      &hunk_str[3], &hunk_str[4], &hunk_str[5],
        !            91:      &hunk_str[6]};
        !            92: 
        !            93: 
        !            94: /** get_more_space(type_struct) *****************************************/
        !            95: /*                                                                     */
        !            96: /*  Allocates and structures a new page, returning 0.                  */
        !            97: /*  If no space is available, returns 1.                               */
        !            98: 
        !            99: get_more_space(type_struct)                                 
        !           100: struct types *type_struct;
        !           101: {
        !           102:        int cntr;
        !           103:        char *start;
        !           104:        int *loop, *temp;
        !           105:        lispval p, plim;
        !           106:        struct heads *next; extern char holend[];
        !           107: 
        !           108:        if(initflag == FALSE) 
        !           109:                /*  mustn't look at plist of plima too soon  */
        !           110:                {
        !           111:                while( plim=copval(plima,(lispval)CNIL), TYPE(plim)!=INT )
        !           112:                        copval(plima,error("BAD PAGE LIMIT",TRUE));
        !           113:                if( plim->i <= current ) return(1);     /*  Can't allocate  */
        !           114:                }
        !           115: 
        !           116:        if( current >= TTSIZE ) return(2);
        !           117: 
        !           118: #ifdef HOLE
        !           119:        if(type_struct==&strng_str || (type_struct==&funct_str))
        !           120:                start = gethspace(NBPG,type_struct->type);
        !           121:        else
        !           122: #endif
        !           123:                start = xsbrk();
        !           124: 
        !           125: 
        !           126:        SETTYPE(start, type_struct->type);  /*  set type of page  */
        !           127: 
        !           128:        /* bump the page counter for this space */
        !           129: 
        !           130:        ++((*(type_struct->pages))->i);
        !           131: 
        !           132:        type_struct->space_left = type_struct->space;
        !           133:        if(start >= holend) {
        !           134:                next = &header[ current++ ];
        !           135:                next->pntr = start;
        !           136:                next->link = type_struct->first;
        !           137:                type_struct->first = next;
        !           138:        }
        !           139:        if(type_struct==&strng_str) {
        !           140:                type_struct->next_free = start;
        !           141:                return(0);  /*  space was available  */
        !           142:        }
        !           143:        type_struct->first = next;
        !           144:        temp = loop = (int *) start;
        !           145:        for(cntr=1; cntr < type_struct->space; cntr++)
        !           146:                loop = (int *) (*loop = (int) (loop + type_struct->type_len));
        !           147:        *loop = (int) (type_struct->next_free);
        !           148:        type_struct->next_free = (char *) temp;
        !           149: 
        !           150:        /*  if type atom, set pnames to CNIL  */
        !           151: 
        !           152:        if( type_struct == &atom_str )
        !           153:                for(cntr=0, p=(lispval) temp; cntr<atom_str.space; ++cntr)
        !           154:                        {
        !           155:                        p->a.pname = (char *) CNIL;
        !           156:                        p = (lispval) ((int *)p + atom_str.type_len);
        !           157:                        }
        !           158:        return(0);  /*  space was available  */
        !           159: }
        !           160: 
        !           161: 
        !           162: /** next_one(type_struct) ************************************************/
        !           163: /*                                                                     */
        !           164: /*  Allocates one new item of each kind of space, except STRNG.                */
        !           165: /*  If there is no space, calls gc, the garbage collector.             */
        !           166: /*  If there is still no space, allocates a new page using             */
        !           167: /*  get_more_space(type_struct)                                                */
        !           168: 
        !           169: lispval
        !           170: next_one(type_struct)
        !           171: struct types *type_struct;
        !           172: {
        !           173: 
        !           174:        register char *temp;
        !           175:        snpand(1);
        !           176: 
        !           177:        while(type_struct->next_free == (char *) CNIL)
        !           178:                {
        !           179:                int g;
        !           180: 
        !           181:                if((type_struct->type != ATOM) &&   /* can't collect atoms */
        !           182:                   (type_struct->type != STRNG) &&  /* can't collect strings */
        !           183:                   (type_struct->type != BCD) &&    /* nor function headers  */
        !           184:                   (gcthresh->i <= current) &&          /* threshhold for gc */
        !           185:                   gcdis->a.clb == nil &&               /* gc not disabled */
        !           186:                   (NOTNIL(copval(gcload,CNIL)) || (loading->a.clb != tatom)) &&
        !           187:                                        /* not to collect during load */
        !           188:                   (initflag == FALSE) &&       /* dont gc during init */
        !           189:                   (gcflag == FALSE))             /* don't recurse gc */
        !           190: 
        !           191:                        {
        !           192:                        /* fputs("Collecting",poport);
        !           193:                        dmpport(poport);*/
        !           194:                        gc(type_struct);  /*  collect  */
        !           195:                        }
        !           196: 
        !           197:                if( type_struct->next_free != (char *) CNIL ) break;
        !           198: 
        !           199:                if(! (g=get_more_space(type_struct))) break;
        !           200: 
        !           201:                if( g==1 )
        !           202:                        {
        !           203:                        plimit->i = current+NUMSPACES;
        !           204:                                /*  allow a few more pages  */
        !           205:                        copval(plima,plimit);   /*  restore to reserved reg  */
        !           206: 
        !           207:                        error("PAGE LIMIT EXCEEDED--EMERGENCY PAGES ALLOCATED",
        !           208:                                TRUE);
        !           209:                        }
        !           210:                else error("SORRY, ABSOLUTE PAGE LIMIT HAS BEEN REACHED",
        !           211:                                TRUE);
        !           212:                }
        !           213: 
        !           214:        temp = type_struct->next_free;
        !           215:        type_struct->next_free = * (char **)(type_struct->next_free);
        !           216:        return((lispval) temp);
        !           217: }
        !           218: 
        !           219: lispval
        !           220: newint()
        !           221: {
        !           222:        ++(int_items->i);
        !           223:        return(next_one(&int_str));
        !           224: }
        !           225: 
        !           226: lispval
        !           227: newdot()
        !           228: {
        !           229:        lispval temp;
        !           230: 
        !           231:        ++(dtpr_items->i);
        !           232:        temp = next_one(&dtpr_str);
        !           233:        temp->d.car = temp->d.cdr = nil;
        !           234:        return(temp);
        !           235: }
        !           236: 
        !           237: lispval
        !           238: newdoub()
        !           239: {
        !           240:        ++(doub_items->i);
        !           241:        return(next_one(&doub_str));
        !           242: }
        !           243: 
        !           244: lispval
        !           245: newsdot()
        !           246: {
        !           247:        register lispval temp;
        !           248:        ++(dtpr_items->i);
        !           249:        temp = next_one(&sdot_str);
        !           250:        temp->d.car = temp->d.cdr = 0;
        !           251:        return(temp);
        !           252: }
        !           253: 
        !           254: struct atom *
        !           255: newatom() {
        !           256:        struct atom *save;
        !           257: 
        !           258:        ++(atom_items->i);
        !           259:        save = (struct atom *) next_one(&atom_str) ;    
        !           260:        save->plist = save->fnbnd = nil;
        !           261:        save->hshlnk = (struct atom *)CNIL;
        !           262:        save->clb = CNIL;
        !           263:        save->pname = newstr();
        !           264:        return (save);
        !           265: }
        !           266: 
        !           267: char *newstr() {
        !           268:        char *save;
        !           269:        int atmlen2,atmlen;
        !           270: 
        !           271:        ++(str_items->i);
        !           272:        atmlen = strlen(strbuf)+1;
        !           273:        if(atmlen > strng_str.space_left)
        !           274:                while(get_more_space(&strng_str))
        !           275:                        error("YOU HAVE RUN OUT OF SPACE",TRUE);
        !           276:        strcpy((save = strng_str.next_free), strbuf);
        !           277:        atmlen2 = atmlen;
        !           278:        while(atmlen2 & 3) ++atmlen2;   /*  even up length of string  */
        !           279:        strng_str.next_free += atmlen2;
        !           280:        strng_str.space_left -= atmlen2;
        !           281:        return(save);
        !           282: }
        !           283: 
        !           284: char *inewstr(s) char *s;
        !           285: {
        !           286:        strbuf[STRBLEN-1] = '\0';
        !           287:        strcpyn(strbuf,s,STRBLEN-1);
        !           288:        return(newstr());
        !           289: }
        !           290: 
        !           291: lispval
        !           292: newarray()
        !           293:        {
        !           294:        register lispval temp;
        !           295: 
        !           296:        ++(array_items->i);
        !           297:        temp = next_one(&array_str);
        !           298:        temp->ar.data = (char *)nil;
        !           299:        temp->ar.accfun = nil;
        !           300:        temp->ar.aux = nil;
        !           301:        temp->ar.length = SMALL(0);
        !           302:        temp->ar.delta = SMALL(0);
        !           303:        return(temp);
        !           304:        }
        !           305: 
        !           306: lispval
        !           307: badcall()
        !           308:        { error("BAD FUNCTION DESCRIPTOR USED IN CALL",FALSE); }
        !           309: 
        !           310: lispval
        !           311: newfunct()
        !           312:        {
        !           313:        register lispval temp;
        !           314:        ++(funct_items->i);
        !           315:        temp = next_one(&funct_str);
        !           316:        temp->bcd.entry = badcall;
        !           317:        temp->bcd.discipline = nil;
        !           318:        return(temp);
        !           319:        }
        !           320: 
        !           321: lispval
        !           322: newval()
        !           323:        {
        !           324:        register lispval temp;
        !           325:        ++(val_items->i);
        !           326:        temp = next_one(&val_str);
        !           327:        temp->l = nil;
        !           328:        return(temp);
        !           329:        }
        !           330: 
        !           331: lispval
        !           332: newhunk(hunknum)
        !           333: int hunknum;
        !           334:        {
        !           335:        register lispval temp;
        !           336: 
        !           337:        ++(hunk_items[hunknum]->i);             /* Update used hunks count */
        !           338:        temp = next_one(&hunk_str[hunknum]);    /* Get a hunk */
        !           339:        return(temp);
        !           340:        }
        !           341: 
        !           342: lispval
        !           343: inewval(arg) lispval arg;
        !           344:        {
        !           345:        lispval temp;
        !           346:        ++(val_items->i);
        !           347:        temp = next_one(&val_str);
        !           348:        temp->l = arg;
        !           349:        return(temp);
        !           350:        }
        !           351: 
        !           352: 
        !           353: /** Ngc *****************************************************************/
        !           354: /*                                                                     */
        !           355: /*  LISP interface to gc.                                              */
        !           356: 
        !           357: lispval Ngc()
        !           358:        {
        !           359:        lispval temp;
        !           360: 
        !           361:        if( ISNIL(lbot->val) ) return(gc(CNIL));
        !           362: 
        !           363:        if( TYPE(lbot->val) != DTPR ) error("BAD CALL TO GC",FALSE);
        !           364: 
        !           365:        chkport = poport;
        !           366: 
        !           367:        if( NOTNIL(lbot->val->d.car) )
        !           368:                {
        !           369:                temp = eval(lbot->val->d.car);
        !           370:                if( TYPE(temp) == PORT ) chkport = temp->p;
        !           371:                }
        !           372: 
        !           373:        gc1(TRUE);
        !           374: 
        !           375:        return(nil);
        !           376:        }
        !           377: 
        !           378: /** gc(type_struct) *****************************************************/
        !           379: /*                                                                     */
        !           380: /*  garbage collector:  Collects garbage by mark and sweep algorithm.  */
        !           381: /*  After this is done, calls the Nlambda, gcafter.                    */
        !           382: /*  gc may also be called from LISP, as a lambda of no arguments.      */
        !           383: 
        !           384: lispval
        !           385: gc(type_struct)
        !           386:        struct types *type_struct;
        !           387:        {
        !           388:        lispval save;
        !           389:        struct {
        !           390:                long mytime;
        !           391:                long allelse[3];
        !           392:        } begin, finish;
        !           393:        extern int GCtime;
        !           394: 
        !           395:        save = copval(gcport,CNIL);
        !           396:        if(GCtime)
        !           397:                times(&begin);
        !           398: 
        !           399:        while( (TYPE(save) != PORT) && NOTNIL(save))
        !           400:                save = error("NEED PORT FOR GC",TRUE);
        !           401: 
        !           402:        chkport = (ISNIL(save) ? poport : save->p);
        !           403:        
        !           404:        gc1(NOTNIL(copval(gccheck,CNIL)) || (chkport!=poport)); /* mark&sweep */
        !           405: 
        !           406:        /* Now we call gcafter--special case if gc called from LISP */
        !           407: 
        !           408:        if( type_struct == (struct types *) CNIL )
        !           409:                gccall1->d.cdr = nil;  /* make the call "(gcafter)" */
        !           410:        else
        !           411:                {
        !           412:                gccall1->d.cdr = gccall2;
        !           413:                gccall2->d.car = *(type_struct->type_name);
        !           414:                }
        !           415:        {lispval temp;temp = rdrsdot, rdrsdot = rdrsdot2, rdrsdot2 = temp; /*KLUDGE*/}
        !           416:        gcflag = TRUE;          /*  flag to indicate in garbage collector  */
        !           417:        save = eval(gccall1);   /*  call gcafter  */
        !           418:        gcflag = FALSE;         /*  turn off flag  */
        !           419:        {lispval temp;temp = rdrsdot, rdrsdot = rdrsdot2, rdrsdot2 = temp; /*KLUDGE*/}
        !           420: 
        !           421:        if(GCtime) {
        !           422:                times(&finish);
        !           423:                GCtime += (finish.mytime - begin.mytime);
        !           424:        }
        !           425:        return(save);   /*  return result of gcafter  */
        !           426:        }
        !           427: 
        !           428:        
        !           429: 
        !           430: /*  gc1()  **************************************************************/
        !           431: /*                                                                     */
        !           432: /*  Mark-and-sweep phase                                               */
        !           433: 
        !           434: gc1(chkflag) int chkflag;
        !           435:        {
        !           436:        int j, typep,k;
        !           437:        register int *start,bvalue,type_len; 
        !           438:        register struct types *s;
        !           439:        int *point,i,freecnt,itemstogo,bits,bindex,type,enddat;
        !           440:        struct heads *loop;
        !           441:        struct argent *loop2;
        !           442:        struct nament *loop3;
        !           443: #ifdef METER
        !           444:        int Mbvalue;
        !           445: #endif
        !           446:        int markdp();
        !           447:        int debugin  = FALSE;   /* temp debug flag */
        !           448:        extern int *beginsweep;
        !           449: #define ERDB(s) { printf(s); fflush(stdout); }
        !           450: 
        !           451: #ifndef UNIXTS
        !           452:        vadvise(VA_ANOM);
        !           453:        /*  decide whether to check LISP structure or not  */
        !           454: #endif
        !           455: 
        !           456: 
        !           457: 
        !           458:        /*  first set all bit maps to zero  */
        !           459: 
        !           460: 
        !           461:        if(debugin) ERDB("Begin gc\n");
        !           462:        enddat = (int)datalim >> 8;
        !           463:        for(bvalue=0; bvalue < (int)enddat ; ++bvalue)
        !           464:        {
        !           465: #ifdef METER
        !           466:                /* Mbitmapq[bvalue] = bitmapq[bvalue];  /* remember old vals */
        !           467:                /* the C compiler will use a movd if we let it,and this
        !           468:                   will not work since the bit maps may be illegal 
        !           469:                   floating point values
        !           470:                */
        !           471:                asm(" movq _bitmapq[r10],_Mbitmapq[r10] ");
        !           472: #endif
        !           473:             bitmapq[bvalue] = zeroq; 
        !           474:        }
        !           475: 
        !           476:        /* try the movc5 to clear the bit maps */
        !           477:        /* blzero(bitmap,TTSIZE * 16); */
        !           478: 
        !           479: 
        !           480:        /* then mark all atoms' plists, clbs, and function bindings */
        !           481: 
        !           482:        for(loop=atom_str.first; loop!=(struct heads *)CNIL; loop=loop->link)
        !           483:                for(start=(int *)(loop->pntr), i=1;
        !           484:                        i <= atom_str.space;
        !           485:                        start = start + atom_str.type_len, ++i)
        !           486:                        {
        !           487: 
        !           488:                        /* unused atoms are marked with pname == CNIL */
        !           489:                        /* this is done by get_more_space, as well as */
        !           490:                        /* by gc (in the future)                      */
        !           491: 
        !           492:                        if(((lispval)start)->a.pname == (char *)CNIL) continue;
        !           493: #define MARKSUB(p)     if(nil!=((lispval)start)->p)markdp(((lispval)start)->p);
        !           494:                        MARKSUB(a.clb);
        !           495:                        MARKSUB(a.fnbnd);
        !           496:                        MARKSUB(a.plist);
        !           497:                        }
        !           498: 
        !           499:        /* Mark all the atoms and ints associated with the hunk
        !           500:           data types */
        !           501:           
        !           502:        for(i=0; i<8; i++) {
        !           503:                markdp(hunk_items[i]);
        !           504:                markdp(hunk_name[i]);
        !           505:                markdp(hunk_pages[i]);
        !           506:        }
        !           507:        /* next run up the name stack */
        !           508:        if(debugin) ERDB("name stack\n");
        !           509:        for(loop2 = np - 1; loop2 >=  orgnp; --loop2) markdp((loop2->val));     
        !           510: 
        !           511:        /* now the bindstack (vals only, atoms are marked elsewhere ) */
        !           512:        for(loop3 = bnp - 1; loop3 >= orgbnp; --loop3)markdp(loop3->val);
        !           513: 
        !           514:        if(debugin) ERDB("compiler stuff\n");   
        !           515:        /* from TBL 29july79  */
        !           516:        /* next mark all compiler linked data */
        !           517:        point = bind_lists;
        !           518:        while((start = point) != (int *)CNIL) {
        !           519:                if(debugin) ERDB("once ");
        !           520:                while( *start != -1 )
        !           521:                        markdp(*start++);
        !           522:                point = (int *)*(point-1);
        !           523:        }
        !           524:        /* end from TBL */
        !           525: 
        !           526:        if(debugin) ERDB("signif stuff\n");
        !           527:        /* next mark all system-significant lisp data */
        !           528: 
        !           529:        for(i=0; i<SIGNIF; ++i) markdp((lispsys[i]));
        !           530: 
        !           531:        if(debugin) printf("time to sweep up\n");       
        !           532:        /* all accessible data has now been marked. */
        !           533:        /* all collectable spaces must be swept,    */
        !           534:        /* and freelists constructed.               */
        !           535: 
        !           536:        /* first clear the structure elements for types
        !           537:         * we will sweep
        !           538:         */
        !           539:        
        !           540:        for(k=0 ; k <= HUNK128 ; k++)
        !           541:        {
        !           542:                if( s=gcableptr[k] )
        !           543:                {
        !           544:                  (*(s->items))->i = 0;
        !           545:                  s->space_left = 0;
        !           546:                  s->next_free = (char *) CNIL;
        !           547:                }
        !           548:        }
        !           549: 
        !           550: 
        !           551:        /* sweep up in memory looking at gcable pages */
        !           552: 
        !           553:        for(start = beginsweep,  bindex = (int)start >> 7; 
        !           554:            start < (int *)datalim;
        !           555:            start += 128)
        !           556:        {
        !           557:            /* printf(" start %x, bindex %x\n",start,bindex); */
        !           558:            if(!(s=gcableptr[type = TYPE(start)])) 
        !           559:            {   
        !           560:                bindex += 4;   /* and 4 words of 32 bit bitmap words */
        !           561:                continue;
        !           562:            }
        !           563: 
        !           564:            freecnt = 0;                /* number of free items found */
        !           565:            itemstogo = s->space;       /* number of items per page  */
        !           566:            bits = 32;                  /* number of bits per word */
        !           567:            type_len = s->type_len;
        !           568: 
        !           569:            /* printf(" s %d, itemstogo %d, len %d\n",s,itemstogo,type_len);*/
        !           570:            bvalue = bitmapi[bindex++];
        !           571: #ifdef METER
        !           572:            Mbvalue = Mbitmapi[bindex-1];
        !           573: #endif
        !           574: 
        !           575:            point = start;
        !           576:            while(TRUE)
        !           577:            {
        !           578:                /*printf(" bv: %08x, ",bvalue);*/
        !           579:                if(!(bvalue & 1))       /* if data element is not marked */
        !           580:                {
        !           581:                    freecnt++;
        !           582:                    *point = (int) (s->next_free) ;
        !           583:                    s->next_free = (char *) point;
        !           584: #ifdef METER
        !           585:                    if(type == DTPR) 
        !           586:                    {
        !           587:                         if(Mbvalue & 1) usedfree++;
        !           588:                         else freefree++;
        !           589:                    }
        !           590: #endif
        !           591:                }
        !           592: #ifdef METER
        !           593:                else if(type == DTPR) 
        !           594:                {
        !           595:                        if (Mbvalue & 1) usedused++;
        !           596:                        else freeused++;
        !           597:                }
        !           598: #endif
        !           599: 
        !           600:                if( --itemstogo <= 0 ) 
        !           601:                {    if(type_len >= 64) 
        !           602:                     {
        !           603:                        bindex++;
        !           604:                        if(type_len >=128) bindex += 2;
        !           605:                     }
        !           606:                     break;
        !           607:                }
        !           608: 
        !           609:                point += type_len;
        !           610:                /* shift over mask by number of words in data type */
        !           611: 
        !           612:                if( (bits -= type_len) > 0)
        !           613:                {  bvalue = bvalue >> type_len;
        !           614: #ifdef METER
        !           615:                   Mbvalue = Mbvalue >> type_len;
        !           616: #endif
        !           617:                } 
        !           618:                else if( bits == 0 ) 
        !           619:                {  bvalue = bitmapi[bindex++];
        !           620: #ifdef METER
        !           621:                   Mbvalue = Mbitmapi[bindex-1];
        !           622: #endif
        !           623:                   bits = 32;
        !           624:                }
        !           625:                else
        !           626:                {  bits = -bits;
        !           627:                   while( bits >= 32) { bindex++;
        !           628:                                        bits -= 32;
        !           629:                                      }
        !           630:                   bvalue = bitmapi[bindex++];
        !           631:                   bvalue = bvalue >> bits;
        !           632: #ifdef METER
        !           633:                   Mbvalue = Mbitmapi[bindex-1];
        !           634:                   Mbvalue = Mbvalue >> bits;
        !           635: #endif
        !           636:                   bits = 32 - bits;;
        !           637:                }
        !           638:        }
        !           639: 
        !           640:        /* printf(" t %d,fr %d ",type,freecnt); */
        !           641:        s->space_left += freecnt;
        !           642:        (*(s->items))->i += s->space - freecnt;
        !           643:      }
        !           644: 
        !           645: #ifndef UNIXTS
        !           646:        vadvise(VA_NORM);
        !           647: #endif
        !           648: }
        !           649: 
        !           650: /** alloc() *************************************************************/
        !           651: /*                                                                     */
        !           652: /*  This routine tries to allocate one more page of the space named    */
        !           653: /*  by the argument.  If no more space is available returns 1, else 0. */
        !           654: 
        !           655: lispval
        !           656: alloc(tname,npages)
        !           657:        lispval tname; int npages;
        !           658:        {
        !           659:        int ii, jj;
        !           660: 
        !           661:        ii = typenum(tname);
        !           662: 
        !           663:        if(((int)datalim >> 9) + npages > TTSIZE)
        !           664:           error("Space request would exceed maximum memory allocation",FALSE);
        !           665: 
        !           666:        for( jj=0; jj<npages; ++jj)
        !           667:                if(get_more_space(spaces[ii])) break;
        !           668:        return(inewint(jj));
        !           669:        }
        !           670: 
        !           671: lispval
        !           672: csegment(tname,nitems,useholeflag)
        !           673: lispval tname; int nitems;
        !           674: {
        !           675:        int ii, jj;
        !           676:        char *charadd;
        !           677: 
        !           678:        ii = typenum(tname);
        !           679: 
        !           680:        nitems = nitems*4*spaces[ii]->type_len; /*  find c-length of space  */
        !           681:        nitems = roundup(nitems,512);           /*  round up to right length  */
        !           682: #ifdef HOLE
        !           683:        if((tname==str_name) && useholeflag)
        !           684:                charadd = gethspace(nitems,ii);
        !           685:        else
        !           686: #endif
        !           687:        {
        !           688:                current += nitems/512;
        !           689:                charadd = sbrk(nitems);
        !           690:                datalim = (lispval)(charadd+nitems);
        !           691:        }
        !           692:        if( (int) charadd == 0 )
        !           693:                error("NOT ENOUGH SPACE FOR ARRAY",FALSE);
        !           694:        if((((int)datalim) >> 9) > TTSIZE) {
        !           695:                datalim = (lispval) (TTSIZE << 9);
        !           696:                badmem(53);
        !           697:        }
        !           698:        for(jj=0; jj<nitems; jj=jj+512) {
        !           699:                SETTYPE(charadd+jj, spaces[ii]->type);
        !           700:        }
        !           701:        blzero(charadd,nitems);
        !           702:        return((lispval)charadd);
        !           703: }
        !           704: 
        !           705: int csizeof(tname) lispval tname;
        !           706:        {
        !           707:        return( spaces[typenum(tname)]->type_len * 4 );
        !           708:        }
        !           709: 
        !           710: int typenum(tname) lispval tname;
        !           711:        {
        !           712:        int ii;
        !           713: 
        !           714: chek:  for(ii=0; ii<NUMSPACES; ++ii)
        !           715:                if(tname == *(spaces[ii]->type_name)) break;
        !           716:        if(ii == NUMSPACES)
        !           717:                {
        !           718:                tname = error("BAD TYPE NAME",TRUE);
        !           719:                goto chek;
        !           720:                }
        !           721: 
        !           722:        return(ii);
        !           723:        
        !           724:        }
        !           725: char *
        !           726: gethspace(segsiz,type)
        !           727: {
        !           728:        extern usehole; extern char holend[]; extern char *curhbeg;
        !           729:        register char *value;
        !           730: 
        !           731:        if(usehole) {   
        !           732:                curhbeg = (char *) roundup(((int)curhbeg),NBPG);
        !           733:                if((holend - curhbeg) < segsiz)
        !           734:                {       printf("[fasl hole filled up]\n");
        !           735:                        usehole = FALSE;
        !           736:                } else {
        !           737:                        value = curhbeg;
        !           738:                        curhbeg = curhbeg + segsiz;
        !           739:                        /*printf("start %d, finish %d, size %d\n",value, curhbeg,segsiz);*/
        !           740:                        return(value);
        !           741:                }
        !           742:        }
        !           743:        value = (ysbrk(segsiz/NBPG,type));
        !           744:        datalim = (lispval)(value + segsiz);
        !           745:        return(value);
        !           746: }
        !           747: gcrebear()
        !           748: {
        !           749: #ifdef HOLE
        !           750:        /* this gets done upon rebirth */
        !           751:        strng_str.space_left = 0;
        !           752:        funct_str.space_left = 0;
        !           753:        funct_str.next_free = (char *) CNIL;
        !           754: #endif
        !           755: }
        !           756: 
        !           757: /** markit(p) ***********************************************************/
        !           758: /*  just calls markdp                                                  */
        !           759: 
        !           760: markit(p) lispval *p; { markdp(*p); }
        !           761: 
        !           762: /** markdp(p) ***********************************************************/
        !           763: /*                                                                     */
        !           764: /*  markdp is the routine which marks each data item.  If it is a      */
        !           765: /*  dotted pair, the car and cdr are marked also.                      */
        !           766: /*  An iterative method is used to mark list structure, to avoid       */
        !           767: /*  excessive recursion.                                               */
        !           768: 
        !           769: 
        !           770: markdp(p) register lispval p;
        !           771:        {
        !           772: /*     register int r, s;      (goes with non-asm readbit, oksetbit)   */
        !           773: /*     register hsize, hcntr;                                          */
        !           774:        int hsize, hcntr;
        !           775: 
        !           776: ptr_loop:
        !           777:        if((int)p <= 0) return; /*  do not mark special data types or nil=0  */
        !           778: 
        !           779:        switch( TYPE(p) )
        !           780:                {
        !           781:                case INT:
        !           782:                case DOUB:
        !           783: /*                     setbit(p);*/
        !           784:                        ftstbit;
        !           785:                        return;
        !           786:                case VALUE:
        !           787:                        ftstbit;
        !           788:                        p = p->l;
        !           789:                        goto ptr_loop;
        !           790:                case DTPR:
        !           791:                        ftstbit;
        !           792:                        markdp(p->d.car);
        !           793:                        p = p->d.cdr;
        !           794:                        goto ptr_loop;
        !           795: 
        !           796:                case ARRAY:
        !           797:                        ftstbit;        /* mark array itself */
        !           798: 
        !           799:                        markdp(p->ar.accfun);   /* mark access function */
        !           800:                        markdp(p->ar.aux);              /* mark aux data */
        !           801:                        markdp(p->ar.length);   /* mark length */
        !           802:                        markdp(p->ar.delta);    /* mark delta */
        !           803:                        if(TYPE(p->ar.aux)==DTPR && p->ar.aux->d.car==Vnogbar)
        !           804:                                return;
        !           805:                        {
        !           806: /*                     register int i, l; int d;               */
        !           807: /*                     register char *dataptr = p->ar.data;    */
        !           808:                        int i,l,d;
        !           809:                        char *dataptr = p->ar.data;
        !           810: 
        !           811:                        for(i=0, l=p->ar.length->i, d=p->ar.delta->i; i<l; ++i)
        !           812:                                {
        !           813:                                markdp(dataptr);
        !           814:                                dataptr += d;
        !           815:                                }
        !           816:                        return;
        !           817:                        }
        !           818:                case SDOT:
        !           819:                        do {
        !           820:                                ftstbit;
        !           821:                                p = p->s.CDR;
        !           822:                        } while (p!=0);
        !           823:                        return;
        !           824: 
        !           825:                case BCD:
        !           826:                        ftstbit;
        !           827:                        markdp(p->bcd.discipline);
        !           828:                        return;
        !           829: 
        !           830:                case HUNK2:
        !           831:                case HUNK4:
        !           832:                case HUNK8:
        !           833:                case HUNK16:
        !           834:                case HUNK32:
        !           835:                case HUNK64:
        !           836:                case HUNK128:
        !           837:                        {
        !           838:                                hsize = 2 << HUNKSIZE(p);
        !           839:                                ftstbit;
        !           840:                                for (hcntr = 0; hcntr < hsize; hcntr++)
        !           841:                                        markdp(p->h.hunk[hcntr]);
        !           842:                                return;
        !           843:                        }
        !           844:                }
        !           845:        return;
        !           846:        }
        !           847: 
        !           848: 
        !           849: 
        !           850: char *
        !           851: xsbrk()
        !           852:        {
        !           853:        static char *xx;        /*  pointer to next available blank page  */
        !           854:        extern int xcycle;      /*  number of blank pages available  */
        !           855:        lispval u;                      /*  used to compute limits of bit table  */
        !           856: 
        !           857:        if( (xcycle--) <= 0 )
        !           858:                {
        !           859:                xcycle = 15;
        !           860:                xx = sbrk(16*NBPG);     /*  get pages 16 at a time  */
        !           861:                if( (int)xx== -1 )
        !           862:                        lispend("For sbrk from lisp: no space... Goodbye!");
        !           863:                goto done;
        !           864:                }
        !           865:        xx += NBPG;
        !           866: done:  if( (u = (lispval)(xx+NBPG))  > datalim ) datalim = u;
        !           867:        return(xx);
        !           868:        }
        !           869: 
        !           870: char *ysbrk(pages,type) int pages, type;
        !           871:        {
        !           872:        char *xx;       /*  will point to block of storage  */
        !           873:        int i;
        !           874: 
        !           875:        xx = sbrk(pages*NBPG);
        !           876:        if((int)xx == -1)
        !           877:                error("OUT OF SPACE FOR ARRAY REQUEST",FALSE);
        !           878: 
        !           879:        datalim = (lispval)(xx+pages*NBPG);     /*  compute bit table limit  */
        !           880: 
        !           881:        /*  set type for pages  */
        !           882: 
        !           883:        for(i = 0; i < pages; ++i) {
        !           884:                SETTYPE((xx + i*NBPG),type);
        !           885:        }
        !           886: 
        !           887:        return(xx);     /*  return pointer to block of storage  */
        !           888:        }
        !           889: 
        !           890: #ifdef VMS
        !           891: /* sbrk - 
        !           892:  *   this function is used by the VMS franz to allocate space.  
        !           893:  * It allocates space in the zfreespace array.
        !           894:  * The single argument passed to sbrk is the number of bytes to allocate
        !           895:  *
        !           896:  */
        !           897: 
        !           898: extern char zfreespace[];
        !           899: extern char *lsbrkpnt;
        !           900: 
        !           901: char *
        !           902: sbrk(n)
        !           903: {
        !           904:        char *result;
        !           905:        if(lsbrkpnt == (char *)0)
        !           906:        {  
        !           907:           lsbrkpnt = (char *) roundup((int)zfreespace,NBPG);
        !           908:        }
        !           909:        result = lsbrkpnt;
        !           910: /*     printf("lispbrk: %x \n",lsbrkpnt);
        !           911:        fflush(stdout);  */
        !           912:        lsbrkpnt += n;
        !           913:        if(lsbrkpnt > &zfreespace[FREESIZE])
        !           914:          error("sbrk: out of space ",FALSE);
        !           915:        return(result);
        !           916: }
        !           917: #endif
        !           918: /* getatom **************************************************************/
        !           919: /* returns either an existing atom with the name specified in strbuf, or*/
        !           920: /* if the atom does not already exist, regurgitates a new one and       */
        !           921: /* returns it.                                                          */
        !           922: lispval
        !           923: getatom()
        !           924: {   register lispval aptr;
        !           925:     register char *name, *endname;
        !           926:     register int hash;
        !           927:     register struct argent *lbot, *np;
        !           928:     lispval    b;
        !           929:     char       c;
        !           930: 
        !           931:        name = strbuf;
        !           932:        if (*name == (char)0377) return (eofa);
        !           933:        hash = hashfcn(name);
        !           934:        atmlen = strlen(name) + 1;
        !           935:        aptr = (lispval) hasht[hash];
        !           936:        while (aptr != CNIL)
        !           937:            if (strcmp(name,aptr->a.pname)==0)
        !           938:                return (aptr);
        !           939:            else
        !           940:                aptr = (lispval) aptr->a.hshlnk;
        !           941:        aptr = (lispval) newatom();
        !           942:        aptr->a.hshlnk = hasht[hash];
        !           943:        hasht[hash] = (struct atom *) aptr;
        !           944:        endname = name + atmlen - 2;
        !           945:        if ((atmlen != 4) && (*name == 'c') && (*endname == 'r'))
        !           946:                {
        !           947:                b = newdot();
        !           948:                protect(b);
        !           949:                b->d.car = lambda;
        !           950:                b->d.cdr = newdot();
        !           951:                b = b->d.cdr;
        !           952:                b->d.car = newdot();
        !           953:                (b->d.car)->d.car = xatom;
        !           954:                while(TRUE)
        !           955:                        {
        !           956:                        b->d.cdr = newdot();
        !           957:                        b= b->d.cdr;
        !           958:                        if(++name == endname)
        !           959:                                {
        !           960:                                b->d.car= (lispval) xatom;
        !           961:                                aptr->a.fnbnd = unprot();
        !           962:                                break;
        !           963:                                }
        !           964:                        b->d.car= newdot();
        !           965:                        b= b->d.car;
        !           966:                        if((c = *name) == 'a') b->d.car = cara;
        !           967:                        else if (c == 'd') b->d.car = cdra;
        !           968:                        else{ unprot();
        !           969:                           break;
        !           970:                         }
        !           971:                        }
        !           972:                }
        !           973: 
        !           974:        return(aptr);
        !           975:        }
        !           976: 
        !           977: /* our hash function */
        !           978: 
        !           979: hashfcn(symb)
        !           980: char *symb;
        !           981: {
        !           982:        register int i;
        !           983:        for (i=0 ; *symb ; i += i + *symb++);
        !           984:        return(i & (HASHTOP-1));
        !           985: }
        !           986: 
        !           987: extern struct atom *hasht[HASHTOP];

unix.superglobalmegacorp.com

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