char *mprStrndupInternal(MPR_LOC_DEC(ctx, loc), const char *str, uint size) { char *newp; uint len; mprAssert(VALID_BLK(ctx)); if (str == 0) { str = ""; } len = strlen(str) + 1; len = min(len, size); if (len < MPR_SLAB_STR_MAX) { newp = mprSlabAllocBlock(MPR_LOC_PASS(ctx, loc), MPR_SLAB_STR_MAX, MPR_SLAB_STR_INC); } else { newp = mprAllocBlock(MPR_LOC_PASS(ctx, loc), len); } if (newp) { memcpy(newp, str, len); } return newp; }
int mprAllocStrcpy(MPR_LOC_DEC(ctx, loc), char **dest, int destMax, const char *src) { int len; mprAssert(dest); mprAssert(destMax >= 0); mprAssert(src); len = strlen(src); if (destMax > 0 && len >= destMax) { mprAssert(0); return MPR_ERR_WONT_FIT; } if (len > 0) { *dest = (char*) mprAllocBlock(MPR_LOC_PASS(ctx, loc), len); memcpy(*dest, src, len); (*dest)[len] = '\0'; } else { *dest = (char*) mprAlloc(ctx, 1); *dest = '\0'; len = 0; } return len; }
static int growSlab(MPR_LOC_DEC(ctx, loc), MprSlab *slab, uint size, uint inc) { MprBlk *bp; MprSlabBlock *sb; int i, chunkSize, len; mprAssert(VALID_BLK(ctx)); mprAssert(slab); mprAssert(size > 0); /* * Take the maximum requested by anyone */ slab->preAllocateIncr = max(slab->preAllocateIncr, inc); /* * We allocate an array of blocks each of user "size" bytes. */ chunkSize = HDR_SIZE + size; len = chunkSize * slab->preAllocateIncr; bp = mprAllocBlock(MPR_LOC_PASS(ctx, loc), len); #if BLD_DEBUG memset(bp, 0xf1, len); #endif if (bp == 0) { mprAssert(0); return MPR_ERR_MEMORY; } bp->flags |= ALLOC_FLAGS_IS_SLAB; /* * We store the slab information in the user data portion */ sb = (MprSlabBlock*) GET_PTR(bp); sb = (MprSlabBlock*) ((char*) sb + len - chunkSize); for (i = slab->preAllocateIncr - 1; i >= 0; i--) { sb->next = slab->next; slab->next = sb; sb = (MprSlabBlock*) ((char*) sb - chunkSize); } #if BLD_FEATURE_ALLOC_STATS { MprSlabStats *stats; stats = &slab->stats; stats->freeCount += slab->preAllocateIncr; if (stats->freeCount > stats->peakFreeCount) { stats->peakFreeCount = stats->freeCount; } } #endif return 0; }
void *mprAllocZeroedBlock(MPR_LOC_DEC(ctx, loc), uint size) { void *newBlock; MprBlk *bp; bp = GET_HDR(ctx); mprAssert(VALID_BLK(ctx)); newBlock = mprAllocBlock(MPR_LOC_PASS(ctx, loc), size); if (newBlock) { memset(newBlock, 0, size); } return newBlock; }
PUBLIC void *ecCreateStream(EcCompiler *cp, ssize size, cchar *path, void *manager) { EcLocation *loc; EcStream *sp; if ((sp = mprAllocBlock(size, MPR_ALLOC_ZERO | MPR_ALLOC_MANAGER)) == 0) { return NULL; } mprSetManager(sp, manager); sp->compiler = cp; cp->stream = sp; loc = &sp->loc; loc->column = 0; loc->source = 0; loc->lineNumber = 1; loc->filename = sclone(path); cp->putback = NULL; return sp; }
void *mprMemdupInternal(MPR_LOC_DEC(ctx, loc), const void *ptr, uint size) { char *newp; mprAssert(VALID_BLK(ctx)); if (size < MPR_SLAB_STR_MAX) { newp = mprSlabAllocBlock(MPR_LOC_PASS(ctx, loc), MPR_SLAB_STR_MAX, MPR_SLAB_STR_INC); } else { newp = mprAllocBlock(MPR_LOC_PASS(ctx, loc), size); } if (newp) { memcpy(newp, ptr, size); } return newp; }
int mprAllocMemcpy(MPR_LOC_DEC(ctx, loc), char **dest, int destMax, const void *src, int nbytes) { mprAssert(dest); mprAssert(src); mprAssert(nbytes > 0); mprAssert(destMax <= 0 || destMax >= nbytes); if (destMax > 0 && nbytes > destMax) { mprAssert(0); return MPR_ERR_WONT_FIT; } if (nbytes > 0) { *dest = (char*) mprAllocBlock(MPR_LOC_PASS(ctx,loc), nbytes); if (*dest == 0) { return MPR_ERR_MEMORY; } memcpy(*dest, src, nbytes); } else { *dest = (char*) mprAlloc(ctx, 1); } return nbytes; }
static int mprCoreStrcat(MPR_LOC_DEC(ctx, loc), char **destp, int destMax, int existingLen, const char *delim, const char *src, va_list args) { va_list ap; char *dest, *str, *dp; int sepLen, addBytes, required; mprAssert(destp); mprAssert(destMax >= 0); mprAssert(src); dest = *destp; sepLen = (delim) ? strlen(delim) : 0; #ifdef __va_copy __va_copy(ap, args); #else ap = args; #endif addBytes = 0; if (existingLen > 0) { addBytes += sepLen; } str = (char*) src; while (str) { addBytes += strlen(str); str = va_arg(ap, char*); if (str) { addBytes += sepLen; } } required = existingLen + addBytes + 1; if (destMax > 0 && required >= destMax) { mprAssert(0); return MPR_ERR_WONT_FIT; } if (ctx != 0) { if (dest == 0) { dest = (char*) mprAllocBlock(MPR_LOC_PASS(ctx, loc), required); } else { dest = (char*) mprReallocBlock(MPR_LOC_PASS(ctx, loc), dest, required); } } else { dest = (char*) *destp; } dp = &dest[existingLen]; if (delim && existingLen > 0) { strcpy(dp, delim); dp += sepLen; } if (addBytes > 0) { #ifdef __va_copy __va_copy(ap, args); #else ap = args; #endif str = (char*) src; while (str) { strcpy(dp, str); dp += strlen(str); str = va_arg(ap, char*); if (delim && str) { strcpy(dp, delim); dp += sepLen; } } } else if (dest == 0) {
static int mprSprintfCore(MPR_LOC_DEC(ctx, loc), char **bufPtr, int maxsize, const char *spec, va_list arg) { Format fmt; char *cp; char c; char *sValue; num iValue; unum uValue; int count, i, len, state; mprAssert(bufPtr); mprAssert(spec); if (*bufPtr != 0) { mprAssert(maxsize > 0); fmt.buf = (uchar*) *bufPtr; fmt.endbuf = &fmt.buf[maxsize]; fmt.growBy = 0; } else { if (maxsize <= 0) { maxsize = MAXINT; } len = min(MPR_DEFAULT_ALLOC, maxsize); fmt.buf = (uchar*) mprAllocBlock(MPR_LOC_PASS(ctx, loc), len); fmt.endbuf = &fmt.buf[len]; fmt.growBy = MPR_DEFAULT_ALLOC * 2; } fmt.maxsize = maxsize; fmt.start = fmt.buf; fmt.end = fmt.buf; fmt.len = 0; *fmt.start = '\0'; state = STATE_NORMAL; while ((c = *spec++) != '\0') { state = getState(c, state); switch (state) { case STATE_NORMAL: BPUT(ctx, loc, &fmt, c); break; case STATE_PERCENT: fmt.precision = -1; fmt.width = 0; fmt.flags = 0; break; case STATE_MODIFIER: switch (c) { case '+': fmt.flags |= SPRINTF_SIGN; break; case '-': fmt.flags |= SPRINTF_LEFT; break; case '#': fmt.flags |= SPRINTF_ALTERNATE; break; case '0': fmt.flags |= SPRINTF_LEAD_ZERO; break; case ' ': fmt.flags |= SPRINTF_LEAD_SPACE; break; case ',': fmt.flags |= SPRINTF_COMMA; break; } break; case STATE_WIDTH: if (c == '*') { fmt.width = va_arg(arg, int); if (fmt.width < 0) { fmt.width = -fmt.width; fmt.flags |= SPRINTF_LEFT; } } else { while (isdigit((int)c)) { fmt.width = fmt.width * 10 + (c - '0'); c = *spec++; } spec--; } break; case STATE_DOT: fmt.precision = 0; fmt.flags &= ~SPRINTF_LEAD_ZERO; break; case STATE_PRECISION: if (c == '*') { fmt.precision = va_arg(arg, int); } else {
void *mprSlabAllocBlock(MPR_LOC_DEC(ctx, loc), uint size, uint inc) { #if NO_SLAB return mprAllocBlock(MPR_LOC_PASS(ctx, loc), size); #else MprBlk *parent, *bp; MprSlabBlock *sb; MprApp *app; MprSlab *slab; int slabIndex; if (ctx == 0) { mprAssert(ctx); return 0; } mprAssert(size > 0); mprAssert(VALID_BLK(ctx)); parent = GET_HDR(ctx); mprAssert(VALID_HDR(parent)); CHECK_HDR(parent); size = SLAB_ALIGN(size); app = parent->app; mprAssert(app); slabIndex = GET_SLAB(size); if (slabIndex < 0 || slabIndex >= MPR_MAX_SLAB) { return mprAllocBlock(MPR_LOC_PASS(ctx, loc), size); } /* * Dequeue a block from the slab. "sb" will point to the user data * portion of the block (i.e. after the MprBlk header). Slabs must be * allocated off the "slabs" context to ensure they don't get freed * until after all other blocks are freed. */ mprLock(app->allocLock); slab = &app->alloc.slabs[slabIndex]; if ((sb = slab->next) == 0) { if (growSlab(MPR_LOC_ARGS(parent->app->alloc.slabs), slab, size, inc) < 0) { mprUnlock(app->allocLock); return 0; } sb = slab->next; } mprAssert(sb); /* * Dequeue the block */ slab->next = sb->next; #if BLD_FEATURE_ALLOC_STATS { MprSlabStats *slabStats; /* * Update the slab stats */ slabStats = &slab->stats; slabStats->totalAllocCount++; slabStats->freeCount--; slabStats->allocCount++; if (slabStats->allocCount > slabStats->peakAllocCount) { slabStats->peakAllocCount = slabStats->allocCount; } } #endif /* BLD_FEATURE_ALLOC_STATS */ bp = GET_HDR(sb); #if BLD_DEBUG && !BREW if (bp == stopAlloc) { mprBreakpoint(MPR_LOC, "breakOnAddr"); } #endif bp->size = size; bp->flags = ALLOC_MAGIC | ALLOC_FLAGS_SLAB_BLOCK; bp->destructor = 0; bp->parent = parent; if (parent->children == 0) { parent->children = bp; bp->next = bp->prev = bp; } else { /* * Append to the end of the list. Preserve alloc order */ bp->next = parent->children; bp->prev = parent->children->prev; parent->children->prev->next = bp; parent->children->prev = bp; } bp->children = 0; bp->app = app; #if BLD_FEATURE_ALLOC_LEAK_TRACK bp->location = loc; #endif mprUnlock(app->allocLock); return GET_PTR(bp); #endif }
void *mprReallocBlock(MPR_LOC_DEC(ctx, loc), void *ptr, uint size) { MprBlk *bp, *newbp, *firstChild, *cp; MprApp *app; void *newPtr; mprAssert(VALID_BLK(ctx)); mprAssert(size > 0); if (ptr == 0) { return mprAllocBlock(MPR_LOC_PASS(ctx, loc), size); } mprAssert(VALID_BLK(ptr)); bp = GET_HDR(ptr); mprAssert(bp); mprAssert(VALID_HDR(bp)); CHECK_HDR(bp); if (size < bp->size) { return ptr; } newPtr = mprAllocBlock(MPR_LOC_PASS(ctx, loc), size); if (newPtr == 0) { bp->flags &= ~ALLOC_FLAGS_FREE; free(bp); return 0; } newbp = GET_HDR(newPtr); mprAssert(newbp->size >= size); memcpy((char*) newbp + HDR_SIZE, (char*) bp + HDR_SIZE, bp->size); mprAssert(newbp->size >= size); /* * Fix the next / prev pointers */ app = bp->app; mprLock(app->allocLock); newbp->next->prev = newbp; newbp->prev->next = newbp; /* * Need to fix the parent pointer of all children */ if ((firstChild = newbp->children) != 0) { cp = firstChild; do { cp->parent = newbp; cp = cp->next; } while (cp != firstChild); } /* * May need to set the children pointer of our parent */ if (newbp->parent->children == bp) { newbp->parent->children = newbp; } /* * Free the original block */ mprFree(ptr); mprUnlock(app->allocLock); return GET_PTR(newbp); }