From: Brian Demsky Date: Sat, 21 Jul 2012 01:52:55 +0000 (-0700) Subject: more hashtable fixes X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=commitdiff_plain;h=c652f8c61178d4d97055ea51eb04601fd253827f more hashtable fixes clean up memory allocation code a bit --- diff --git a/hashtable.h b/hashtable.h index 4eae7571..126b6a43 100644 --- a/hashtable.h +++ b/hashtable.h @@ -8,11 +8,27 @@ #include #include -template +template struct hashlistnode { _Key key; _Val val; - struct hashlistnode<_Key,_Val> *next; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *next; + + void * operator new(size_t size) { + return _malloc(size); + } + + void operator delete(void *p, size_t size) { + _free(p); + } + + void * operator new[](size_t size) { + return _malloc(size); + } + + void operator delete[](void *p, size_t size) { + _free(p); + } }; /** Hashtable class. By default it is snapshotting, but you can pass @@ -23,7 +39,7 @@ template **) _calloc(initialcapacity, sizeof(struct hashlistnode<_Key,_Val> *)); + table = (struct hashlistnode<_Key,_Val, _malloc, _calloc,_free> **) _calloc(initialcapacity, sizeof(struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *)); loadfactor = factor; capacity = initialcapacity; threshold = (unsigned int) (initialcapacity*loadfactor); @@ -33,9 +49,9 @@ template * bin = table[i]; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> * bin = table[i]; while(bin!=NULL) { - struct hashlistnode<_Key,_Val> * next=bin->next; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> * next=bin->next; delete bin; bin=next; } @@ -47,7 +63,7 @@ template * bin = table[i]; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> * bin = table[i]; while(bin!=NULL) { - struct hashlistnode<_Key,_Val> * next=bin->next; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> * next=bin->next; delete bin; bin=next; } } - memset(table, 0, capacity*sizeof(struct hashlistnode<_Key, _Val> *)); + memset(table, 0, capacity*sizeof(struct hashlistnode<_Key, _Val, _malloc, _calloc, _free> *)); size=0; } @@ -81,9 +97,9 @@ template *ptr = table[(((_KeyInt)key) & mask)>>_Shift]; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *ptr = table[(((_KeyInt)key) & mask)>>_Shift]; size++; - struct hashlistnode<_Key,_Val> *search = ptr; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *search = ptr; while(search!=NULL) { if (search->key==key) { @@ -93,7 +109,7 @@ templatenext; } - struct hashlistnode<_Key,_Val> *newptr=(struct hashlistnode<_Key,_Val> *)new struct hashlistnode<_Key,_Val>; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *newptr=(struct hashlistnode<_Key,_Val,_malloc,_calloc,_free> *)new struct hashlistnode<_Key,_Val, _malloc, _calloc, _free>; newptr->key=key; newptr->val=val; newptr->next=ptr; @@ -108,9 +124,9 @@ template *ptr = table[(((_KeyInt)key) & mask)>>_Shift]; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *ptr = table[(((_KeyInt)key) & mask)>>_Shift]; size++; - struct hashlistnode<_Key,_Val> *search = ptr; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *search = ptr; while(search!=NULL) { if (search->key==key) { @@ -119,7 +135,7 @@ templatenext; } - struct hashlistnode<_Key,_Val> *newptr=(struct hashlistnode<_Key,_Val> *)new struct hashlistnode<_Key,_Val>; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *newptr=(struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *)new struct hashlistnode<_Key,_Val, _malloc, _calloc, _free>; newptr->key=key; newptr->next=ptr; table[(((_KeyInt)key)&mask)>>_Shift]=newptr; @@ -128,7 +144,7 @@ template *search = table[(((_KeyInt)key) & mask)>>_Shift]; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *search = table[(((_KeyInt)key) & mask)>>_Shift]; while(search!=NULL) { if (search->key==key) { @@ -141,7 +157,7 @@ template *search = table[(((_KeyInt)key) & mask)>>_Shift]; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *search = table[(((_KeyInt)key) & mask)>>_Shift]; while(search!=NULL) { if (search->key==key) { @@ -154,7 +170,7 @@ template *search = table[(((_KeyInt)key) & mask)>>_Shift]; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *search = table[(((_KeyInt)key) & mask)>>_Shift]; while(search!=NULL) { if (search->key==key) { @@ -167,11 +183,11 @@ template ** oldtable = table; - struct hashlistnode<_Key,_Val> ** newtable; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> ** oldtable = table; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> ** newtable; unsigned int oldcapacity = capacity; - if((newtable = (struct hashlistnode<_Key,_Val> **) _calloc(newsize, sizeof(struct hashlistnode<_Key,_Val> *))) == NULL) { + if((newtable = (struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> **) _calloc(newsize, sizeof(struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> *))) == NULL) { printf("Calloc error %s %d\n", __FILE__, __LINE__); exit(-1); } @@ -182,14 +198,14 @@ template * bin = oldtable[i]; + struct hashlistnode<_Key, _Val, _malloc, _calloc, _free> * bin = oldtable[i]; while(bin!=NULL) { _Key key=bin->key; - struct hashlistnode<_Key, _Val> * next=bin->next; + struct hashlistnode<_Key, _Val, _malloc, _calloc, _free> * next=bin->next; unsigned int index = (((_KeyInt)key) & mask) >>_Shift; - struct hashlistnode<_Key, _Val> * tmp=newtable[index]; + struct hashlistnode<_Key, _Val, _malloc, _calloc, _free> * tmp=newtable[index]; bin->next=tmp; newtable[index]=bin; bin = next; @@ -200,7 +216,7 @@ template **table; + struct hashlistnode<_Key,_Val, _malloc, _calloc, _free> **table; unsigned int capacity; _KeyInt mask; unsigned int size; diff --git a/mymemory.cc b/mymemory.cc index a365bb4c..b702d399 100644 --- a/mymemory.cc +++ b/mymemory.cc @@ -126,38 +126,41 @@ mspace mySpace = NULL; /** This global references the unaligned memory address that was malloced for the snapshotting heap */ void * basemySpace = NULL; -/** Adding the fix for not able to allocate through a reimplemented calloc at the beginning before instantiating our allocator -A bit circumspect about adding an sbrk. linux docs say to avoid using it... */ +/** Bootstrap allocation. Problem is that the dynamic linker calls + * require calloc to work and calloc requires the dynamic linker to + * work. */ + +#define BOOTSTRAPBYTES 4096 +char bootstrapmemory[BOOTSTRAPBYTES]; +size_t offset=0; + void * HandleEarlyAllocationRequest( size_t sz ){ - if( 0 == mySpace ){ - void * returnAddress = sbrk( sz ); - if( nextRequest >= REQUESTS_BEFORE_ALLOC ){ - exit( EXIT_FAILURE ); - } - allocatedReqs[ nextRequest++ ] = ( size_t )returnAddress; - return returnAddress; + /*Align to 8 byte boundary*/ + sz=(sz+7)&~7; + + if (sz > (BOOTSTRAPBYTES-offset)) { + printf("OUT OF BOOTSTRAP MEMORY\n"); + exit(EXIT_FAILURE); } - return NULL; + + void * pointer= (void *) & bootstrapmemory[offset]; + offset+=sz; + return pointer; } -/** The fact that I am not expecting more than a handful requests is implicit in my not using a binary search here*/ +/** Check whether this is bootstrapped memory that we should not + free. */ + bool DontFree( void * ptr ){ - if( howManyFreed == nextRequest ) return false; //a minor optimization to reduce the number of instructions executed on each free call.... - if( NULL == ptr ) return true; - for( int i = nextRequest - 1; i >= 0; --i ){ - if( allocatedReqs[ i ] == ( size_t )ptr ) { - ++howManyFreed; - return true; - } - } - return false; + return (ptr>=(&bootstrapmemory[0])&&ptr<(&bootstrapmemory[BOOTSTRAPBYTES])); } /** Snapshotting malloc implementation for user programs. */ void *malloc( size_t size ) { - void * earlyReq = HandleEarlyAllocationRequest( size ); - if( earlyReq ) return earlyReq; - return mspace_malloc( mySpace, size ); + if (mySpace) + return mspace_malloc( mySpace, size ); + else + return HandleEarlyAllocationRequest( size ); } /** Snapshotting free implementation for user programs. */ @@ -173,12 +176,13 @@ void *realloc( void *ptr, size_t size ){ /** Snapshotting calloc implementation for user programs. */ void * calloc( size_t num, size_t size ){ - void * earlyReq = HandleEarlyAllocationRequest( size * num ); - if( earlyReq ) { - std::memset( earlyReq, 0, size * num ); - return earlyReq; + if (mySpace) + return mspace_calloc( mySpace, num, size ); + else { + void *tmp=HandleEarlyAllocationRequest( size * num ); + std::memset( tmp, 0, size * num ); + return tmp; } - return mspace_calloc( mySpace, num, size ); } /** Snapshotting new operator for user programs. */