2f313d36a367752cb1925bf3b514cc5c11ce343b tdreszer Mon Jan 28 11:45:16 2013 -0800 Added local memeory support for bits and a couple of routines to query lm size. diff --git src/lib/localmem.c src/lib/localmem.c index e364a66..276b663 100644 --- src/lib/localmem.c +++ src/lib/localmem.c @@ -62,73 +62,103 @@ newBlock(lm, blockSize); return lm; } void lmCleanup(struct lm **pLm) /* Clean up a local memory pool. */ { struct lm *lm = *pLm; if (lm == NULL) return; slFreeList(&lm->blocks); freeMem(lm); *pLm = NULL; } +int lmFlushZ(struct lm *lm) +// Zero's and makes available most recent block of pool, abandoning older blocks +// USE WITH CAUTION: All previous pointers into lm will be invalid +{ +slFreeList(&(lm->blocks->next)); // free any extra blocks +struct lmBlock *mb = lm->blocks; +mb->free = (char *)(mb+1); +size_t fullSize = (mb->end - mb->free); +memset(mb->free,0,fullSize); +return fullSize; +} + +size_t lmAvailable(struct lm *lm) +// Returns currently available memory in pool +{ +struct lmBlock *mb = lm->blocks; +return (mb->end - mb->free); +} + +size_t lmSize(struct lm *lm) +// Returns current size of pool, even for memory already allocated +{ +size_t fullSize = 0; + +struct lmBlock *mb = lm->blocks; +for (;mb != NULL;mb = mb->next) + fullSize += (mb->end - (char *)(mb+1)); + +return fullSize; +} + void *lmAlloc(struct lm *lm, size_t size) /* Allocate memory from local pool. */ { struct lmBlock *mb = lm->blocks; void *ret; size_t memLeft = mb->end - mb->free; if (memLeft < size) mb = newBlock(lm, size); ret = mb->free; mb->free += ((size+lm->allignAdd)&lm->allignMask); if (mb->free > mb->end) mb->free = mb->end; return ret; } -void *lmCloneMem(struct lm *lm, void *pt, size_t size) -/* Return a local mem copy of memory block. */ -{ -void *d = lmAlloc(lm, size); -memcpy(d, pt, size); -return d; -} - -char *lmCloneStringZ(struct lm *lm, char *string, int size) -/* Return local mem copy of string. */ +void *lmAllocMoreMem(struct lm *lm, void *pt, size_t oldSize, size_t newSize) +/* Adjust memory size on a block, possibly relocating it. If block is grown, + * new memory is zeroed. */ { -if (string == NULL) - return NULL; -else +struct lmBlock *mb = lm->blocks; +// rare case that pointer is to last lm alloc, but still try. +// Note this is the one place where the pointer gets reused and it is known to be in this lm +// Since lm allocs are never freed, this means the pointer CAN be reused (by lmCloneMem) +if ((char *)pt + oldSize == mb->free +&& (char *)pt + newSize <= mb->end) { - char *s = lmAlloc(lm, size+1); - memcpy(s, string, size); - return s; + if (newSize > oldSize) // only move the free pointer on more mem + mb->free = pt + newSize; + return pt; } +void *new = lmAlloc(lm, newSize); +memcpy(new, pt, oldSize); +return new; } -char *lmCloneString(struct lm *lm, char *string) +char *lmCloneStringZ(struct lm *lm, char *string, int size) /* Return local mem copy of string. */ { if (string == NULL) return NULL; -else - return lmCloneStringZ(lm, string, strlen(string)); +else // in rare cases, this returns the same mem + return lmAllocMoreMem(lm, string, size, size + 1); // but lm allocs are never freed so it works } char *lmCloneFirstWord(struct lm *lm, char *line) /* Clone first word in line */ { char *startFirstWord = skipLeadingSpaces(line); if (startFirstWord == NULL) return NULL; char *endFirstWord = skipToSpaces(startFirstWord); if (endFirstWord == NULL) return lmCloneString(lm, startFirstWord); else return lmCloneStringZ(lm, startFirstWord, endFirstWord - startFirstWord); }