Annotation of 3BSD/cmd/lisp/Talloc.c, revision 1.1.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.