int bopen(void *buf, int bufsize, int flags) { bFlags = flags; #ifdef BASTARD_TESTING srand(time(0L)); #endif /* BASTARD_TESTING */ /* * If bopen already called by a shared process, just increment the count * and return; */ if (++bopenCount > 1) { return 0; } if (buf == NULL) { if (bufsize == 0) { bufsize = B_DEFAULT_MEM; } #ifdef IRIX bufsize = ROUNDUP4(bufsize); #endif if ((buf = malloc(bufsize)) == NULL) { /* resetting bopenCount lets client code decide to attempt to call * bopen() again with a smaller memory request, should it desire to. * Fix suggested by Simon Byholm. */ --bopenCount; return -1; } #ifdef B_STATS bStatsMemMalloc += bufsize; #endif } else { bFlags |= B_USER_BUF; } bFreeSize = bFreeLeft = bufsize; bFreeBuf = bFreeNext = buf; memset(bQhead, 0, sizeof(bQhead)); #if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) bFillBlock(buf, bufsize); #endif #ifdef B_STATS bStackStart = &buf; #endif #ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD verifyFreeBlock(buf, bufsize); #endif return 0; }
int bopen(void *buf, int bufsize, int flags) { bFlags = flags; #ifdef BASTARD_TESTING srand(time(0L)); #endif /* BASTARD_TESTING */ /* * If bopen already called by a shared process, just increment the count * and return; */ if (++bopenCount > 1) { return 0; } if (buf == NULL) { if (bufsize == 0) { bufsize = B_DEFAULT_MEM; } #ifdef IRIX bufsize = ROUNDUP4(bufsize); #endif #if FIXMEM buf = (void *)MEM_START; #else if ((buf = malloc(bufsize)) == NULL) { return -1; } #endif #ifdef B_STATS bStatsMemMalloc += bufsize; #endif } else { bFlags |= B_USER_BUF; } bFreeSize = bFreeLeft = bufsize; bFreeBuf = bFreeNext = buf; memset(bQhead, 0, sizeof(bQhead)); #if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) bFillBlock(buf, bufsize); #endif #ifdef B_STATS bStackStart = &buf; #endif #ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD verifyFreeBlock(buf, bufsize); #endif return 0; }
void verifyBallocSpace() { int q; char *p; bType *bp; /* * First verify all the free blocks. */ for (q = 0; q < B_MAX_CLASS; q++) { for (bp = bQhead[q]; bp != NULL; bp = bp->u.next) { verifyFreeBlock(bp, q); } } /* * Now verify other space */ p = bFreeBuf; while (p < (bFreeBuf + bFreeSize)) { bp = (bType *)p; if (bp->u.size > 0xFFFFF) { p += sizeof(bp->u); while (p < (bFreeBuf + bFreeSize) && *p == B_FILL_CHAR) { p++; } } else { a_assert(((bp->flags & ~B_MALLOCED) == B_INTEGRITY) || bp->flags == B_FILL_WORD); p += (sizeof(bType) + bp->u.size); while (p < (bFreeBuf + bFreeSize) && *p == B_FILL_CHAR) { p++; } } } }
void *balloc(B_ARGS_DEC, int size) { bType *bp; int q, memSize; /* * Call bopen with default values if the application has not yet done so */ if (bFreeBuf == NULL) { if (bopen(NULL, B_DEFAULT_MEM, 0) < 0) { return NULL; } } #ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD verifyBallocSpace(); #endif if (size < 0) { return NULL; } #ifdef BASTARD_TESTING if (rand() == 0x7fff) { return NULL; } #endif /* BASTARD_TESTING */ memSize = ballocGetSize(size, &q); if (q >= B_MAX_CLASS) { /* * Size if bigger than the maximum class. Malloc if use has been okayed */ if (bFlags & B_USE_MALLOC) { #ifdef B_STATS bstats(0, NULL); #endif #ifdef IRIX memSize = ROUNDUP4(memSize); #endif bp = (bType*) malloc(memSize); if (bp == NULL) { traceRaw(T("B: malloc failed\n")); return NULL; } #ifdef B_STATS bStatsMemMalloc += memSize; #endif #if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) bFillBlock(bp, memSize); #endif } else { traceRaw(T("B: malloc failed\n")); return NULL; } /* * the u.size is the actual size allocated for data */ bp->u.size = memSize - sizeof(bType); bp->flags = B_MALLOCED; } else if ((bp = bQhead[q]) != NULL) { /* * Take first block off the relevant q if non-empty */ bQhead[q] = bp->u.next; #ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD verifyFreeBlock(bp, q); #endif #if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) bFillBlock(bp, memSize); #endif bp->u.size = memSize - sizeof(bType); bp->flags = 0; } else { if (bFreeLeft > memSize) { /* * The q was empty, and the free list has spare memory so * create a new block out of the primary free block */ bp = (bType*) bFreeNext; #ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD verifyFreeBlock(bp, q); #endif bFreeNext += memSize; bFreeLeft -= memSize; #if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) bFillBlock(bp, memSize); #endif bp->u.size = memSize - sizeof(bType); bp->flags = 0; } else if (bFlags & B_USE_MALLOC) { #ifdef B_STATS static int once = 0; if (once++ == 0) { bstats(0, NULL); } #endif /* * Nothing left on the primary free list, so malloc a new block */ #ifdef IRIX memSize = ROUNDUP4(memSize); #endif if ((bp = (bType*) malloc(memSize)) == NULL) { traceRaw(T("B: malloc failed\n")); return NULL; } #ifdef B_STATS bStatsMemMalloc += memSize; #endif #if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) bFillBlock(bp, memSize); #endif bp->u.size = memSize - sizeof(bType); bp->flags = B_MALLOCED; } else { traceRaw(T("B: malloc failed\n")); return NULL; } } #ifdef B_STATS bStatsAlloc(B_ARGS, bp, q, memSize); #endif bp->flags |= B_INTEGRITY; /* * The following is a good place to put a breakpoint when trying to reduce * determine and reduce maximum memory use. */ #if 0 #ifdef B_STATS if (bStatsBallocInUse == bStatsBallocMax) { bstats(0, NULL); } #endif #endif return (void*) ((char*) bp + sizeof(bType)); }