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