library/src/garbage_collection/BP_MemoryGarbageCollector.cc
// unlinks an element from the list
unlinks an element from the list
unlinks an element from the list
size_t BP_GarbageCollectorUnlinkHeapChunk(P_BP_GARBAGE_COLLECTOR_DATA gc, P_BP_GARBAGE_COLLECTOR_ALLOC_CHUNK chunk)
{
	if(!gc)
	{
		printf("\n Err. No gc.");
		return ERR_FAILURE;
	}
	if(!chunk)
	{
		printf("\n Err. Got null chunk.");
		return ERR_FAILURE;
	}
	if(!gc->chunks)
	{
		printf("\n Error got null chunks in gc..");
		return ERR_FAILURE;
	}
	P_BP_GARBAGE_COLLECTOR_ALLOC_CHUNK chunks_list = gc->chunks->first;
	if(!chunks_list)
	{
		printf("\n Err. No first pointer.");
		return ERR_FAILURE;
	}
	for(; chunks_list; chunks_list = chunks_list->next)
	{
		if(chunks_list == chunk )
		{
			size_t is_first = 0;
			size_t has_prev = 0;
			size_t has_next = 0;
			size_t is_middle_chunk  = 0;
			size_t is_last_chunk = 0;
			size_t chunk_has_been_freed = 0;
			if( (chunk != chunk->first) && (chunk->next != NULL) && (chunk->prev != NULL) )
				is_middle_chunk = 1;
			if(chunk == BP_GarbageCollectorGetLastChunk(gc))
				is_last_chunk = 1;
			if(chunk == chunk->first)
				is_first = 1;
			if(chunk->next != NULL)
				has_next = 1;
			if(chunk->prev != NULL)
				has_prev = 1;
			if(is_first && has_next)
			{
				chunk = chunk->next;
				if(chunk->prev->chunk_ptr)
					bpfree(chunk->prev->chunk_ptr);
				chunk->prev->chunk_ptr = NULL;
				bpfree(chunk->prev);
				chunk->prev  = NULL;
				chunk->first = chunk;
				gc->chunks   = chunk;
				BP_GarbageCollectorResetAllFirstListPtrs(gc->chunks, chunk);
				gc->chunks   = chunk;
				gc->total_chunks_freed_n++;
				return ERR_SUCCESS;
			}
			if(is_first && !has_next)
			{
				if(chunk->chunk_ptr)
					bpfree(chunk->chunk_ptr);
				chunk->chunk_ptr = NULL;
				if(chunk)
					bpfree(chunk);
				gc->chunks   = NULL;
				gc->total_chunks_freed_n++;
				return ERR_SUCCESS;
			}
			if(is_middle_chunk && !is_first && !is_last_chunk)
			{
				chunk->next->prev = chunk->prev;
				chunk->prev->next = chunk->next;
				bpfree(chunk->chunk_ptr);
				bpfree(chunk);
				gc->total_chunks_freed_n++;
				return ERR_SUCCESS;
			}
			if(is_last_chunk && has_prev)
			{
				chunk->prev->next = NULL;
				bpfree(chunk->chunk_ptr);
				bpfree(chunk);
				gc->total_chunks_freed_n++;
				return ERR_SUCCESS;
			}
			if(is_last_chunk && !has_prev)
			{
				bpfree(chunk->chunk_ptr);
				bpfree(chunk);
				gc->chunks = NULL;
				gc->total_chunks_freed_n++;
				return ERR_SUCCESS;
			}
			printf("\n\n FATAL ERROR: Cant bpfree this (stuck/corrupted)");
			BP_GargbageCollectorPrintChunk(chunk);
			printf("\n\n");
			asm("int3");
		}
	}
	return ERR_FAILURE;
}
size_t BP_GarbageCollectorUnlinkHeapChunk ( P_BP_GARBAGE_COLLECTOR_DATA gc , P_BP_GARBAGE_COLLECTOR_ALLOC_CHUNK chunk ) { if ( ! gc ) { printf ( " \n " ) ; return ERR_FAILURE ; } if ( ! chunk ) { printf ( " \n " ) ; return ERR_FAILURE ; } if ( ! gc -> chunks ) { printf ( " \n " ) ; return ERR_FAILURE ; } P_BP_GARBAGE_COLLECTOR_ALLOC_CHUNK chunks_list = gc -> chunks -> first ; if ( ! chunks_list ) { printf ( " \n " ) ; return ERR_FAILURE ; } for ( ; chunks_list ; chunks_list = chunks_list -> next ) { if ( chunks_list == chunk ) { size_t is_first = 0 ; size_t has_prev = 0 ; size_t has_next = 0 ; size_t is_middle_chunk = 0 ; size_t is_last_chunk = 0 ; size_t chunk_has_been_freed = 0 ; if ( ( chunk != chunk -> first ) && ( chunk -> next != NULL ) && ( chunk -> prev != NULL ) ) is_middle_chunk = 1 ; if ( chunk == BP_GarbageCollectorGetLastChunk ( gc ) ) is_last_chunk = 1 ; if ( chunk == chunk -> first ) is_first = 1 ; if ( chunk -> next != NULL ) has_next = 1 ; if ( chunk -> prev != NULL ) has_prev = 1 ; if ( is_first && has_next ) { chunk = chunk -> next ; if ( chunk -> prev -> chunk_ptr ) bpfree ( chunk -> prev -> chunk_ptr ) ; chunk -> prev -> chunk_ptr = NULL ; bpfree ( chunk -> prev ) ; chunk -> prev = NULL ; chunk -> first = chunk ; gc -> chunks = chunk ; BP_GarbageCollectorResetAllFirstListPtrs ( gc -> chunks , chunk ) ; gc -> chunks = chunk ; gc -> total_chunks_freed_n ++ ; return ERR_SUCCESS ; } if ( is_first && ! has_next ) { if ( chunk -> chunk_ptr ) bpfree ( chunk -> chunk_ptr ) ; chunk -> chunk_ptr = NULL ; if ( chunk ) bpfree ( chunk ) ; gc -> chunks = NULL ; gc -> total_chunks_freed_n ++ ; return ERR_SUCCESS ; } if ( is_middle_chunk && ! is_first && ! is_last_chunk ) { chunk -> next -> prev = chunk -> prev ; chunk -> prev -> next = chunk -> next ; bpfree ( chunk -> chunk_ptr ) ; bpfree ( chunk ) ; gc -> total_chunks_freed_n ++ ; return ERR_SUCCESS ; } if ( is_last_chunk && has_prev ) { chunk -> prev -> next = NULL ; bpfree ( chunk -> chunk_ptr ) ; bpfree ( chunk ) ; gc -> total_chunks_freed_n ++ ; return ERR_SUCCESS ; } if ( is_last_chunk && ! has_prev ) { bpfree ( chunk -> chunk_ptr ) ; bpfree ( chunk ) ; gc -> chunks = NULL ; gc -> total_chunks_freed_n ++ ; return ERR_SUCCESS ; } printf ( " \n \n " ) ; BP_GargbageCollectorPrintChunk ( chunk ) ; printf ( " \n \n " ) ; asm ( " " ) ; } } return ERR_FAILURE ; }
unlinks an element from the list
unlinks an element from the list
// requires a garbage collection structure // set chunks pointer // walk chunks list and verify our chunk exists in the list // if we found the chunk in the list, unlink it // knowledge values for conditional branching // check if its a middle chunk // check if its the last chunk // set flag for first // if its the first element, but has a next pointer, rework the list // printf("\n Unlinking first w/ next"); // destroy data pointer // nullify after destruction // destroy chunk itself // set chunks to new first element // reset all the first list pointers // final reset to first element // chunk has been unlinked // if its the first, and has no next // increament the total number of chunks bpfreed // printf("\n Unlinking first w/o next"); // if the chunk is a middle chunk, handle it here // printf("\n Unlinking middle chunk."); // link up chunk // destroy chunk // return success // if its the last chunk and has a previous // printf("\n Unlinking last chunk w/ previous."); // if it has no previous // printf("\n Unlinking last chunk w/o previous. SINGLE."); // return indicating success