Exemple #1
0
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);
}