library/src/datastructures/BP-HashTable.cc
// add a key to a registry
add a key to a registry
add a key to a registry
void * BP_HashRegAddMemoryEntry
(
	P_BP_HASH_TABLE_REGISTRY      hreg,
	BP_HASH_REG_MEM_ENTRY_TYPE    entry_type,
	size_t                        initial_data_size,
	BPLN_PARMS
)
{
	BP_GLOBAL_HASH_TABLE_OVERRIDE(NULL);
	if(!initial_data_size)
		return NULL;
	if(!hreg->memory_table)
		hreg->memory_table = (P_BP_HASH_TABLE_MEM) calloc(sizeof(BP_HASH_TABLE_MEM), 1);
	if(!hreg->memory_table)
	{
		if(BP_DEBUG_BREAKPOINT_ON_ALLOC_FAIL)
		{
			asm("int3");
		}
		return NULL;
	}
	P_BP_HASH_TABLE_MEM_PTR_ENTRY new_entry = (P_BP_HASH_TABLE_MEM_PTR_ENTRY) calloc(sizeof(BP_HASH_TABLE_MEM_PTR_ENTRY), 1);
	if(!new_entry)
	{
		if(BP_DEBUG_BREAKPOINT_ON_ALLOC_FAIL)
		{
			asm("int3");
		}
		return NULL;
	}
	new_entry->data_size = initial_data_size;
	do
	{
		new_entry->data = (void *) calloc(initial_data_size, 1);
		if(new_entry->data)
		{
			break;
		}
		if(BP_DEBUG_BREAKPOINT_ON_ALLOC_FAIL)
		{
			printf("\n [!!] calloc failed: (initial_data_size: %u, elem_size: 1", initial_data_size);
			printf("\n");
			asm("int3");
		}
		sleep(3);
	}
	while(1);
	new_entry->key = new_entry->data;
	new_entry->alloc_type = BP_HASH_TABLE_ALLOCATOR_CALLOC;
	new_entry->entry_type = entry_type;
	size_t add_func_len  = 0;
	size_t add_fname_len = 0;
	if(func)
	{
		add_func_len    = bpstrlen(func)+1;
		new_entry->func = strdup(func);
	}
	if(file_name)
	{
		add_fname_len        = bpstrlen(file_name)+1;
		new_entry->file_name = strdup(file_name);
	}
	new_entry->line_number = line_number;
	if(global_mprof_create_backtrace_on_alloc)
	{
		size_t max_depth = 32;
		char *bt_buff[max_depth+1];
		BP_ZERO_STACK(bt_buff);
		int bt_size = backtrace((void **) &bt_buff, max_depth);
		size_t trace_depth_count = BP_CountNullTerminatedPtrArray((char **) &bt_buff);
		char ** bt_syms = backtrace_symbols((void **) &bt_buff, max_depth);
		if(!bt_syms)
		{
			printf("\n [!!] Error: backtrace_symbols() failed, this should never happen.");
			printf("\n");
			__asm("int3");
			return NULL;
		}
		do
		{
			 (direct calloc)
			new_entry->alloc_backtrace_symbols = (char **) calloc(sizeof(char *) * (bt_size+1), 1);
			if(new_entry->alloc_backtrace_symbols)
			{
				break;
			}
			if(BP_DEBUG_BREAKPOINT_ON_ALLOC_FAIL)
			{
				printf("\n [!!] Memory addition failed because backtrace symbols could not be allocated");
				printf("\n");
				asm("int3");
			}
			sleep(3);
		}
		while(1);
		do
		{
			 (direct calloc)
			new_entry->alloc_backtrace = (char **) calloc(sizeof(char *) * (bt_size+1), 1);
			if(new_entry->alloc_backtrace)
			{
				break;
			}
			if(BP_DEBUG_BREAKPOINT_ON_ALLOC_FAIL)
			{
				printf("\n [!!] Memory addition failed because backtrace symbols could not be allocated");
				printf("\n");
				asm("int3");
			}
			s
			sleep(3);
		}
		while(1);
		size_t n = 0;
		for(; n < bt_size; n++)
		{
			new_entry->alloc_backtrace[n]         = strdup(bt_buff[n]);
			new_entry->alloc_backtrace_symbols[n] = strdup(bt_syms[n]);
			new_entry->alloc_backtrace_depth++;
		}
	}
	HASH_ADD_PTR
	(
		hreg->memory_table->entries,
		key,
		new_entry
	);
	hreg->memory_table->managment_structures_total_size += sizeof(BP_HASH_TABLE_MEM_PTR_ENTRY);
	hreg->memory_table->managed_data_size += initial_data_size;
	hreg->memory_table->managed_heap_alloc_total_size += initial_data_size + sizeof(BP_HASH_TABLE_MEM_PTR_ENTRY) + add_func_len + add_fname_len;
	return new_entry->data;
}
void * BP_HashRegAddMemoryEntry ( P_BP_HASH_TABLE_REGISTRY hreg , BP_HASH_REG_MEM_ENTRY_TYPE entry_type , size_t initial_data_size , BPLN_PARMS ) { BP_GLOBAL_HASH_TABLE_OVERRIDE ( NULL ) ; if ( ! initial_data_size ) return NULL ; if ( ! hreg -> memory_table ) hreg -> memory_table = ( P_BP_HASH_TABLE_MEM ) calloc ( sizeof ( BP_HASH_TABLE_MEM ) , 1 ) ; if ( ! hreg -> memory_table ) { if ( BP_DEBUG_BREAKPOINT_ON_ALLOC_FAIL ) { asm ( " " ) ; } return NULL ; } P_BP_HASH_TABLE_MEM_PTR_ENTRY new_entry = ( P_BP_HASH_TABLE_MEM_PTR_ENTRY ) calloc ( sizeof ( BP_HASH_TABLE_MEM_PTR_ENTRY ) , 1 ) ; if ( ! new_entry ) { if ( BP_DEBUG_BREAKPOINT_ON_ALLOC_FAIL ) { asm ( " " ) ; } return NULL ; } new_entry -> data_size = initial_data_size ; do { new_entry -> data = ( void * ) calloc ( initial_data_size , 1 ) ; if ( new_entry -> data ) { break ; } if ( BP_DEBUG_BREAKPOINT_ON_ALLOC_FAIL ) { printf ( " \n " , initial_data_size ) ; printf ( " \n " ) ; asm ( " " ) ; } sleep ( 3 ) ; } while ( 1 ) ; new_entry -> key = new_entry -> data ; new_entry -> alloc_type = BP_HASH_TABLE_ALLOCATOR_CALLOC ; new_entry -> entry_type = entry_type ; size_t add_func_len = 0 ; size_t add_fname_len = 0 ; if ( func ) { add_func_len = bpstrlen ( func ) + 1 ; new_entry -> func = strdup ( func ) ; } if ( file_name ) { add_fname_len = bpstrlen ( file_name ) + 1 ; new_entry -> file_name = strdup ( file_name ) ; } new_entry -> line_number = line_number ; if ( global_mprof_create_backtrace_on_alloc ) { size_t max_depth = 32 ; char * bt_buff [ max_depth + 1 ] ; BP_ZERO_STACK ( bt_buff ) ; int bt_size = backtrace ( ( void * * ) & bt_buff , max_depth ) ; size_t trace_depth_count = BP_CountNullTerminatedPtrArray ( ( char * * ) & bt_buff ) ; char * * bt_syms = backtrace_symbols ( ( void * * ) & bt_buff , max_depth ) ; if ( ! bt_syms ) { printf ( " \n " ) ; printf ( " \n " ) ; __asm ( " " ) ; return NULL ; } do { new_entry -> alloc_backtrace_symbols = ( char * * ) calloc ( sizeof ( char * ) * ( bt_size + 1 ) , 1 ) ; if ( new_entry -> alloc_backtrace_symbols ) { break ; } if ( BP_DEBUG_BREAKPOINT_ON_ALLOC_FAIL ) { printf ( " \n " ) ; printf ( " \n " ) ; asm ( " " ) ; } sleep ( 3 ) ; } while ( 1 ) ; do { new_entry -> alloc_backtrace = ( char * * ) calloc ( sizeof ( char * ) * ( bt_size + 1 ) , 1 ) ; if ( new_entry -> alloc_backtrace ) { break ; } if ( BP_DEBUG_BREAKPOINT_ON_ALLOC_FAIL ) { printf ( " \n " ) ; printf ( " \n " ) ; asm ( " " ) ; } sleep ( 3 ) ; } while ( 1 ) ; size_t n = 0 ; for ( ; n < bt_size ; n ++ ) { new_entry -> alloc_backtrace [ n ] = strdup ( bt_buff [ n ] ) ; new_entry -> alloc_backtrace_symbols [ n ] = strdup ( bt_syms [ n ] ) ; new_entry -> alloc_backtrace_depth ++ ; } } HASH_ADD_PTR ( hreg -> memory_table -> entries , key , new_entry ) ; hreg -> memory_table -> managment_structures_total_size += sizeof ( BP_HASH_TABLE_MEM_PTR_ENTRY ) ; hreg -> memory_table -> managed_data_size += initial_data_size ; hreg -> memory_table -> managed_heap_alloc_total_size += initial_data_size + sizeof ( BP_HASH_TABLE_MEM_PTR_ENTRY ) + add_func_len + add_fname_len ; return new_entry -> data ; }
add a key to a registry
add a key to a registry
// macro to override hreg on null // ensure we have an initial data size // create memory table if we don't already have one // ensure the table was created ok // allocate new entry // set initial data size // allocate space for data (must be in loop) // sleep for a few seconds before retrying alloc // set key and data pointer as the same // default allocator is clear/alloc // set the entry type from user specification // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Set Line/Func/File Tracking %%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // counters for adding func and filename // set function // set filename // set the line number // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Add Backtrace if Globally Configured To Do So %% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // create depth for backtrace // create temporary buffer // gather backtrace (use int, not size_t) // gather trace depth count // gather symbols // allocate space for symbols // allocate space for symbols (direct calloc) // sleep for a few seconds before retrying alloc // allocate space for backtrace // allocate space for symbols (direct calloc) // sleep for a few seconds before retrying allocs // iterator // add all symbols // duplicate the symbol and trace // increment the backtrace depth // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Add Entry %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // add to the memory table // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Adjust Size Counters %%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // increase the managed data size by the size of a new entry // increase managed data size // increase the total alloc data size // return indicating success