void *xmgetblk(int i) { int j,w,*m,*q,**r; w = i << 3; /* number of words */ /* * allocate block */ /* M01.01a.0708.01 */ if( i >= MAXQUICK ) { dbggtblk++ ; return( NULL ) ; } if( *(r = &root[i]) ) { /* there is an item on the list */ m = *r; /* get 1st item on list */ *r = *((int **) m); /* root pts to next item */ } else { /* nothing on list, try pool */ if ( (m = getosm(w+1)) ) /* add size of control word */ *m++ = i; /* put size in control word */ } /* * zero out the block */ if( (q = m) ) for( j = 0 ; j < w ; j++ ) *q++ = 0; return(m); }
/* * xmgetblk - get a block of memory from the o/s pool. * * First try to get a block from the 'fast' list, anchored by root[4], * a list of blocks of size 64 bytes. This list is singly linked and * blocks are deleted/removed in LIFO order from the root. If there * are no free blocks on the list, we call getosm to get a block from * the os memory pool. * * If we cannot get memory for an MDBLOCK, we return NULL (the request * will fail). Otherwise we will attempt to free up DNDs to make space * and if that fails, the system will be halted. * * Arguments: * memtype: the type of request */ void *xmgetblk(WORD memtype) { WORD i, j, w, *m, *q, **r; if ((memtype < MEMTYPE_MDBLOCK) || (memtype > MEMTYPE_OFD)) { dbggtblk++; return NULL; } /* * allocate block */ i = 4; /* always from root[4] */ w = 32; /* number of words */ /* * we should execute the following loop a maximum of twice: the second * time only if we're allocating a DMD/DND/OFD & no memory is available */ for (j = 0; ; j++) { if ( *(r = &root[i]) ) /* there is an item on the free list */ { m = *r; /* get first item on list */ *r = *((WORD **) m); /* root points to next item */ break; } /* nothing on free list, try pool */ if ( (m = getosm(w+1)) ) /* include size of control word */ { *m++ = i; /* put size in control word */ break; } /* no memory available for an MDBLOCK, that's (sort of) OK */ if (memtype == MEMTYPE_MDBLOCK) break; /* * no memory for DMD/DND/OFD, try to get some * * note defensive programming: if free_available_dnds() said it * worked, but we're here again, then it lied and we should quit * to avoid an infinite loop */ if ((j >= 2) || (free_available_dnds() == 0)) { kcprintf(_("\033EOut of internal memory.\nUse FOLDR100.PRG to get more.\nSystem halted!\n")); halt(); /* halt system */ } } /* * zero out the block */ if ( (q = m) ) for (j = 0; j < w; j++) *q++ = 0; return m; }