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

1.1     ! root        1: # include "global.h"
        !             2: 
        !             3: # define NUMWORDS TTSIZE * 128  /*  max number of words in P0 space  */
        !             4: # define BITQUADS TTSIZE * 2   /*  length of bit map in quad words  */
        !             5: 
        !             6: # define ftstbit       asm("   ashl    $-2,r11,r3");\
        !             7:                        asm("   bbcs    r3,_bitmapq,$1");\
        !             8:                        asm("   .byte   4");
        !             9: /*  define ftstbit     if( readbit(p) ) return; oksetbit;  */
        !            10: # define readbit(p)    ((int)bitmap[r=(int)p>>5] & (s=bitmsk[((int)p>>2)&7]))
        !            11: # define lookbit(p)    (bitmap[(int)p>>5] & bitmsk[((int)p>>2) & 7])
        !            12: # define setbit(p)     {bitmap[(int)p>>5] |= bitmsk[((int)p >> 2) & 7];}
        !            13: # define oksetbit      {bitmap[r] |= s;}
        !            14: 
        !            15: # define readchk(p)    ((int)bitfre[(int)p>>5] & bitmsk[((int)p>>2)&7])
        !            16: # define setchk(p)     {bitfre[(int)p>>5] |= bitmsk[((int)p >> 2) & 7];}
        !            17: 
        !            18: struct heads {
        !            19:        struct heads *link;
        !            20:        char *pntr;
        !            21: }  header[TTSIZE];
        !            22: 
        !            23: FILE * chkport;                                /* garbage collection dump file */
        !            24: lispval datalim;                       /*  end of data space */
        !            25: double bitmapq[BITQUADS];              /*  the bit map--one bit per long  */
        !            26: double zeroq;                          /*  a quad word of zeros  */
        !            27: char *bitmap = (char *) bitmapq;       /*  byte version of bit map array */
        !            28: char bitmsk[8]={1,2,4,8,16,32,64,128};  /*  used by bit-marking macros  */
        !            29: int  *bind_lists = (int *) CNIL;       /*  lisp data for compiled code */
        !            30: 
        !            31: char *xsbrk();
        !            32: 
        !            33: 
        !            34: int atmlen;
        !            35: 
        !            36: struct types {
        !            37: char   *next_free;
        !            38: int    space_left,
        !            39:        space,
        !            40:        type,
        !            41:        type_len;                       /*  note type_len is in units of int */
        !            42: lispval *items,
        !            43:        *pages,
        !            44:        *type_name;
        !            45: struct heads
        !            46:        *first;
        !            47: } atom_str = {(char *)CNIL,0,ATOMSPP,ATOM,5,&atom_items,&atom_pages,&atom_name,(struct heads *)CNIL},
        !            48:   strng_str    = {(char *)CNIL,0,STRSPP,STRNG,1,&str_items,&str_pages,&str_name,(struct heads *)CNIL},
        !            49:   int_str  = {(char *)CNIL,0,INTSPP,INT,1,&int_items,&int_pages,&int_name,(struct heads *)CNIL},
        !            50:   dtpr_str = {(char *)CNIL,0,DTPRSPP,DTPR,2,&dtpr_items,&dtpr_pages,&dtpr_name,(struct heads *)CNIL},
        !            51:   doub_str     = {(char *)CNIL,0,DOUBSPP,DOUB,2,&doub_items,&doub_pages,&doub_name,(struct heads *)CNIL},
        !            52:   array_str   = {(char *)CNIL,0,ARRAYSPP,ARRAY,5,&array_items,&array_pages,&array_name,(struct heads *)CNIL},
        !            53:   sdot_str = {(char *)CNIL,0,SDOTSPP,SDOT,2,&sdot_items,&sdot_pages,&sdot_name,(struct heads *)CNIL},
        !            54:   val_str  = {(char *)CNIL,0,VALSPP,VALUE,1,&val_items,&val_pages,&val_name,(struct heads *)CNIL},
        !            55:   funct_str = {(char *)CNIL,0,BCDSPP,BCD,2,&funct_items,&funct_pages,&funct_name,(struct heads *)CNIL};
        !            56: 
        !            57: extern int initflag; /* starts off TRUE: initially gc not allowed */
        !            58: 
        !            59: int gcflag = FALSE;    /*  TRUE during garbage collection  */
        !            60: 
        !            61: int current = 0;       /* number of pages currently allocated */
        !            62: 
        !            63: #define NUMSPACES 9
        !            64: 
        !            65: static struct types *(spaces[NUMSPACES]) = 
        !            66:        {&atom_str, &strng_str, &int_str,
        !            67:         &dtpr_str, &doub_str, &array_str,
        !            68:         &sdot_str, &val_str, &funct_str};
        !            69: 
        !            70: 
        !            71: /** get_more_space(type_struct) *****************************************/
        !            72: /*                                                                     */
        !            73: /*  Allocates and structures a new page, returning 0.                  */
        !            74: /*  If no space is available, returns 1.                               */
        !            75: 
        !            76: get_more_space(type_struct)                                 
        !            77: struct types *type_struct;
        !            78: {
        !            79:        int cntr;
        !            80:        char *start;
        !            81:        int *loop, *temp;
        !            82:        lispval p, plim;
        !            83:        struct heads *next;
        !            84: 
        !            85:        if(initflag == FALSE) 
        !            86:                /*  mustn't look at plist of plima too soon  */
        !            87:                {
        !            88:                while( plim=copval(plima,(lispval)CNIL), TYPE(plim)!=INT )
        !            89:                        copval(plima,error("BAD PAGE LIMIT",TRUE));
        !            90:                if( plim->i <= current ) return(1);     /*  Can't allocate  */
        !            91:                }
        !            92: 
        !            93:        if( current >= TTSIZE ) return(2);
        !            94: 
        !            95:        start = xsbrk( NBPG );
        !            96: 
        !            97:        /* bump the page counter for this space */
        !            98: 
        !            99:        ++((*(type_struct->pages))->i);
        !           100: 
        !           101:        SETTYPE(start, type_struct->type);  /*  set type of page  */
        !           102: 
        !           103:        type_struct->space_left = type_struct->space;
        !           104:        next = &header[ current++ ];
        !           105:        if ((type_struct->type)==STRNG)
        !           106:                {
        !           107:                type_struct->next_free = start;
        !           108:                return(0);  /*  space was available  */
        !           109:                }
        !           110:        next->pntr = start;
        !           111:        next->link = type_struct->first;
        !           112:        type_struct->first = next;
        !           113:        temp = loop = (int *) start;
        !           114:        for(cntr=1; cntr < type_struct->space; cntr++)
        !           115:                loop = (int *) (*loop = (int) (loop + type_struct->type_len));
        !           116:        *loop = (int) (type_struct->next_free);
        !           117:        type_struct->next_free = (char *) temp;
        !           118: 
        !           119:        /*  if type atom, set pnames to CNIL  */
        !           120: 
        !           121:        if( type_struct == &atom_str )
        !           122:                for(cntr=0, p=(lispval) temp; cntr<atom_str.space; ++cntr)
        !           123:                        {
        !           124:                        p->pname = (char *) CNIL;
        !           125:                        p = (lispval) ((int *)p + atom_str.type_len);
        !           126:                        }
        !           127:        return(0);  /*  space was available  */
        !           128: }
        !           129: 
        !           130: 
        !           131: /** next_one(type_struct) ************************************************/
        !           132: /*                                                                     */
        !           133: /*  Allocates one new item of each kind of space, except STRNG.                */
        !           134: /*  If there is no space, calls gc, the garbage collector.             */
        !           135: /*  If there is still no space, allocates a new page using             */
        !           136: /*  get_more_space(type_struct)                                                */
        !           137: 
        !           138: lispval
        !           139: next_one(type_struct)
        !           140: struct types *type_struct;
        !           141: {
        !           142: 
        !           143:        register char *temp;
        !           144:        snpand(1);
        !           145: 
        !           146:        while(type_struct->next_free == (char *) CNIL)
        !           147:                {
        !           148:                int g;
        !           149: 
        !           150:                if((type_struct->type != ATOM) &&   /* can't collect atoms */
        !           151:                   (type_struct->type != STRNG) &&  /* can't collect strings */
        !           152:                   (gcthresh->i <= current) &&       /* threshhold for gc */
        !           153:                   ISNIL(copval(gcdis,CNIL)) &&   /* gc not disabled */
        !           154:                   (NOTNIL(copval(gcload,CNIL)) || (loading->clb != tatom)) &&
        !           155:                                        /* not to collect during load */
        !           156:                   (initflag == FALSE) &&       /* dont gc during init */
        !           157:                   (gcflag == FALSE))             /* don't recurse gc */
        !           158: 
        !           159:                        {
        !           160:                        /* fputs("Collecting",poport);
        !           161:                        dmpport(poport);*/
        !           162:                        gc(type_struct);  /*  collect  */
        !           163:                        }
        !           164: 
        !           165:                if( type_struct->next_free != (char *) CNIL ) break;
        !           166: 
        !           167:                if(! (g=get_more_space(type_struct))) break;
        !           168: 
        !           169:                if( g==1 )
        !           170:                        {
        !           171:                        plimit->i = current+NUMSPACES;
        !           172:                                /*  allow a few more pages  */
        !           173:                        copval(plima,plimit);   /*  restore to reserved reg  */
        !           174: 
        !           175:                        error("PAGE LIMIT EXCEEDED--EMERGENCY PAGES ALLOCATED",
        !           176:                                TRUE);
        !           177:                        }
        !           178:                else error("SORRY, ABSOLUTE PAGE LIMIT HAS BEEN REACHED",
        !           179:                                TRUE);
        !           180:                }
        !           181: 
        !           182:        temp = type_struct->next_free;
        !           183:        type_struct->next_free = * (char **)(type_struct->next_free);
        !           184:        return((lispval) temp);
        !           185: }
        !           186: 
        !           187: lispval
        !           188: newint()
        !           189: {
        !           190:        ++(int_items->i);
        !           191:        return(next_one(&int_str));
        !           192: }
        !           193: 
        !           194: lispval
        !           195: newdot()
        !           196: {
        !           197:        lispval temp;
        !           198: 
        !           199:        ++(dtpr_items->i);
        !           200:        temp = next_one(&dtpr_str);
        !           201:        temp->car = temp->cdr = nil;
        !           202:        return(temp);
        !           203: }
        !           204: 
        !           205: lispval
        !           206: newdoub()
        !           207: {
        !           208:        ++(doub_items->i);
        !           209:        return(next_one(&doub_str));
        !           210: }
        !           211: 
        !           212: lispval
        !           213: newsdot()
        !           214: {
        !           215:        register lispval temp;
        !           216:        ++(dtpr_items->i);
        !           217:        temp = next_one(&sdot_str);
        !           218:        temp->car = temp->cdr = 0;
        !           219:        return(temp);
        !           220: }
        !           221: 
        !           222: struct atom *newatom() {
        !           223:        struct atom *save;
        !           224: 
        !           225:        ++(atom_items->i);
        !           226:        save = (struct atom *) next_one(&atom_str) ;    
        !           227:        save->plist = save->fnbnd = nil;
        !           228:        save->hshlnk = (struct atom *)CNIL;
        !           229:        save->clb = CNIL;
        !           230:        save->pname = newstr();
        !           231:        return (save);
        !           232: }
        !           233: 
        !           234: char *newstr() {
        !           235:        char *save;
        !           236:        int atmlen2;
        !           237: 
        !           238:        ++(str_items->i);
        !           239:        atmlen = strlen(strbuf)+1;
        !           240:        if(atmlen > strng_str.space_left)
        !           241:                while(get_more_space(&strng_str))
        !           242:                        error("YOU HAVE RUN OUT OF SPACE",TRUE);
        !           243:        strcpy((save = strng_str.next_free), strbuf);
        !           244:        atmlen2 = atmlen;
        !           245:        while(atmlen2 % 4) ++atmlen2;   /*  even up length of string  */
        !           246:        strng_str.next_free += atmlen2;
        !           247:        strng_str.space_left -= atmlen2;
        !           248:        return(save);
        !           249: }
        !           250: 
        !           251: char *inewstr(s) char *s;
        !           252: {
        !           253:        strbuf[STRBLEN-1] = '\0';
        !           254:        strcpyn(strbuf,s,STRBLEN-1);
        !           255:        return(newstr());
        !           256: }
        !           257: 
        !           258: lispval
        !           259: newarray()
        !           260:        {
        !           261:        register lispval temp;
        !           262:        ++(array_items->i);
        !           263:        temp = next_one(&array_str);
        !           264:        temp->data = (char *)nil;
        !           265:        temp->accfun = nil;
        !           266:        temp->aux = nil;
        !           267:        temp->length = SMALL(0);
        !           268:        temp->delta = SMALL(0);
        !           269:        return(temp);
        !           270:        }
        !           271: 
        !           272: lispval
        !           273: badcall()
        !           274:        { error("BAD FUNCTION DESCRIPTOR USED IN CALL",FALSE); }
        !           275: 
        !           276: lispval
        !           277: newfunct()
        !           278:        {
        !           279:        register lispval temp;
        !           280:        ++(funct_items->i);
        !           281:        temp = next_one(&funct_str);
        !           282:        temp->entry = badcall;
        !           283:        temp->discipline = nil;
        !           284:        return(temp);
        !           285:        }
        !           286: 
        !           287: lispval
        !           288: newval()
        !           289:        {
        !           290:        register lispval temp;
        !           291:        ++(val_items->i);
        !           292:        temp = next_one(&val_str);
        !           293:        temp->l = nil;
        !           294:        return(temp);
        !           295:        }
        !           296: 
        !           297: lispval
        !           298: inewval(arg) lispval arg;
        !           299:        {
        !           300:        lispval temp;
        !           301:        ++(val_items->i);
        !           302:        temp = next_one(&val_str);
        !           303:        temp->l = arg;
        !           304:        return(temp);
        !           305:        }
        !           306: 
        !           307: /** Ngc *****************************************************************/
        !           308: /*                                                                     */
        !           309: /*  LISP interface to gc.                                              */
        !           310: 
        !           311: lispval Ngc()
        !           312:        {
        !           313:        lispval temp;
        !           314: 
        !           315:        if( ISNIL(lbot->val) ) return(gc(CNIL));
        !           316: 
        !           317:        if( TYPE(lbot->val) != DTPR ) error("BAD CALL TO GC",FALSE);
        !           318: 
        !           319:        chkport = poport;
        !           320: 
        !           321:        if( NOTNIL(lbot->val->car) )
        !           322:                {
        !           323:                temp = eval(lbot->val->car);
        !           324:                if( TYPE(temp) == PORT ) chkport = (FILE *)*temp;
        !           325:                }
        !           326: 
        !           327:        gc1(TRUE);
        !           328: 
        !           329:        return(nil);
        !           330:        }
        !           331: 
        !           332: /** gc(type_struct) *****************************************************/
        !           333: /*                                                                     */
        !           334: /*  garbage collector:  Collects garbage by mark and sweep algorithm.  */
        !           335: /*  After this is done, calls the Nlambda, gcafter.                    */
        !           336: /*  gc may also be called from LISP, as a lambda of no arguments.      */
        !           337: 
        !           338: lispval
        !           339: gc(type_struct)
        !           340:        struct types *type_struct;
        !           341:        {
        !           342:        lispval save;
        !           343:        struct {
        !           344:                long mytime;
        !           345:                long allelse[3];
        !           346:        } begin, finish;
        !           347:        extern int GCtime;
        !           348: 
        !           349:        save = copval(gcport,CNIL);
        !           350:        if(GCtime)
        !           351:                times(&begin);
        !           352: 
        !           353:        while( (TYPE(save) != PORT) && NOTNIL(save))
        !           354:                save = error("NEED PORT FOR GC",TRUE);
        !           355: 
        !           356:        chkport = ISNIL(save) ? poport : (FILE *)*save;
        !           357:        
        !           358:        gc1(NOTNIL(copval(gccheck,CNIL)) || (chkport!=poport)); /* mark&sweep */
        !           359: 
        !           360:        /* Now we call gcafter--special case if gc called from LISP */
        !           361: 
        !           362:        if( type_struct == (struct types *) CNIL )
        !           363:                gccall1->cdr = nil;  /* make the call "(gcafter)" */
        !           364:        else
        !           365:                {
        !           366:                gccall1->cdr = gccall2;
        !           367:                gccall2->car = *(type_struct->type_name);
        !           368:                }
        !           369:        gcflag = TRUE;          /*  flag to indicate in garbage collector  */
        !           370:        save = eval(gccall1);   /*  call gcafter  */
        !           371:        gcflag = FALSE;         /*  turn off flag  */
        !           372: 
        !           373:        if(GCtime) {
        !           374:                times(&finish);
        !           375:                GCtime += (finish.mytime - begin.mytime);
        !           376:        }
        !           377:        return(save);   /*  return result of gcafter  */
        !           378:        }
        !           379: 
        !           380:        
        !           381: 
        !           382: /*  gc1()  **************************************************************/
        !           383: /*                                                                     */
        !           384: /*  Mark-and-sweep phase                                               */
        !           385: 
        !           386: gc1(chkflag) int chkflag;
        !           387:        {
        !           388:        int i, j, typep;
        !           389:        register int *start, *point;
        !           390:        struct types *s;
        !           391:        struct heads *loop;
        !           392:        struct argent *loop2;
        !           393:        int markdp();
        !           394: 
        !           395:        
        !           396:        /*  decide whether to check LISP structure or not  */
        !           397: 
        !           398: 
        !           399: 
        !           400: 
        !           401:        /*  first set all bit maps to zero  */
        !           402: 
        !           403:        for(i=0; i<((int)datalim >> 8); ++i) bitmapq[i] = zeroq;
        !           404: 
        !           405: 
        !           406:        /* then mark all atoms' plists, clbs, and function bindings */
        !           407: 
        !           408:        for(loop=atom_str.first; loop!=(struct heads *)CNIL; loop=loop->link)
        !           409:                for(start=(int *)(loop->pntr), i=1;
        !           410:                        i <= atom_str.space;
        !           411:                        start = start + atom_str.type_len, ++i)
        !           412:                        {
        !           413: 
        !           414:                        /* unused atoms are marked with pname == CNIL */
        !           415:                        /* this is done by get_more_space, as well as */
        !           416:                        /* by gc (in the future)                      */
        !           417: 
        !           418:                        if(((lispval)start)->pname == (char *)CNIL) continue;
        !           419: #define MARKSUB(p)     if(nil!=((lispval)start)->p)markdp(((lispval)start)->p);
        !           420:                        MARKSUB(clb);
        !           421:                        MARKSUB(fnbnd);
        !           422:                        MARKSUB(plist);
        !           423:                        }
        !           424: 
        !           425:        /* next run up the name stack */
        !           426: 
        !           427:        for(loop2 = np - 1; loop2 >=  orgnp; --loop2) markdp((loop2->val));     
        !           428:        /* from TBL 29july79  */
        !           429:        /* next mark all compiler linked data */
        !           430:        point = bind_lists;
        !           431:        while((start = point) != (int *)CNIL) {
        !           432:                while( *start != -1 )
        !           433:                        markdp(*start++);
        !           434:                point = (int *)*(point-1);
        !           435:        }
        !           436:        /* end from TBL */
        !           437: 
        !           438:        /* next mark all system-significant lisp data */
        !           439: 
        !           440:        for(i=0; i<SIGNIF; ++i) markdp((lispsys[i]));
        !           441: 
        !           442:        /* all accessible data has now been marked. */
        !           443:        /* all collectable spaces must be swept,    */
        !           444:        /* and freelists constructed.               */
        !           445: 
        !           446:        for(i=0; i<NUMSPACES; ++i)
        !           447:                {
        !           448:                /* STRINGS do not participate. */
        !           449:                /* ATOMS dont either (currently) */
        !           450: 
        !           451:                s = spaces[i];
        !           452:                typep = s->type;
        !           453:                if((typep==STRNG) || (typep==ATOM)) continue;
        !           454: 
        !           455:                s->space_left = 0;  /* we will count free cells */
        !           456:                (*(s->items))->i = 0;    /* and compute cells used    */
        !           457: 
        !           458:                /* for each space, traverse list of pages. */
        !           459: 
        !           460:                s->next_free = (char *) CNIL;   /*  reinitialize free list  */
        !           461: 
        !           462:                for(loop = s->first; loop != (struct heads *) CNIL; loop=loop->link)
        !           463:                        {
        !           464:                        /* add another page's worth to use count */
        !           465: 
        !           466:                        (*(s->items))->i  += s->space;
        !           467: 
        !           468:                        /* for each page, make a list of unmarked data */
        !           469: 
        !           470:                        for(j=0, point=(int *)(loop->pntr);
        !           471:                                j<s->space; ++j, point += s->type_len)
        !           472:                                if( ! lookbit(point) )
        !           473:                                        {
        !           474:                                                /* add to free list */
        !           475:                                                /* update pointer to free list*/
        !           476:                                                /* update count of free list */
        !           477: 
        !           478:                                        *point = (int)(s->next_free);
        !           479:                                        s->next_free = (char *) point;
        !           480:                                        ++(s->space_left);
        !           481:                                        }
        !           482:                        }
        !           483:                (*(s->items))->i -= s->space_left;      /* compute cells used */
        !           484:                }
        !           485: }
        !           486: 
        !           487: /** alloc() *************************************************************/
        !           488: /*                                                                     */
        !           489: /*  This routine tries to allocate one more page of the space named    */
        !           490: /*  by the argument.  If no more space is available returns 1, else 0. */
        !           491: 
        !           492: lispval
        !           493: alloc(tname,npages)
        !           494:        lispval tname; int npages;
        !           495:        {
        !           496:        int ii, jj;
        !           497: 
        !           498:        ii = typenum(tname);
        !           499: 
        !           500:        for( jj=0; jj<npages; ++jj)
        !           501:                if(get_more_space(spaces[ii])) break;
        !           502:        return(inewint(jj));
        !           503:        }
        !           504: 
        !           505: lispval
        !           506: csegment(tname,nitems)
        !           507: lispval tname; int nitems;
        !           508:        {
        !           509:        int ii, jj;
        !           510:        char *charadd;
        !           511: 
        !           512:        ii = typenum(tname);
        !           513: 
        !           514:        nitems = nitems*4*spaces[ii]->type_len; /*  find c-length of space  */
        !           515:        while( nitems%512 ) ++nitems;           /*  round up to right length  */
        !           516:        current += nitems/512;
        !           517:        charadd = sbrk(nitems);
        !           518:        if( (int) charadd == 0 )
        !           519:                error("NOT ENOUGH SPACE FOR ARRAY",FALSE);
        !           520:        (datalim = (lispval)(charadd+nitems));
        !           521:        if((((int)datalim) >> 9) > TTSIZE) {
        !           522:                datalim = (lispval) (TTSIZE << 9);
        !           523:                badmem(53);
        !           524:        }
        !           525:        for(jj=0; jj<nitems; jj=jj+512) {
        !           526:                SETTYPE(charadd+jj, spaces[ii]->type);
        !           527:        }
        !           528:        return((lispval)charadd);
        !           529:        }
        !           530: 
        !           531: int csizeof(tname) lispval tname;
        !           532:        {
        !           533:        return( spaces[typenum(tname)]->type_len * 4 );
        !           534:        }
        !           535: 
        !           536: int typenum(tname) lispval tname;
        !           537:        {
        !           538:        int ii;
        !           539: 
        !           540: chek:  for(ii=0; ii<NUMSPACES; ++ii)
        !           541:                if(tname == *(spaces[ii]->type_name)) break;
        !           542:        if(ii == NUMSPACES)
        !           543:                {
        !           544:                tname = error("BAD TYPE NAME",TRUE);
        !           545:                goto chek;
        !           546:                }
        !           547: 
        !           548:        return(ii);
        !           549:        }
        !           550: 
        !           551: /** markit(p) ***********************************************************/
        !           552: /*  just calls markdp                                                  */
        !           553: 
        !           554: markit(p) lispval *p; { markdp(*p); }
        !           555: 
        !           556: /** markdp(p) ***********************************************************/
        !           557: /*                                                                     */
        !           558: /*  markdp is the routine which marks each data item.  If it is a      */
        !           559: /*  dotted pair, the car and cdr are marked also.                      */
        !           560: /*  An iterative method is used to mark list structure, to avoid       */
        !           561: /*  excessive recursion.                                               */
        !           562: 
        !           563: 
        !           564: markdp(p) register lispval p;
        !           565:        {
        !           566: /*     register int r, s;      (goes with non-asm readbit, oksetbit)   */
        !           567: 
        !           568: ptr_loop:
        !           569:        if((int)p <= 0) return; /*  do not mark special data types or nil=0  */
        !           570: 
        !           571:        switch( TYPE(p) )
        !           572:                {
        !           573:                case INT:
        !           574:                case DOUB:
        !           575: /*                     setbit(p);*/
        !           576:                        ftstbit;
        !           577:                        return;
        !           578:                case VALUE:
        !           579:                        ftstbit;
        !           580:                        p = p->l;
        !           581:                        goto ptr_loop;
        !           582:                case DTPR:
        !           583:                        ftstbit;
        !           584:                        markdp(p->car);
        !           585:                        p = p->cdr;
        !           586:                        goto ptr_loop;
        !           587: 
        !           588:                case ARRAY:
        !           589:                        ftstbit;        /* mark array itself */
        !           590: 
        !           591:                        markdp(p->accfun);      /* mark access function */
        !           592:                        markdp(p->aux);         /* mark aux data */
        !           593:                        markdp(p->length);      /* mark length */
        !           594:                        markdp(p->delta);       /* mark delta */
        !           595: 
        !           596:                        {
        !           597:                        register int i, l; int d;
        !           598:                        register char *dataptr = p->data;
        !           599: 
        !           600:                        for(i=0, l=p->length->i, d=p->delta->i; i<l; ++i)
        !           601:                                {
        !           602:                                markdp(dataptr);
        !           603:                                dataptr += d;
        !           604:                                }
        !           605:                        return;
        !           606:                        }
        !           607:                case SDOT:
        !           608:                        do {
        !           609:                                ftstbit;
        !           610:                                p = p->CDR;
        !           611:                        } while (p!=0);
        !           612:                        return;
        !           613: 
        !           614:                case BCD:
        !           615:                        ftstbit;
        !           616:                        markdp(p->discipline);
        !           617:                        return;
        !           618:                }
        !           619:        return;
        !           620:        }
        !           621: 
        !           622: 
        !           623: 
        !           624: char *
        !           625: xsbrk()
        !           626:        {
        !           627:        static char *xx;        /*  pointer to next available blank page  */
        !           628:        static int cycle = 0;   /*  number of blank pages available  */
        !           629:        lispval u;                      /*  used to compute limits of bit table  */
        !           630: 
        !           631:        if( (cycle--) <= 0 )
        !           632:                {
        !           633:                cycle = 15;
        !           634:                xx = sbrk(16*NBPG);     /*  get pages 16 at a time  */
        !           635:                if( (int)xx== -1 )
        !           636:                        lispend("For sbrk from lisp: no space... Goodbye!");
        !           637:                goto done;
        !           638:                }
        !           639:        xx += NBPG;
        !           640: done:  if( (u = (lispval)(xx+NBPG))  > datalim ) datalim = u;
        !           641:        return(xx);
        !           642:        }
        !           643: 
        !           644: char *ysbrk(pages,type) int pages, type;
        !           645:        {
        !           646:        char *xx;       /*  will point to block of storage  */
        !           647:        int i;
        !           648: 
        !           649:        xx = sbrk(pages*NBPG);
        !           650:        if((int)xx == -1)
        !           651:                error("OUT OF SPACE FOR ARRAY REQUEST",FALSE);
        !           652: 
        !           653:        datalim = (lispval)(xx+pages*NBPG);     /*  compute bit table limit  */
        !           654: 
        !           655:        /*  set type for pages  */
        !           656: 
        !           657:        for(i = 0; i < pages; ++i) {
        !           658:                SETTYPE((xx + i*NBPG),type);
        !           659:        }
        !           660: 
        !           661:        return(xx);     /*  return pointer to block of storage  */
        !           662:        }
        !           663: 
        !           664: /* getatom **************************************************************/
        !           665: /* returns either an existing atom with the name specified in strbuf, or*/
        !           666: /* if the atom does not already exist, regurgitates a new one and       */
        !           667: /* returns it.                                                          */
        !           668: lispval
        !           669: getatom()
        !           670: {   register lispval aptr;
        !           671:     register char *name, *endname;
        !           672:     lispval    b;
        !           673:     char       c;
        !           674:     register int hash;
        !           675:     snpand(4);
        !           676: 
        !           677:        name = strbuf;
        !           678:        if (*name == (char)0377) return (eofa);
        !           679:        hash = 0;
        !           680:        for(name=strbuf; *name;) {
        !           681:                hash ^= *name++;
        !           682:        }
        !           683:        hash &= 0177;   /*  make sure no high-order bits have crept in  */
        !           684:        atmlen = name - strbuf + 1;
        !           685:        aptr = (lispval) hasht[hash];
        !           686:        while (aptr != CNIL)
        !           687:            if (strcmp(strbuf,aptr->pname)==0)
        !           688:                return (aptr);
        !           689:            else
        !           690:                aptr = (lispval) aptr->hshlnk;
        !           691:        aptr = (lispval) newatom();
        !           692:        aptr->hshlnk = hasht[hash];
        !           693:        hasht[hash] = (struct atom *) aptr;
        !           694:        endname = name - 1;
        !           695:        name = strbuf;
        !           696:        if ((atmlen != 4) && (*name == 'c') && (*endname == 'r'))
        !           697:                {
        !           698:                b = newdot();
        !           699:                protect(b);
        !           700:                b->car = lambda;
        !           701:                b->cdr = newdot();
        !           702:                b = b->cdr;
        !           703:                b->car = newdot();
        !           704:                (b->car)->car = xatom;
        !           705:                while(TRUE)
        !           706:                        {
        !           707:                        b->cdr = newdot();
        !           708:                        b= b->cdr;
        !           709:                        if(++name == endname)
        !           710:                                {
        !           711:                                b->car= (lispval) xatom;
        !           712:                                aptr->fnbnd = unprot();
        !           713:                                break;
        !           714:                                }
        !           715:                        b->car= newdot();
        !           716:                        b= b->car;
        !           717:                        if((c = *name) == 'a') b->car = cara;
        !           718:                        else if (c == 'd') b->car = cdra;
        !           719:                        else{ unprot();
        !           720:                           break;
        !           721:                         }
        !           722:                        }
        !           723:                }
        !           724: 
        !           725:        return(aptr);
        !           726:        }
        !           727: 

unix.superglobalmegacorp.com

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