add bulk memory operations and memtest
[tedtools.git] / tmalloc.c
index 953e28f..d6c0b76 100644 (file)
--- a/tmalloc.c
+++ b/tmalloc.c
@@ -117,3 +117,160 @@ clrspace(char *buf) {
         return ptrc - buf;
 }
 
+
+MemoryContext *
+allocMemoryContext(MemoryContext* parent, int flags) {
+       MemoryContext *res;
+
+       res = (MemoryContext*)tmalloc( sizeof(MemoryContext) );
+       res->flags = flags;
+       res->parent = parent;
+       if ( parent ) {
+               res->child = parent->child;
+               parent->child = res;
+       } else
+               res->child = NULL;
+
+       res->chunk = (MemoryChunk*)tmalloc( MEMCHNKHDRSZ + CNTXCHUNK );
+       res->chunk->size = res->chunk->freesize = CNTXCHUNK;
+       res->chunk->next = NULL;
+
+       return res;
+}
+
+void
+freeMemoryContext(MemoryContext *cntx) {
+       MemoryContext   *ptr=cntx;
+       MemoryChunk     *chunk, *chunkptr;
+
+       if ( cntx->parent )
+               cntx->parent->child=NULL;
+
+       while( ptr ) {
+               cntx=ptr->child;
+
+               chunkptr=ptr->chunk;
+               while( chunkptr ) {
+                       chunk=chunkptr->next;
+                       tfree(chunkptr);
+                       chunkptr=chunk;
+               }
+               
+               tfree(ptr);
+               ptr=cntx;
+       }
+}
+
+void*   
+mcalloc(MemoryContext *cntx, size_t size) {
+       MemoryChunk     *chunk = cntx->chunk;
+       MCAllocatedSpace *alloc;
+
+       size = PTRALIGN(size) + MCASHDRSZ;
+       if ( cntx->flags & MC_DEBUG )
+               size += sizeof(u_int32_t);
+
+       if ( chunk->freesize < size ) {
+               MemoryChunk     *newchunk;
+
+               if ( size >= CNTXCHUNK ) {
+                       newchunk = (MemoryChunk*)tmalloc(MEMCHNKHDRSZ + size);
+                       newchunk->size = newchunk->freesize = size;
+                       newchunk->next = chunk->next;
+                       chunk->next = newchunk;
+               } else {
+                       newchunk = (MemoryChunk*)tmalloc(MEMCHNKHDRSZ + CNTXCHUNK);
+                       newchunk->size = newchunk->freesize = CNTXCHUNK;
+                       newchunk->next = chunk;
+                       cntx->chunk = newchunk; 
+               }
+
+               chunk = newchunk;
+       }
+
+       chunk->freesize -= size;
+       alloc = (MCAllocatedSpace*)( chunk->data + chunk->freesize );
+       alloc->size = size; 
+       alloc->cntx = cntx;
+       if ( cntx->flags & MC_DEBUG ) {
+               *(u_int32_t*)((char*)alloc + alloc->size - sizeof(u_int32_t) ) = MCMAGICKNUMBER;
+               memset( alloc->data, 0xc3, size - MCASHDRSZ - sizeof(u_int32_t) ); 
+       }
+
+       return (void*)(alloc->data);
+}
+
+void *
+mc0alloc(MemoryContext *cntx, size_t size) {
+       void *res = mcalloc(cntx, size);
+       memset( res, 0, size );
+       return res;
+}
+
+void *
+mcrealloc(void * ptr, size_t size) {
+       MCAllocatedSpace        *alloc = (MCAllocatedSpace*)( (char*)ptr - MCASHDRSZ );
+       size_t realsize;
+
+       if ( ptr==NULL )
+               tlog(TL_CRIT|TL_EXIT, "mcrealloc: realloc null pointer");
+
+       if ( alloc->cntx->flags & MC_DEBUG ) {
+               tassert(  *(u_int32_t*)( (char*)alloc + alloc->size - sizeof(u_int32_t) ) == MCMAGICKNUMBER );
+               realsize = alloc->size - MCASHDRSZ - sizeof(u_int32_t); 
+       } else
+               realsize = alloc->size - MCASHDRSZ;
+
+       if ( size > realsize ) {
+               if ( (char*)alloc == alloc->cntx->chunk->data + alloc->cntx->chunk->freesize && 
+                               PTRALIGN(size)-realsize <= alloc->cntx->chunk->freesize ) {
+                       /* just enlarge */
+                       alloc->cntx->chunk->freesize -= PTRALIGN(size)-realsize;
+                       alloc->size+=PTRALIGN(size)-realsize;
+                       if ( alloc->cntx->flags & MC_DEBUG ) {
+                               memset( (char*)(alloc->data) + realsize,  0xc3, PTRALIGN(size)-realsize );
+                               *(u_int32_t*)((char*)alloc + alloc->size - sizeof(u_int32_t) ) = MCMAGICKNUMBER;
+                       }
+               } else {  
+                       void *newptr = mcalloc(alloc->cntx, size);
+                       memcpy( newptr, ptr, realsize );
+                       ptr = newptr;
+                       if ( alloc->cntx->flags & MC_DEBUG ) 
+                               memset( (char*)ptr + realsize, 0xc3, PTRALIGN(size)-realsize );
+               }
+       }
+       return ptr;
+}
+
+
+void    
+mcfree(void * ptr) {
+       MCAllocatedSpace        *alloc = (MCAllocatedSpace*)( (char*)ptr - MCASHDRSZ );
+
+       if ( ptr==NULL )
+               tlog(TL_CRIT|TL_EXIT, "mcfree: free null pointer");
+
+       if ( alloc->cntx->flags & MC_DEBUG ) 
+               tassert(  *(u_int32_t*)((char*)alloc + alloc->size - sizeof(u_int32_t) ) == MCMAGICKNUMBER );
+
+       if ( (char*)alloc == alloc->cntx->chunk->data + alloc->cntx->chunk->freesize ) /* last allocated value */
+               alloc->cntx->chunk->freesize+=alloc->size;
+
+       alloc->cntx=NULL;
+}
+
+char * 
+mcstrdup(MemoryContext *cntx, char * src) {
+       return mcnstrdup(cntx, src, strlen(src));
+}
+
+char *
+mcnstrdup(MemoryContext *cntx, char *src, int len) {
+       char *dest=(char*)mcalloc(cntx, len+1);
+       memcpy(dest, src, len);
+       dest[len]='\0';
+       return dest;
+}
+