void * getNewMemChunkFromOS_and_Initialize() {
	//_mem gives the ADDRESS of the memory chunk given by OS.
	void * _mem = getMemoryFromOS( ArenaSize + (2*sizeof(ObjectHeader)) + (2*sizeof(ObjectFooter)) );

	//establish fence posts
	//step1:fencepost1
	struct ObjectFooter * fencepost1 = (struct ObjectFooter *)_mem;
	fencepost1->_allocated = 1;
	fencepost1->_objectSize = 123456789;//the size doesn't matter


	char * temp = (char *)_mem + (2*sizeof(struct ObjectFooter)) + sizeof(struct ObjectHeader) + ArenaSize;

	//step2
	struct ObjectHeader * fencepost2 = (struct ObjectHeader *)temp;

	fencepost2->_allocated = 1;
	fencepost2->_objectSize = 123456789;
	fencepost2->_next = NULL;
	fencepost2->_prev = NULL;

	//initialize the list to point to the _mem
	//step3
	temp = (char *) _mem + sizeof(struct ObjectFooter);
	ObjectHeader * currentHeader = (struct ObjectHeader *) temp;

	//step4
	temp = (char *)_mem + sizeof(struct ObjectFooter) + sizeof(struct ObjectHeader) + ArenaSize;
	ObjectFooter * currentFooter = (struct ObjectFooter *) temp;


	//set the size
	currentHeader->_objectSize = ArenaSize + sizeof(struct ObjectHeader) + sizeof(struct ObjectFooter); //initially around 2MB
	currentHeader->_allocated = 0;//all as free memory, only 1 chunk

	currentFooter->_allocated = 0;
	currentFooter->_objectSize = currentHeader->_objectSize;


	//add to the exiting freelist
	ObjectHeader * lastNode =  _freeList->_prev;

	lastNode->_next = currentHeader;
	currentHeader->_prev = lastNode;
	currentHeader->_next = _freeList;
	_freeList->_prev = currentHeader;

	//increase count of mem chunks that got from OS
	_numChunks++;

	return currentHeader;
}
Beispiel #2
0
void initialize()
{
	// Environment var VERBOSE prints stats at end and turns on debugging
	// Default is on
	_verbose = 1;
	const char * envverbose = getenv( "MALLOCVERBOSE" );
	if ( envverbose && !strcmp( envverbose, "NO") ) {
	_verbose = 0;
	}

	pthread_mutex_init(&mutex, NULL);
	void * _mem = getMemoryFromOS( ArenaSize + (2*sizeof(struct ObjectHeader)) + (2*sizeof(struct ObjectFooter)) );

	// In verbose mode register also printing statistics at exit
	atexit( atExitHandlerInC );

	//establish fence posts
	struct ObjectFooter * fencepost1 = (struct ObjectFooter *)_mem;
	fencepost1->_allocated = 1;
	fencepost1->_objectSize = 123456789;
	char * temp = 
	  (char *)_mem + (2*sizeof(struct ObjectFooter)) + sizeof(struct ObjectHeader) + ArenaSize;
	struct ObjectHeader * fencepost2 = (struct ObjectHeader *)temp;
	fencepost2->_allocated = 1;
	fencepost2->_objectSize = 123456789;
	fencepost2->_next = NULL;
	fencepost2->_prev = NULL;

	//initialize the list to point to the _mem
	temp = (char *) _mem + sizeof(struct ObjectFooter);
	struct ObjectHeader * currentHeader = (struct ObjectHeader *) temp;
	temp = (char *)_mem + sizeof(struct ObjectFooter) + sizeof(struct ObjectHeader) + ArenaSize;
	struct ObjectFooter * currentFooter = (struct ObjectFooter *) temp;
	_freeList = &_freeListSentinel;
	currentHeader->_objectSize = ArenaSize + sizeof(struct ObjectHeader) + sizeof(struct ObjectFooter); //2MB
	currentHeader->_allocated = 0;
	currentHeader->_next = _freeList;
	currentHeader->_prev = _freeList;
	currentFooter->_allocated = 0;
	currentFooter->_objectSize = currentHeader->_objectSize;
	_freeList->_prev = currentHeader;
	_freeList->_next = currentHeader; 
	_freeList->_allocated = 2; // sentinel. no coalescing.
	_freeList->_objectSize = 0;
	_memStart = (char*) currentHeader;
}
Beispiel #3
0
struct ObjectHeader * findValidSpot(size_t size) {

