void Trick::Sie::top_level_objects_print(std::ofstream & sie_out) { Trick::VARIABLE_MAP_ITER vit ; int jj ; for ( vit = trick_MM->variable_map_begin() ; vit != trick_MM->variable_map_end() ; vit++ ) { ALLOC_INFO * alloc_info = (*vit).second ; if ( alloc_info != NULL ) { sie_out << " <top_level_object" ; sie_out << std::endl << " name=\"" << vit->first << "\"" ; sie_out << std::endl << " type=\"" ; std::string type = trickTypeCharString(alloc_info->type, alloc_info->user_type_name ); std::replace(type.begin(), type.end(), ':', '_'); sie_out << type << "\"" << std::endl ; sie_out << " alloc_memory_init=\"" << alloc_info->alloced_in_memory_init << "\""; sie_out << ">" << std::endl ; if ( alloc_info->num_index > 0 ) { for (jj = 0; jj < alloc_info->num_index; jj++) { sie_out << " <dimension>" << alloc_info->index[jj] << "</dimension>" << std::endl ; } } sie_out << " </top_level_object>" << std::endl << std::endl ; } } }
// MEMBER FUNCTION void Trick::ClassicCheckPointAgent::write_decl(std::ostream& chkpnt_os, ALLOC_INFO *info) { const char *type_spec; type_spec = trickTypeCharString(info->type, info->user_type_name); if (info->stcl == TRICK_EXTERN) { chkpnt_os << "// extern "; } if ( info->num_index == 0 ) { chkpnt_os << type_spec << " " << info->name << ";" << std::endl; } else if ((info->num_index > 0) && (info->num_index <= TRICK_MAX_INDEX)) { int ii; chkpnt_os << type_spec; ii = info->num_index-1; while ((ii >= 0) && (info->index[ii] == 0)) { chkpnt_os << "*"; ii --; } chkpnt_os << " " << info->name ; ii = 0; while ((ii < info->num_index) && (info->index[ii] != 0)) { chkpnt_os << "[" << info->index[ii] << "]" ; ii ++; } chkpnt_os << ";" << std::endl; } else { // ERROR - num_index cant be negative. } }
std::string Trick::ClassicCheckPointAgent:: ref_string_from_ptr( void* pointer, ATTRIBUTES* attr, int curr_dim) { std::string reference_string; if ((attr != NULL) && ((curr_dim >= attr->num_index) || (attr->index[curr_dim].size != 0))) { message_publish(MSG_ERROR, "Checkpoint Agent ERROR: ref_string_from_ptr called with a non-pointer type.\n") ; } if (pointer == NULL) { reference_string = "NULL"; } else { ALLOC_INFO *alloc_info; /** Find the allocation that contains the pointer-address. */ alloc_info = mem_mgr->get_alloc_info_of( pointer); if (alloc_info != NULL) { int alloc_elem_size; int alloc_elem_index; int misalignment; alloc_elem_size = alloc_info->size; alloc_elem_index = (int) (((long) pointer - (long) alloc_info->start) / alloc_elem_size); misalignment = (int) (((long) pointer - (long) alloc_info->start) % alloc_elem_size); // If type-checking AND the type specifiers match AND the type we're looking for // is either not structured or if it is, the attr-list that describes the contents // of the structure is the same. if ( (attr != NULL) && (attr->type == alloc_info->type) && ( (attr->type != TRICK_STRUCTURED) || (attr->attr == alloc_info->attr))) { int ii; int n_l_ptrs, n_r_ptrs; // Calculate the number of pointers (asterisks) on the left side of the assignment. n_l_ptrs = attr->num_index - curr_dim; // Calculate the number of pointers (asterisks) on the right side of the assignment. n_r_ptrs = 0; for (ii=0 ; ii <alloc_info->num_index ; ii++) { if (alloc_info->index[ii] == 0) n_r_ptrs++; } if (n_l_ptrs != (n_r_ptrs + 1)) { reference_string = "NULL /*ERROR: # asterisks disagree.*/"; } else { if (misalignment == 0) { std::stringstream workss; if (alloc_info->name != NULL) { workss << "&" << alloc_info->name; if (alloc_info->num_index != 0) { workss << "[" << alloc_elem_index << "]"; } reference_string = workss.str(); } else { std::stringstream ss; ss << "Checkpoint Agent ERROR: The name of the allocation at " << alloc_info->start << " is NULL." << "Therefore, Trick::ClassicCheckPointAgent::ref_string_from_ptr() can't generate a textual reference to it." << std::endl; message_publish(MSG_ERROR, ss.str().c_str() ); reference_string = "ERROR - Allocation name is NULL"; } } else { message_publish(MSG_ERROR, "Checkpoint Agent ERROR: Badly aligned pointer.\n" " It is not aligned with the data object\n" " (of the same type) into which it is pointing.\n") ; reference_string = "ERROR - Badly aligned pointer"; } } } else if (alloc_info->type == TRICK_STRUCTURED) { // The type specifications don't match, but the right-side is structured, // so we apparently the matching type is buried in the right hand side structure. if (alloc_info->name != NULL) { std::string rightside; std::stringstream element_name; element_name << "&" << alloc_info->name; if (alloc_info->num_index != 0) { element_name << '[' << alloc_elem_index << ']'; } rightside = get_var_name( pointer, alloc_info->attr, (char *) alloc_info->start + (alloc_elem_index * alloc_info->size), element_name.str(), &attr ); reference_string = rightside; } else { std::stringstream ss; ss << "Checkpoint Agent ERROR: The name of the allocation at " << alloc_info->start << " is NULL." << "Therefore, Trick::ClassicCheckPointAgent::ref_string_from_ptr() can't generate a textual reference to it." << std::endl; message_publish(MSG_ERROR, ss.str().c_str() ); reference_string = "ERROR - Allocation name is NULL"; } } else { // The type specifications don't match, and the right hand side is not structured if (attr != NULL) { const char* left_type_spec = trickTypeCharString(attr->type, ""); const char* right_type_spec = trickTypeCharString(alloc_info->type, alloc_info->user_type_name); message_publish(MSG_ERROR, "Checkpoint Agent ERROR: Type mismatch. Type specifications disagree.\n" " The left side type specifier is \"%s\" but the right side is \"%s\".\n", left_type_spec, right_type_spec) ; reference_string = "ERROR - Type specifications disagree"; } else { if (misalignment == 0) { std::stringstream workss; if (alloc_info->name != NULL) { workss << "&" << alloc_info->name; if (alloc_info->num_index != 0) { workss << "[" << alloc_elem_index << "]"; } reference_string = workss.str(); } else { std::stringstream ss; ss << "Checkpoint Agent ERROR: The name of the allocation at " << alloc_info->start << " is NULL." << "Therefore, Trick::ClassicCheckPointAgent::ref_string_from_ptr() can't generate a textual reference to it." << std::endl; message_publish(MSG_ERROR, ss.str().c_str() ); reference_string = "ERROR - Allocation name is NULL"; } } else { message_publish(MSG_ERROR, "Checkpoint Agent ERROR: Badly aligned pointer.\n" " It is not aligned with the data object\n" " (of the same type) into which it is pointing.\n") ; reference_string = "ERROR - Badly Aligned Pointer"; } } } } else if ((attr != NULL) && ((curr_dim + 1) == attr->num_index)) { if (attr->type == TRICK_CHARACTER) { std::stringstream ss; write_quoted_str( ss, (const char*)pointer); reference_string = ss.str(); } else if (attr->type == TRICK_WCHAR) { message_publish(MSG_ERROR, "Checkpoint Agent ERROR: TRICK_WCHAR not fully supported yet.\n") ; reference_string = "ERROR: TRICK_WCHAR not fully supported yet."; } else { std::string lname = left_side_name(); message_publish(MSG_ERROR, "Checkpoint Agent ERROR: Pointer <%p> in \"%s\" is not in Trick managed memory\n" "nor is it a character pointer.\n", pointer, lname.c_str()) ; reference_string = "ERROR - Pointer not in Trick managed memory"; } } else { std::string lname = left_side_name(); message_publish(MSG_ERROR, "Checkpoint Agent ERROR: Pointer <%p> in \"%s\" is not in Trick managed memory\n" "nor is it a character pointer.\n", pointer, lname.c_str()) ; reference_string = "ERROR - Pointer not in Trick managed memory"; } } return( reference_string); }
// MEMBER FUNCTION void* Trick::MemoryManager:: declare_extern_var( void* address, TRICK_TYPE type, std::string user_type_name, int n_stars, std::string var_name, int n_cdims, int *cdims) { int ii; int size; char* allocation_name; int n_elems; ATTRIBUTES* sub_attr; ALLOC_INFO *new_alloc; VARIABLE_MAP::iterator variable_pos; /** @par Design Details: This function is implemented using the following algorithm: */ /** @li Validate Parameters. The address can't be NULL.*/ if (address == NULL) { emitError("declare_extern_var() called with NULL address."); return ((void*)NULL); } /** @li Determine whether the given variable name is already in use. */ if (var_name != "") { pthread_mutex_lock(&mm_mutex); variable_pos = variable_map.find( var_name); if (variable_pos != variable_map.end()) { std::stringstream message; message << "Variable \""<< var_name <<"\" already declared."; emitError(message.str()); pthread_mutex_unlock(&mm_mutex); return ((void*)NULL); } pthread_mutex_unlock(&mm_mutex); allocation_name = strdup( var_name.c_str()); } else { allocation_name = NULL; } /** @li Calculate the number of elements in this external variable. This is the product of the sizes of the constrained dimensions. */ n_elems = 1; for (ii = 0; ii < n_cdims ; ii++ ) { n_elems = n_elems * cdims[ii]; } if (n_elems == 0) { std::stringstream message; message << "declare_extern_var() can't register \"" << var_name << "\" because one or more of its constrained dimensions " << "is zero, thus making its total size zero."; emitError(message.str()); return ((void*)NULL); } /** @li From the TRICK_TYPE, user_type_name and the number of pointers (asterisks), determine the size and the attributes of an element. */ if ( get_type_attributes(type, user_type_name, n_stars, sub_attr, size) != 0) { std::stringstream message; message << "get_type_attributes failed for type " << type << " \"" << user_type_name << "\"."; emitError(message.str()); return ((void*)NULL); } /** @li Allocate and populate an ALLOC_INFO record for the external allocation (the thingy pointed to by @b address). */ if ((new_alloc = (ALLOC_INFO*)calloc(1, sizeof(ALLOC_INFO))) != NULL) { new_alloc->start = (void *) address; new_alloc->end = ((char*)new_alloc->start) + (n_elems * size) - 1; new_alloc->name = allocation_name; new_alloc->stcl = TRICK_EXTERN; new_alloc->alloc_type = TRICK_ALLOC_OTHER; new_alloc->size = size; if ( sub_attr != NULL ) { new_alloc->language = sub_attr->language ; } else { new_alloc->language = Language_C ; } new_alloc->type = type; if ((type == TRICK_STRUCTURED) || (type == TRICK_ENUMERATED) || (type == TRICK_OPAQUE_TYPE)) { new_alloc->user_type_name = strdup( user_type_name.c_str()); } else { new_alloc->user_type_name = NULL ; } new_alloc->attr = sub_attr; new_alloc->num = n_elems; new_alloc->num_index = 0; for (ii = 0; ii < n_cdims ; ii++ ) { new_alloc->index[new_alloc->num_index] = cdims[ii]; new_alloc->num_index ++ ; } for (ii = 0 ; ii < n_stars ; ii++) { new_alloc->index[new_alloc->num_index] = 0; new_alloc->num_index ++ ; } new_alloc->id = extern_alloc_info_map_counter++ ; /** @li Insert the <address, ALLOC_INFO> key-value pair into the alloc_info_map.*/ pthread_mutex_lock(&mm_mutex); alloc_info_map[address] = new_alloc; /** @li Insert the <variable-name, ALLOC_INFO> key-value pair into the variable map. */ if (new_alloc->name) { variable_map[new_alloc->name] = new_alloc; } pthread_mutex_unlock(&mm_mutex); } else { emitError("Out of memory.") ; return ((void*)NULL); } if (debug_level) { int i; std::cout << std::endl; std::cout << "Extern declaration: " << new_alloc->num << " element(s) of type(" ; std::cout << trickTypeCharString(type, user_type_name.c_str()) ; for (i=0;i<n_stars;i++) { std::cout << "*"; } std::cout << "), size(" << size << ") @ addr(" << address << ")." ; std::cout << std::endl << std::endl; std::cout.flush(); } /** @li Return the address of the allocation. */ return (address); }