	struct ObjectHeader * ptr = _freeList->_next;
	while(ptr != _freeList){
		if (ptr->_allocated == 0) {
			if (ptr->_objectSize >= size){            //find the first block large enough to satisfy the request.   
				return ptr;
			}
		}
		ptr = ptr->_next;
	}
	if (ptr == _freeList){
		void * _mem = getMemoryFromOS( ArenaSize + (2*sizeof(struct ObjectHeader)) + (2*sizeof(struct ObjectFooter)) );
		//establish fence posts
		struct ObjectFooter * fencepost1 = (struct ObjectFooter *)_mem;
		fencepost1->_allocated = 1;
		fencepost1->_objectSize = 123456789;
		char * temp =
			(char *)_mem + (2*sizeof(struct ObjectFooter)) + sizeof(struct ObjectHeader) + ArenaSize;
		struct ObjectHeader * fencepost2 = (struct ObjectHeader *)temp;
		fencepost2->_allocated = 1;
		fencepost2->_objectSize = 123456789;
		fencepost2->_next = NULL;
		fencepost2->_prev = NULL;
		//initialize the list to point to the _mem
		temp = (char *) _mem + sizeof(struct ObjectFooter);
		struct ObjectHeader * header = (struct ObjectHeader *) temp;
		temp = (char *)_mem + sizeof(struct ObjectFooter) + sizeof(struct ObjectHeader) + ArenaSize;
		struct ObjectFooter * footer = (struct ObjectFooter *) temp;
		header->_objectSize = ArenaSize + (sizeof(struct ObjectHeader)) + (sizeof(struct ObjectFooter));
		header->_allocated = 0;
		footer->_allocated = 0;
		footer->_objectSize = header->_objectSize;
		struct ObjectHeader * tmp = _freeList->_prev->_prev;
		long offset = (long)tmp - (long)_memStart;
		offset = (long)header - (long)_memStart;
		offset = (long)_freeList - (long)_memStart;
		header->_next = _freeList;
		tmp->_next = header;
		header->_prev = tmp;
		_freeList->_prev = header;
		void * newptr = findValidSpot(size);
		return newptr;
	}
	return ptr;
}
void initialize()
{
	// Environment var VERBOSE prints stats at end and turns on debugging
	// Default is on
	_verbose = 1;
	const char * envverbose = getenv( "MALLOCVERBOSE" );
	if ( envverbose && !strcmp( envverbose, "NO") ) {
		_verbose = 0;
	}

	pthread_mutex_init(&mutex, NULL);

	//_mem gives the ADDRESS of the memory chunk given by OS.
	void * _mem = getMemoryFromOS( ArenaSize + (2*sizeof(struct ObjectHeader)) + (2*sizeof(struct ObjectFooter)) );

	// In verbose mode register also printing statistics at exit
	atexit( atExitHandlerInC );

	/*
	the layout of the memory is like:

	sentinel
	---------
	|header	|
	|type	|
	---------

	|
	| linked
	|
	-----------------
					|
					|
	-------------------------------------------------------------------------------------
	|   footer     ||    header   |   usable memoryspace  |   footer   ||      header   |
	|(fencepost1)  ||  	      	  |						  |			   ||  (fencepost2) |
	-------------------------------------------------------------------------------------
	^				^									  ^				^
	|				|									  |		        |
	step1         step3                                 step4          step2

	------------------------>-------->------->------>--------->-------------------------
	                    			address decreases

	i.e  step2 = step1 - sizeof(fencepost1)

	NOTE: memory addresses increase from stack -> text
	stack has lower address,
	text has higher address,
	stack grows towards text: address increases
	heap grows towars stack: address decreases
	*/

	//establish fence posts
	//step1:fencepost1
	struct ObjectFooter * fencepost1 = (ObjectFooter *)_mem;
	fencepost1->_allocated = 1;
	fencepost1->_objectSize = 123456789;//the size doesn't matter


	char * temp = (char *)_mem + (2*sizeof(ObjectFooter)) + sizeof(ObjectHeader) + ArenaSize;

	//step2
	ObjectHeader * fencepost2 = (ObjectHeader *)temp;

	fencepost2->_allocated = 1;
	fencepost2->_objectSize = 123456789;
	fencepost2->_next = NULL;
	fencepost2->_prev = NULL;

	//initialize the list to point to the _mem
	//step3
	temp = (char *) _mem + sizeof(ObjectFooter);
	struct ObjectHeader * currentHeader = (struct ObjectHeader *) temp;

	//step4
	temp = (char *)_mem + sizeof(ObjectFooter) + sizeof(struct ObjectHeader) + ArenaSize;
	ObjectFooter * currentFooter = (struct ObjectFooter *) temp;

	//step5
	//(*header) = &(header)
	_freeList = &_freeListSentinel;

	//step6 initialize the first header node
	currentHeader->_objectSize = ArenaSize + sizeof(ObjectHeader) + sizeof(ObjectFooter); //initially around 2MB
	currentHeader->_allocated = 0;//all as free memory, only 1 chunk
	currentHeader->_next = _freeList;
	currentHeader->_prev = _freeList;
	currentFooter->_allocated = 0;
	currentFooter->_objectSize = currentHeader->_objectSize;

	//step7 handle the sentinel node
	_freeList->_prev = currentHeader;
	_freeList->_next = currentHeader;
	_freeList->_allocated = 2; // sentinel. no coalescing.
	_freeList->_objectSize = 0;

	//step8 get the start point of usable memory as _memStart
	_memStart = (char*) currentHeader;
}
Beispiel #5
0
void * allocateObject( size_t size )
{
	//Make sure that allocator is initialized
	if ( !_initialized ) {
	_initialized = 1;
	initialize();
	}

	// Add the ObjectHeader/Footer to the size and round the total size up to a multiple of
	// 8 bytes for alignment.
	size_t roundedSize = (size + sizeof(struct ObjectHeader) + sizeof(struct ObjectFooter) + 7) & ~7;

	struct ObjectHeader * _tempFirstChunk = _freeList->_next; //pointing to the first header
	
	//Checking if the list is empty. If yes, then allocating a new 2MB chink
	if(_tempFirstChunk == _freeList) {
			void * newMemory = getMemoryFromOS( ArenaSize + (2*sizeof(struct ObjectHeader)) + (2*sizeof(struct ObjectFooter)) );
			struct ObjectFooter * fencepost1 = (struct ObjectFooter *)newMemory;
			fencepost1->_allocated = 1;
			fencepost1->_objectSize = 123456789;
			char * temp = 
			(char *)newMemory + (2*sizeof(struct ObjectFooter)) + sizeof(struct ObjectHeader) + ArenaSize;
		  	struct ObjectHeader * fencepost2 = (struct ObjectHeader *)temp;
		  	fencepost2->_allocated = 1;
		  	fencepost2->_objectSize = 123456789;
		  	fencepost2->_next = NULL;
		  	fencepost2->_prev = NULL;

			temp = (char *) newMemory + sizeof(struct ObjectFooter);
			struct ObjectHeader * nextListHeader = (struct ObjectHeader *) temp;
			temp = (char *) newMemory + sizeof(struct ObjectFooter) + sizeof(struct ObjectHeader) + ArenaSize;
			struct ObjectFooter * nextListFooter = (struct ObjectFooter *) temp;

			nextListHeader->_objectSize = ArenaSize + sizeof(struct ObjectHeader) + sizeof(struct ObjectFooter); //2MB
			nextListHeader->_allocated = 0;

			nextListFooter->_allocated = 0;
			nextListFooter->_objectSize = nextListHeader->_objectSize;
			
			//pointing the free list accordingly in the correct position
			_freeList->_next = nextListHeader;
			nextListHeader->_prev = _freeList;
			nextListHeader->_next = _freeList;
			_freeList->_prev = nextListHeader;
			
			//updating the looping variable
			_tempFirstChunk = nextListHeader;
	
	}
	while(_tempFirstChunk != _freeList) { // looping until the end
		if(_tempFirstChunk->_objectSize - roundedSize > min_size) { // if it qualifies to be split
			size_t block_size = _tempFirstChunk->_objectSize; // size of the block to be split

			void * marker = (void *)_tempFirstChunk; //marker for the block large enough
	
			/* Getting to the split point
			 * Getting the footer in place
			 * Marking the footer and original header to be allocated
			 * Object size change */
			char * temp = (char*)marker + roundedSize - sizeof(struct ObjectFooter); 
			struct ObjectFooter * newFooter = (struct ObjectFooter *)temp; 
			newFooter->_objectSize = roundedSize; 
			_tempFirstChunk->_objectSize = newFooter->_objectSize; 
			_tempFirstChunk->_allocated = 1;
			newFooter->_allocated = 1; 
			/* end */	
	
			/* Getting to the new header placement for the remaining
			 * New header's size and allocation settings */
			temp = (char *)marker + roundedSize; 
			struct ObjectHeader * newHeader = (struct ObjectHeader *) temp; 
			newHeader->_objectSize = (block_size - roundedSize); 
			newHeader->_allocated = 0;
			/* end */

	
			/* Getting to the original footer to change settings
			 * changing object size of this footer */
			temp = (char *)marker + (block_size - sizeof(struct ObjectFooter)); 
			struct ObjectFooter * prev_footer = (struct ObjectFooter *) temp; 
			prev_footer->_objectSize = newHeader->_objectSize; 
			prev_footer->_allocated = 0;
			/* end */

			//deleting the allocated pointer
			newHeader->_prev = _tempFirstChunk->_prev;
			(_tempFirstChunk->_prev)->_next = newHeader;

			newHeader->_next = _tempFirstChunk->_next;
			(_tempFirstChunk->_next)->_prev = newHeader;
			break;
	
		} else if((_tempFirstChunk->_objectSize - (roundedSize)) <= min_size && (_tempFirstChunk->_objectSize - (roundedSize)) >= 0) {
			size_t current_size = _tempFirstChunk->_objectSize;
			
			//deleting the allocated pointer
			(_tempFirstChunk->_prev)->_next = (_tempFirstChunk->_next);
			(_tempFirstChunk->_next)->_prev = (_tempFirstChunk->_prev);
	
			//marking it and updating it to be allocated
			_tempFirstChunk->_allocated = 1;
			void * marker = (void *) _tempFirstChunk;
			char * temp = (char *) marker + current_size - sizeof(struct ObjectFooter);
			struct ObjectFooter * currentFooter = (struct ObjectFooter *)temp;
			currentFooter->_allocated = 1;
			currentFooter->_objectSize = current_size;
			break;  

		} else {
			//if not found large enough
			_tempFirstChunk = _tempFirstChunk->_next;
			
			//if chunk is found large enough in the whole list, allocating a new 2 MB chunk			
			if(_tempFirstChunk == _freeList) {
				void * newMemory = getMemoryFromOS( ArenaSize + (2*sizeof(struct ObjectHeader)) + (2*sizeof(struct ObjectFooter)) );
				struct ObjectFooter * fencepost1 = (struct ObjectFooter *)newMemory;
				fencepost1->_allocated = 1;
				fencepost1->_objectSize = 123456789;
				char * temp = 
				(char *)newMemory + (2*sizeof(struct ObjectFooter)) + sizeof(struct ObjectHeader) + ArenaSize;
			  	struct ObjectHeader * fencepost2 = (struct ObjectHeader *)temp;
			  	fencepost2->_allocated = 1;
			  	fencepost2->_objectSize = 123456789;
			  	fencepost2->_next = NULL;
			  	fencepost2->_prev = NULL;

				temp = (char *) newMemory + sizeof(struct ObjectFooter);
				struct ObjectHeader * nextListHeader = (struct ObjectHeader *) temp;
				temp = (char *) newMemory + sizeof(struct ObjectFooter) + sizeof(struct ObjectHeader) + ArenaSize;
				struct ObjectFooter * nextListFooter = (struct ObjectFooter *) temp;

				nextListHeader->_objectSize = ArenaSize + sizeof(struct ObjectHeader) + sizeof(struct ObjectFooter); //2MB
				nextListHeader->_allocated = 0;

				nextListFooter->_allocated = 0;
				nextListFooter->_objectSize = nextListHeader->_objectSize;
				
				//updating the freelist pointers according to the current and the new list
				(_tempFirstChunk->_prev)->_next = nextListHeader;
				nextListHeader->_prev = (_tempFirstChunk->_prev);
				nextListHeader->_next = _freeList;
				_freeList->_prev = nextListHeader;
				//updating the loop varaible
				_tempFirstChunk = nextListHeader;
	
			}
		}
	}
	pthread_mutex_unlock(&mutex);
	void * ret = (void *) _tempFirstChunk;
	char * temp = (char *) ret + sizeof(struct ObjectHeader);
	ret = (void *) temp;
	// Return a pointer to usable memory
	return (void *) (ret);

}