Exemplo n.º 1
0
//Command to create a new action using a model job (or reset an existing action job), num is index starting at 0.
int Trick::IPPythonEvent::action_job(int num, std::string jobname, std::string comment) {
    /** @par Detailed Design: */
    /** @li Find the job for the jobname string and pass it to action() */
    JobData *job = exec_get_job(jobname.c_str(),1);
    /** @li Emit an error if specified jobname does not exist. */
    if (job==NULL) {
        message_publish(MSG_WARNING, "Event action job %s not found. No action was added.\n", jobname.c_str()) ;
    } else {
        if (! job->job_class_name.compare("malfunction")) {
            // enable it if it's a malf job because they are not in any queue
            job->disabled = false;
        }
        action(num, jobname, comment, job, 3 );
    }
    return(0);
}
Exemplo n.º 2
0
/**
@details
-# If the #delimiter is not empty and not a comma then set the file extension to ".txt"
-# Else set the file extension to ".csv"
-# Allocate enough memory to hold #record_size of records in memory
-# Open the log file
   -# Return an error if the open failed.
-# Write out the title line of the log file.  The title line includes the names of
   recorded variables and the units of measurement separated by the #delimiter
-# Declare the recording group to the memory manager so that the group can be checkpointed
   and restored
*/
int Trick::DRAscii::format_specific_init() {

    unsigned int jj ;

    /* Store log information in csv/txt file */
    if ( ! delimiter.empty()  &&  delimiter.compare(",") != 0 ) {
        file_name.append(".txt");
    } else {
        file_name.append(".csv");
    }

    /* Calculate a "worst case" for space used for 1 record. */
    writer_buff = (char *)calloc(1 , record_size * rec_buffer.size()) ;

    /* This loop touches all of the memory locations in the allocation forcing the
       system to actually do the allocation */
    for ( jj= 0 ; jj < record_size * rec_buffer.size() ; jj += 1024 ) {
        writer_buff[jj] = 1 ;
    }
    writer_buff[record_size * rec_buffer.size() - 1] = 1 ;

    out_stream.open(file_name.c_str(), std::fstream::out | std::fstream::app ) ;
    if ( !out_stream || !out_stream.good() ) {
        message_publish(MSG_ERROR, "Can't open Data Record file %s.\n", file_name.c_str()) ;
        record = false ;
        return -1 ;
    }

    // Write out the title line of the recording file
    /* Start with the 1st item in the buffer which should be "sys.exec.out.time" */
    out_stream << rec_buffer[0]->ref->reference ;
    if ( rec_buffer[0]->ref->attr->units != NULL ) {
        out_stream << " {" << rec_buffer[0]->ref->attr->units << "}" ;
    }
    /* Write out specified recorded parameters */
    for (jj = 1; jj < rec_buffer.size() ; jj++) {
        out_stream << delimiter << rec_buffer[jj]->ref->reference ;

        if ( rec_buffer[jj]->ref->attr->units != NULL ) {
            out_stream << " {" << rec_buffer[jj]->ref->attr->units << "}" ;
        }
    }
    out_stream << std::endl ;

    return(0) ;
}
Exemplo n.º 3
0
//Command to create a new condition and set its input string (or reset an existing condition string), num is index starting at 0.
int Trick::IPPythonEvent::condition(int num, std::string str, std::string comment, REF2* ref, JobData* job) {
    /** @par Detailed Design: */

    if (num == condition_count) {
        /** @li Add a new condition when num is sequential, i.e. it is equal to condition_count */
        condition_count++;
        if (condition_count == 1) {
            condition_list =
                (Trick::condition_t **)TMM_declare_var_s("Trick::condition_t*[1]");
        } else {
            condition_list =
                (Trick::condition_t **)TMM_resize_array_1d_a(condition_list, condition_count);
        }
        condition_list[num] =
            (Trick::condition_t *)TMM_declare_var_s("Trick::condition_t");
         
        condition_list[num]->fired_count = 0;
        condition_list[num]->fired_time = -1.0;
    }
    if ((num >=0) && (num < condition_count)) {
        /** @li This is either a new condition or user is changing the condition. */
        /** @li Initialize condition variables - default as enabled. */
        condition_list[num]->ref = ref ;
        condition_list[num]->job = job ;
        condition_list[num]->enabled = true;
        condition_list[num]->hold = false;
        condition_list[num]->fired = false;
        if (ref != NULL) {
            condition_list[num]->cond_type = 1;
        } else if (job != NULL) {
            condition_list[num]->cond_type = 2;
        } else condition_list[num]->cond_type = 0;
        condition_list[num]->str = str;
        // comment is for display in mtv, if not supplied create a comment containing up to 50 characters of cond string
        if (comment.empty()) {
            condition_list[num]->comment = str.substr(0,50);
        } else {
            condition_list[num]->comment = comment;
        }
        // dummy must contain max conditions used in any event so it can replace any event in mtv when deleted
    } else {
        /** @li Emit an error if specified index num is not sequential. */
        message_publish(MSG_WARNING, "Event condition not added: condition number %d is not sequential.\n", num) ;
    }
    return(0);
}
Exemplo n.º 4
0
/** @par Detailed Design: */
Trick::MonteRun *Trick::MonteCarlo::get_next_dispatch() {
    /** <ul><li> While there are remaining runs: */
    while (!runs.empty()) {
        MonteRun *curr_run = runs.front();
        /** <li> If it is in range, return it. </ul>*/
        if (in_range(curr_run)) {
            return curr_run;
        /** <li> Otherwise, run the pre run jobs and dequeue it. */
        } else {
            if (verbosity >= ALL) {
                message_publish(MSG_WARNING, "Monte [Master] Run %d is out of range and has been skipped.\n", curr_run->id) ;
            }
            prepare_run(curr_run);
        }
    }
    return NULL;
}
Exemplo n.º 5
0
/*!
 * @brief Print the ball position.
 *
 * @job_class{ scheduled }
 *
 * @return Always returns 0.
 * @param [in] sim_time   Simulation elapsed time.
 * @param [in] exec_data  Executive control date.
 * @param [in] state      Ball EOM state parameters.
 */
int ball_print(
   double      sim_time,
   BallExec  * exec_data,
   BallState * state      )
{
   if (! exec_data->print_off) {
#ifdef TRICK_VER
      message_publish( 0, "time = %8.2f , position = %12.6f , %12.6f\n",
                       sim_time, state->position[0], state->position[1]);
#else
      printf( "time = %8.2f , position = %12.6f , %12.6f\n",
              sim_time, state->position[0], state->position[1]);
#endif
   }

   return( 0 );
}
Exemplo n.º 6
0
int Trick::SlaveInfo::write_master_chkpnt_name(std::string full_path_name) {
    /** @par Detailed Design: */
    /** @li If the slave is an active synchronization partner (activated == true) */
    if ( activated == true ) {
        /** @li write the checkpoint dir/filename to the slave */
        if (full_path_name.length() > sizeof(chkpnt_name)-1) {
            message_publish(MSG_ERROR, "Master could not send checkpoint name to slave because name too long (max = %d).\n",
                            sizeof(chkpnt_name)) ;
            chkpnt_name[0] = MS_ERROR_NAME; // send error character
        } else {
            strcpy(chkpnt_name, full_path_name.c_str());
        }
        connection->write_name(chkpnt_name, sizeof(chkpnt_name)) ;
    }

    return(0) ;
}
Exemplo n.º 7
0
/**
@details
-# Test if the incoming data record group name has been used.
 -# If true return an error.
-# Set the group buffering type to the incoming type
-# Add the group to the executive.
*/
int Trick::DataRecordDispatcher::add_group(Trick::DataRecordGroup * in_group, Trick::DR_Buffering buffering) {

    unsigned int ii ;
    for (  ii = 0 ; ii < groups.size() ; ii++ ) {
        if ( !groups[ii]->group_name.compare(in_group->group_name) ) {
            message_publish(MSG_ERROR, "Data Record group with duplicate name %s.\n", in_group->group_name.c_str()) ;
            return -1 ;
        }
    }
    if ( buffering != Trick::DR_Not_Specified ) {
        in_group->set_buffer_type(buffering) ;
    }

    exec_add_sim_object(in_group , (char *)in_group->name.c_str()) ;

    return 0 ;
}
Exemplo n.º 8
0
void Trick::MonteCarlo::initialize_slave(Trick::MonteSlave* slave_to_init) {
    std::stringstream ss;
    if (slave_to_init->remote_shell_args.empty()) {
        slave_to_init->remote_shell_args = "";
    }
    std::string buffer;
    /** <li> If this is a custom slave dispatch: add the #custom_pre_text. */
    if (custom_slave_dispatch) {
        buffer = custom_pre_text;
    /** <li> Otherwise add the default pre text.     */
    } else {
        default_slave_dispatch_pre_text(slave_to_init, buffer) ;
    }

    if (!slave_to_init->S_main_name.compare("")) {
        slave_to_init->S_main_name = "./S_main_${TRICK_HOST_CPU}.exe";
    }

    /** <li> Append the S_main executable and slave-specific arguments. */
    ss << slave_to_init->S_main_name
       << " " << command_line_args_get_input_file()
       << " --monte_host " << machine_name
       << " --monte_sync_port " << listen_device.port
       << " --monte_data_port " << data_listen_device.port
       << " --monte_client_id " << slave_to_init->id
       << " -O " << run_directory;
    buffer += ss.str();

    /** <li> if this is a custom slave dispatch, append the #custom_post_text. */
    if (custom_slave_dispatch) {
        buffer += custom_post_text;
    } else {
        buffer += std::string("' &");
    }

    if (verbosity >= INFORMATIONAL) {
        message_publish(MSG_INFO, "Monte: Spawning Slave %s:%d :\n%s\n",
                        slave_to_init->machine_name.c_str(), slave_to_init->id, buffer.c_str()) ;
    }
    /** <li> Set the slave's state to INITIALIZING. */
    slave_to_init->state = MonteSlave::INITIALIZING;
    /** <li> Make the system call to execute the shell. */
    system(buffer.c_str());
}
Exemplo n.º 9
0
//Command to create a new action and set its input string (or reset an existing action string), num is index starting at 0.
int Trick::IPPythonEvent::action(int num, std::string str, std::string comment, JobData *job, int act_type) {
    /** @par Detailed Design: */

    if (num == action_count) {
        /** @li Add a new action when num is sequential, i.e. it is equal to action_count */
        action_count++;
        if (action_count == 1) {
            action_list = (Trick::action_t **)TMM_declare_var_s("Trick::action_t*[1]");
        } else {
            action_list = (Trick::action_t **)TMM_resize_array_1d_a(action_list, action_count);
        }
        action_list[num] =
            (Trick::action_t *)TMM_declare_var_s("Trick::action_t");

        action_list[num]->ran_count = 0;
        action_list[num]->ran_time = -1.0;
    }
    if ((num >=0) && (num < action_count)) {
        /** @li This is either a new action or user is changing the action. */
        /** @li Initialize action variables - default as enabled. */
        action_list[num]->job = job ;
        action_list[num]->act_type = act_type ;
        action_list[num]->enabled = true;
        action_list[num]->ran = false;
        action_list[num]->str = str;
        // comment is for display in mtv, if not supplied create a comment containing up to 50 characters of act string
        if (comment.empty()) {
            action_list[num]->comment = str.substr(0,50);
        } else {
            action_list[num]->comment = comment;
        }
        // dummy must contain max actions used in any event so it can replace any event in mtv when deleted
#if 0
        if (num == ip->dummy_event.action_count) {
            ip->dummy_event.action(num, "XXX_DELETED_ACT");
        }
#endif
    } else {
        /** @li Emit an error if specified index num is not sequential. */
        message_publish(MSG_WARNING, "Event action not added: action number %d is not sequential.\n", num) ;
    }
    return(0);
}
Exemplo n.º 10
0
int Trick::DataRecordGroup::write_header() {

    unsigned int jj ;
    std::string header_name ;
    std::fstream out_stream ;

    /*! create the header file used by the GUIs */
    header_name = output_dir + "/log_" + group_name + ".header" ;

    out_stream.open(header_name.c_str(), std::fstream::out ) ;
    if ( ! out_stream  ||  ! out_stream.good() ) {
#ifndef _DMTCP
        message_publish(MSG_ERROR, "Can't open Data Record file %s.\n", header_name.c_str()) ;
#endif
        return -1;
    }

    /* Header file first line is created in format specific header */
    out_stream << "log_" << group_name ;

    format_specific_header(out_stream) ;

    /* Output the file name, variable size, units, and variable name
     * to the rest of recorded data header file.
     * (e.g. file_name  C_type  units  sim_name)
     * Note: "sys.exec.out.time" should be the first variable in the buffer.
     */
    for (jj = 0; jj < rec_buffer.size() ; jj++) {
        /*! recording single data item */
        out_stream << "log_" << group_name << "\t"
            << type_string(rec_buffer[jj]->ref->attr->type,
                           rec_buffer[jj]->ref->attr->size) << "\t"
            << std::setw(6)<<rec_buffer[jj]->ref->attr->units << "\t"
            << rec_buffer[jj]->ref->reference << std::endl ;
    }

    // Send all unwritten characters in the buffer to its output/file.
    out_stream.flush() ;
    out_stream.close() ;

    return(0) ;

}
Exemplo n.º 11
0
int Trick::Executive::freeze(double in_time) {

    long long new_time ;
    new_time = (long long)(in_time * time_tic_value) ;

    if (new_time > time_tics ) {
        freeze_times.push(new_time) ;
        if ( new_time < freeze_job->next_tics ) {
            freeze_job->next_tics = new_time ;
        }
        //std::cout << "\033[33mSET FREEZE TIME " << in_time << " " << new_time << "\033[0m" << std::endl ;
    } else {
        message_publish(MSG_ERROR, "Freeze time specified in the past. specified %f, current_time %f\n",
         in_time , get_sim_time()) ;
    }

    return(0) ;

}
Exemplo n.º 12
0
/** @par Detailed Design: */
void Trick::MonteCarlo::resolve_run(MonteSlave& slave, MonteRun::ExitStatus exit_status) {
    if (exit_status != MonteRun::COMPLETE) {
        failed_runs.push_back(slave.current_run);
    }

    /** <li> Update the bookkeeping. */
    struct timeval time_val;
    gettimeofday(&time_val, NULL);
    slave.current_run->end_time = time_val.tv_sec + (double)time_val.tv_usec / 1000000;
    slave.current_run->exit_status = exit_status;

    ++slave.num_results;
    slave.cpu_time += slave.current_run->end_time - slave.current_run->start_time;

    ++num_results;

    if (verbosity >= ALL) {
        message_publish(MSG_INFO, "Monte [Master] Run %d has been resolved as: %d.\n",slave.current_run->id, exit_status) ;
    }
}
Exemplo n.º 13
0
int Trick::Master::checkpoint() {
    /** @par Detailed Design: */
    /** @li If chkpnt_dump_auto, tell slave to dump a checkpoint */
    unsigned int ii ;
    // do not tell slave to dump if this is a pre_init, post_init, or end checkpoint
    // those are handled with flags sent to slave in init()
    if ((exec_get_mode() == Initialization) || (exec_get_mode() == ExitMode)) {
        return(0);
    }
    if (enabled) {
        // Use 2 loops to read all slave status before writing any status out.
        for ( ii = 0 ; ii < slaves.size() ; ii++ ) {
            slaves[ii]->read_slave_status() ;
        }
        SIM_COMMAND save_command = exec_get_exec_command() ;
        std::string full_path_name = checkpoint_get_output_file();
        for ( ii = 0 ; ii < slaves.size() ; ii++ ) {
            if (slaves[ii]->chkpnt_dump_auto) {
                if (slaves[ii]->chkpnt_binary) {
                    if (slaves[ii]->slave_type == "dmtcp") {
                        exec_set_exec_command((SIM_COMMAND)MS_ChkpntDumpBinCmd) ;
                        slaves[ii]->write_master_status() ;
                        slaves[ii]->write_master_chkpnt_name(full_path_name) ;
                        exec_set_exec_command(save_command) ;
                    } else {
                        message_publish(MSG_ERROR, "Slave is not running under dmtcp control so it cannot dump binary checkpoint.\n") ;
                        slaves[ii]->write_master_status() ;
                    }
                } else { // ascii
                    exec_set_exec_command((SIM_COMMAND)MS_ChkpntDumpAsciiCmd) ;
                    slaves[ii]->write_master_status() ;
                    slaves[ii]->write_master_chkpnt_name(full_path_name) ;
                    exec_set_exec_command(save_command) ;
                }
            } else { // no auto dump
                slaves[ii]->write_master_status() ;
            }
        }
    }
    return(0) ;
}
Exemplo n.º 14
0
int Trick::DataRecordGroup::add_change_variable( std::string in_name ) {

    REF2 * ref2 ;

    ref2 = ref_attributes((char *)in_name.c_str()) ;

    if ( ref2 == NULL || ref2->attr == NULL ) {
        message_publish(MSG_WARNING, "Could not find Data Record change variable %s.\n", in_name.c_str()) ;
        return(-1) ;
    }

    Trick::DataRecordBuffer * new_var = new Trick::DataRecordBuffer ;
    new_var->ref = ref2 ;
    new_var->buffer = (char *)malloc(ref2->attr->size) ;
    new_var->last_value =  NULL ;
    memcpy(new_var->buffer , ref2->address , ref2->attr->size) ;
    change_buffer.push_back(new_var) ;

    return(0) ;

}
// MEMBER FUNCTION
void* Trick::MemoryManager::
      declare_extern_var(void*       address,
                          const char* alloc_definition) {

    void* res_address = NULL;

    ADefParseContext* context = NULL;
    std::stringstream alloc_decl_sstream;

    /** @par Design Details:
     This function is implemented using the following algorithm:
     */

    alloc_decl_sstream << alloc_definition;

    /** @li Create a parse context. */
    context = new ADefParseContext( &alloc_decl_sstream);

    /** @li Call ADEF_parse to parse the declaration. */
    if (context != NULL) {
        if ( ADEF_parse( context) == 0) {

            /** @li Call the general form of declare_extern_var. */
            res_address = declare_extern_var( address,
                                               context->type,
                                               context->user_type_name,
                                               context->n_stars,
                                               context->var_name,
                                               context->n_cdims,
                                               context->cdims);

            /** @li Delete the parse context. */
            delete( context);
        } else {
            message_publish(MSG_ERROR, "Memory Manager: Invalid declaration \"%s\".\n", alloc_definition) ;
        }
    }
    /** @li Return the address. */
    return ( res_address);
}
Exemplo n.º 16
0
/*
@details
-# If the user specified an address and port
 -# disconnect the current listen port
 -# initialize listen port to new address and port
-# else print message of current port number of listen device
*/
int Trick::JSONVariableServer::restart() {

    int ret ;

    if ( user_port_requested ) {
        printf("user_port_requested set %d", port) ;
        tc_disconnect(&listen_dev) ;
        ret = tc_init_with_connection_info(&listen_dev, AF_INET, SOCK_STREAM, source_address.c_str(), port) ;
        if (ret != TC_SUCCESS) {
            message_publish(MSG_ERROR, "ERROR: Could not establish listen port %d for Variable Server. Aborting.\n", port);
            return (-1);
        }
    } else {
        struct sockaddr_in s_in;
        int s_in_size =  sizeof(s_in) ;
        getsockname( listen_dev.socket , (struct sockaddr *)&s_in, (socklen_t *)&s_in_size) ;
        printf("restart JSON variable server message port = %d\n" , ntohs(s_in.sin_port)) ;
        port = listen_dev.port = ntohs(s_in.sin_port);
    }

    return 0 ;
}
Exemplo n.º 17
0
std::string Trick::ClassicCheckPointAgent::get_var_name( void* addr,
                                                         ATTRIBUTES* A,
                                                         void* struct_addr,
                                                         std::string name,
                                                         ATTRIBUTES** left_type) {
    char *ret;
    std::string var_name;

    var_name = name;
    ret = getCompositeSubReference( addr, left_type, struct_addr, A);

    if (ret != NULL) {
        var_name += ret;
        free(ret);
    } else {
          std::stringstream ss;
          ss << "Checkpoint Agent ERROR: Unable to create a subreference of variable \"" << name << "\"."
             << std::endl;
          message_publish(MSG_ERROR, ss.str().c_str() );
    }
    return (var_name);
}
Exemplo n.º 18
0
int STLCheckpoint::speak() {
    //message_publish(1,"Quack!\n") ;
    //message_publish(1,"double_vector: %f %f %f\n", double_vector[0], double_vector[1], double_vector[2]) ;
    //message_publish(1,"vector_vector_double[1]: %f %f %f\n",
    // vector_vector_double[1][0], vector_vector_double[1][1], vector_vector_double[1][2]) ;
    //message_publish(1,"vector_vector_vector_double[4][2]: %f %f %f\n",
    // vector_vector_vector_double[4][2][0], vector_vector_vector_double[4][2][1], vector_vector_vector_double[4][2][2]) ;
    //message_publish(1,"string_vector[0]: %s\n", string_vector[0].c_str()) ;
    //message_publish(1,"map_int_vector_int[1][1] = %d\n", map_int_vector_int[1][1]) ;
    //message_publish(1,"gcd = %d\n", gcd[std::pair<int, int >(24,30)]) ;
    //message_publish(1,"common_multiples = %d\n", common_multiples[std::pair<int, int >(3,5)][1]) ;
    //message_publish(1,"common_multiples = %d\n", common_multiples[std::pair<int, int >(3,5)][1]) ;
    //message_publish(1,"int_pair_int_int.second.second = %d\n", int_pair_int_int.second.second) ;
    //message_publish(1,"pair_int_int_int.first.second = %d\n", pair_int_int_int.first.second) ;
    //message_publish(1,"pair_pair_pair.second.first = %d\n", pair_pair_pair.second.first) ;
    //message_publish(1,"int_queue.front = %d\n", int_queue.front()) ;
    //message_publish(1,"int_priority_queue.top = %d\n", int_priority_queue.top()) ;
    //message_publish(1,"uint_stack.top = %d\n", uint_stack.top()) ;
    //message_publish(1,"queue_vector_int.front()[3] = %d\n", queue_vector_int.front()[3]) ;
    //message_publish(1,"priority_queue_vector_int.top()[2] = %d\n", priority_queue_vector_int.top()[2]) ;
    message_publish(1,"stack_vector_int.top()[1] = %d\n", stack_vector_int.top()[1]) ;
    return 0 ;
}
Exemplo n.º 19
0
int Trick::Master::preload_checkpoint() {
    /** @par Detailed Design: */
    /** @li If chkpnt_load_auto, tell slave to load a checkpoint */
    unsigned int ii ;
    if (enabled) {
        // Use 2 loops to read all slave status before writing any status out.
        for ( ii = 0 ; ii < slaves.size() ; ii++ ) {
            slaves[ii]->read_slave_status() ;
        }
        SIM_COMMAND save_command = exec_get_exec_command() ;
        std::string full_path_name = checkpoint_get_load_file();
        for ( ii = 0 ; ii < slaves.size() ; ii++ ) {
            if (slaves[ii]->chkpnt_load_auto) {
                if (slaves[ii]->chkpnt_binary) {
                    if (slaves[ii]->slave_type == "dmtcp") {
                        exec_set_exec_command((SIM_COMMAND)MS_ChkpntLoadBinCmd) ;
                        slaves[ii]->write_master_status() ;
                        slaves[ii]->write_master_chkpnt_name(full_path_name) ;
                        exec_set_exec_command(save_command) ;
                    } else {
                        message_publish(MSG_ERROR, "Slave is not running under dmtcp control so it cannot load binary checkpoint.\n") ;
                        slaves[ii]->write_master_status() ;
                    }
                } else { // ascii
                    exec_set_exec_command((SIM_COMMAND)MS_ChkpntLoadAsciiCmd) ;
                    slaves[ii]->write_master_status() ;
                    slaves[ii]->write_master_chkpnt_name(full_path_name) ;
                    exec_set_exec_command(save_command) ;
                }
            } else { // no auto load
                slaves[ii]->write_master_status() ;
            }
        }
    }
    return(0) ;
}
Exemplo n.º 20
0
int Trick::VariableServerThread::var_units(std::string var_name, std::string units_name) {

    unsigned int ii ;

    for ( ii = 0 ; ii < vars.size() ; ii++ ) {
        if ( ! std::string(vars[ii]->ref->reference).compare(var_name) ) {
            if (!units_name.compare("xx")) {
                vars[ii]->ref->units = strdup(vars[ii]->ref->attr->units);
            }
            else {
                Unit orig_units(vars[ii]->ref->attr->units) ;
                try {
                    vars[ii]->conversion_factor = orig_units.Conversion_to(units_name.c_str()) ;
                    vars[ii]->ref->units = strdup(units_name.c_str());
                }
                catch (Unit::CONVERSION_ERROR & ce_err ) {
                    message_publish(MSG_ERROR, "Variable Server Error: var_units Units conversion error for \"%s\".\n",var_name.c_str());
                    return(-1) ;
                }
            }
        }
    }
    return(0) ;
}
Exemplo n.º 21
0
//Top of frame job to add new events to processing set.
void Trick::EventProcessor::add_pending_events( long long curr_tics , bool is_restart ) {
    std::vector< Trick::Event * >::iterator it ;
    for ( it = pending_events.begin() ; it != pending_events.end() ; ) {
        if ( (*it)->get_cycle_tics() != 0 ) {
            // this is a cyclic event
            // If we are not calling this routine during a restart
            if ( ! is_restart ) {
                // Set the next time to the current time
                (*it)->set_next_tics( curr_tics ) ;
            }
        } else {
            // this is a one time event, test to see if the event time has past.
            if ( (*it)->get_next_tics() < curr_tics ) {
                // if the time has past, print warning and move to the next event.
                message_publish(MSG_WARNING, "One time event fire time has already past.\n") ;
                it = pending_events.erase(it) ;
                continue ;
            }
        }
        event_set.insert(*it) ;
        process_event_job->next_tics = (*(event_set.begin()))->get_next_tics() ;
        it = pending_events.erase(it) ;
    }
}
Exemplo n.º 22
0
int Trick::Integrator::integrate_1st_order_ode (
    double const* derivs_in, double* state_in_out) {
    int rc;

    if (is_2nd_order_ODE_technique) {
        message_publish(MSG_ERROR,
                        "Integrator ERROR: "
                        "Current integrator is a 2nd order technique.\n");
        return 0;
    }

    for (int ii = 0; ii < num_state; ++ii) {
        state[ii] = state_in_out[ii];
        deriv[intermediate_step][ii] = derivs_in[ii];
    }

    rc = integrate ();

    for (int ii = 0; ii < num_state; ++ii) {
        state_in_out[ii] = state_ws[intermediate_step][ii];
    }

    return rc;
}
Exemplo n.º 23
0
//Shutdown job that writes the job timeline data to disk and closes log files.
int Trick::FrameLog::shutdown() {

    /** @par Detailed Design: */

    int thread, ii, jj;
    char log_buff[128];
    Trick::timeline_t *tl;
    double start, stop, time_scale;

    if ( frame_log_flag == false ) {
        return(0) ;
    }

    /** @li Manually create the log_timeline and log_timeline_init files from saved timeline data. */
    if (fp_time_main == NULL) {
        sprintf(log_buff, "%s/log_timeline.csv", command_line_args_get_output_dir());
        if ((fp_time_main = fopen(log_buff, "w")) == NULL) {
            message_publish(MSG_ERROR, "Could not open log_timeline.csv file for Job Timeline Logging\n") ;
            exit(0);
        }
        fprintf(fp_time_main, "trick_frame_log.frame_log.job_time {s},");
        fprintf(fp_time_main, "trick_frame_log.frame_log.job_trick_id {--},frame_log.frame_log.job_user_id {--}");
        for (jj=1; jj<num_threads; jj++) {
            fprintf(fp_time_main, ",trick_frame_log.frame_log.job_userC%d_id {--}",jj);
        }
        fprintf(fp_time_main, "\n");

        sprintf(log_buff, "%s/log_timeline_init.csv", command_line_args_get_output_dir());
        if ((fp_time_other = fopen(log_buff, "w")) == NULL) {
            message_publish(MSG_ERROR, "Could not open log_timeline_init.csv file for Job Timeline Logging\n") ;
            exit(0);
        }
        fprintf(fp_time_other, "trick_frame_log.frame_log.job_init_time {s},");
        fprintf(fp_time_other, "trick_frame_log.frame_log.job_trickinit_id {--},trick_frame_log.frame_log.job_userinit_id {--}\n");
    }

    time_scale = 1.0 / exec_get_time_tic_value();
            // print to log like this:
            // (only one of the job ids will be filled in depending on what type of job this is)
            //               start job time, 0, 0
            //               start job time, trick job id, user job id
            //               stop  job time, trick job id, user job id
            //               stop  job time, 0, 0
    /** @li print a 0 id before each start time & after each stop time for a stairstep effect in plot. */
    // cyclic jobs
    for ( thread = 0 ; thread < num_threads ; thread++ ) {
        tl = timeline[thread];
        for ( ii = 0 ; ii < tl_count[thread] ; ii++ ) {
            // start & stop time are in tics, so convert to seconds
            start = tl[ii].start * time_scale;
            stop =  tl[ii].stop  * time_scale;
            fprintf(fp_time_main,      "%f,0", start);        // start stairstep
            for (jj=0; jj<num_threads; jj++) {
                fprintf(fp_time_main,  ",0");
            }
            fprintf(fp_time_main,      "\n");
            if (tl[ii].trick_job) {
                fprintf(fp_time_main, "%f,%f", start, tl[ii].id);    // trick job start
                for (jj=0; jj<num_threads; jj++) {
                    fprintf(fp_time_main, ",0");
                }
            } else { // user job
                fprintf(fp_time_main, "%f,0", start);         // user job start
                for (jj=0; jj<num_threads; jj++) {
                    if (jj==thread) {
                        fprintf(fp_time_main, ",%f", tl[ii].id);     // user thread id (0=main)
                    } else {
                        fprintf(fp_time_main, ",0");
                    }
                }
            }
            fprintf(fp_time_main,      "\n");
            if (tl[ii].trick_job) {
                fprintf(fp_time_main, "%f,%f", stop, tl[ii].id);    // trick job end
                for (jj=0; jj<num_threads; jj++) {
                    fprintf(fp_time_main, ",0");
                }
            } else { // user job
                fprintf(fp_time_main, "%f,0", stop);         // user job end
                for (jj=0; jj<num_threads; jj++) {
                    if (jj==thread) {
                        fprintf(fp_time_main, ",%f", tl[ii].id);    // user thread id (0=main)
                    } else {
                        fprintf(fp_time_main, ",0");
                    }
                }
            }
            fprintf(fp_time_main,      "\n");
            fprintf(fp_time_main,      "%f,0", stop);        // end stairstep
            for (jj=0; jj<num_threads; jj++) {
                fprintf(fp_time_main,  ",0");
            }
            fprintf(fp_time_main,      "\n");
        } // end for thread
    } // end for ii

    // non-cyclic jobs
    for ( thread = 0 ; thread < num_threads ; thread++ ) {
        tl = timeline_other[thread];
        for ( ii = 0 ; ii < tl_other_count[thread] ; ii++ ) {
            // start & stop time are in tics, so convert to seconds
            start = tl[ii].start * time_scale;
            stop =  tl[ii].stop  * time_scale;
            fprintf(fp_time_other, "%f,0,0\n", start);          // start stairstep
            if (tl[ii].trick_job) {
                fprintf(fp_time_other, "%f,%f,0\n", start, tl[ii].id); // trick job start
                fprintf(fp_time_other, "%f,%f,0\n", stop, tl[ii].id);  // trick job end
            } else { // user job
                fprintf(fp_time_other, "%f,0,%f\n", start, tl[ii].id); // user job start
                fprintf(fp_time_other, "%f,0,%f\n", stop, tl[ii].id);  // user job end
            }
            fprintf(fp_time_other, "%f,0,0\n", stop);           // end stairstep
        } // end for thread
    } // end for ii

    fclose(fp_time_main);
    fclose(fp_time_other);

    return(0) ;

}
int Trick::VariableServerThread::write_binary_data( int Start, char *buf1, int PacketNum ) {
    int i;
    int ret ;
    int HeaderSize, MessageSize;
    int NumVariablesProcessed;
    unsigned int msg_type , offset, len ;
    unsigned int size ;
    unsigned int swap_int ;
    char * address = 0 ;
    char* param_name;

    //remove warning for unused PacketNum... to be deleted.
    (void)PacketNum ;

    /* start the offset 4 bytes into the message, we'll subtract the sizeof offset at the end */
    offset = sizeof(msg_type) + sizeof(offset) ;

    /* if we are here the msg_type is good, so send a 0, swapped or not 0 is still 0 */
    msg_type = VS_VAR_LIST ;
    memcpy(buf1, &msg_type , sizeof(msg_type)) ;
    HeaderSize = sizeof(msg_type);

    offset += sizeof(unsigned int) ;
    HeaderSize += sizeof(unsigned int);

    for (i = Start; i < (int)vars.size() ; i++) {

        // data to send was copied to buffer in copy_sim_data
        address = (char *)vars[i]->buffer_out;
        size = vars[i]->size ;

        param_name = vars[i]->ref->reference;
        len = strlen(param_name)  ;
        // when var_binary_nonames, do not put the variable names into the message to be sent
        if (binary_data_nonames) {
            MessageSize = sizeof(int) + sizeof(size) + size ;
        } else {
            MessageSize = sizeof(len) + len + sizeof(int) + sizeof(size) + size ;
        }

        /* make sure this message will fit in a packet by itself */
        if ( (HeaderSize + MessageSize) > MAX_MSG_LEN ) {
            message_publish(MSG_WARNING, "%p Variable Server buffer[%d] too small (need %d) for symbol %s, SKIPPING IT.\n",
                            &connection, MAX_MSG_LEN,
                            (int)(HeaderSize + MessageSize),
                            vars[i]->ref->reference );
            continue;
        }

        if ( (offset + MessageSize) < MAX_MSG_LEN ) {
            if (byteswap) {
                if (!binary_data_nonames) {
                    swap_int = trick_byteswap_int((int)len) ;
                    memcpy(&buf1[offset] , &swap_int , sizeof(len)) ;
                    offset += sizeof(len) ;

                    memcpy(&buf1[offset] , param_name , (size_t)len) ;
                    offset += len ;
                }

                swap_int = trick_byteswap_int(vars[i]->ref->attr->type) ;
                memcpy(&buf1[offset] , &swap_int , sizeof(int)) ;
                offset += sizeof(int) ;

                swap_int = trick_byteswap_int((int)size) ;
                memcpy(&buf1[offset] , &swap_int , sizeof(size)) ;
                offset += sizeof(size) ;

                /* TODO: There is a bug here, this call will want to swap the entire buffer, we may not have the whole buffer */
                trick_bswap_buffer(&buf1[offset], address, vars[i]->ref->attr, 1);
                offset += size ;
            }
            else {
                int temp_i ;
                unsigned int temp_ui ;

                if (!binary_data_nonames) {
                    memcpy(&buf1[offset] , &len , sizeof(len)) ;
                    offset += sizeof(len) ;

                    memcpy(&buf1[offset] , param_name , (size_t)len) ;
                    offset += len ;
                }

                memcpy(&buf1[offset] , &vars[i]->ref->attr->type , sizeof(int)) ;
                offset += sizeof(int) ;

                memcpy(&buf1[offset] , &size , sizeof(size)) ;
                offset += sizeof(size) ;

                switch ( vars[i]->ref->attr->type ) {
                    case TRICK_BITFIELD:
                        temp_i = GET_BITFIELD(address , vars[i]->ref->attr->size ,
                          vars[i]->ref->attr->index[0].start, vars[i]->ref->attr->index[0].size) ;
                        memcpy(&buf1[offset] , &temp_i , (size_t)size) ;
                    break ;
                    case TRICK_UNSIGNED_BITFIELD:
                        temp_ui = GET_UNSIGNED_BITFIELD(address , vars[i]->ref->attr->size ,
                                vars[i]->ref->attr->index[0].start, vars[i]->ref->attr->index[0].size) ;
                        memcpy(&buf1[offset] , &temp_ui , (size_t)size) ;
                    break ;
                    case TRICK_NUMBER_OF_TYPES:
                        // TRICK_NUMBER_OF_TYPES is an error case
                        temp_i = 0 ;
                        memcpy(&buf1[offset] , &temp_i , (size_t)size) ;
                    break ; 
                    default:
                        memcpy(&buf1[offset] , address , (size_t)size) ;
                    break ;
                }
                offset += size ;
            }
        }
        else {
            /* indicate that we're over the maximum size */
            if (debug >= 2) {
                message_publish(MSG_DEBUG, "%p tag=<%s> var_server buffer[%d] too small (need %d), sending multiple binary packets.\n",
                        &connection, connection.client_tag, MAX_MSG_LEN,
                        (int)(offset + MessageSize) );
            }
            break ;
        }
    }

    /* adjust the header with the correct information reflecting what has been accomplished */
    NumVariablesProcessed = i - Start;

    offset -= sizeof(offset) ;
    if (byteswap) {
        swap_int = trick_byteswap_int((int)offset) ;
        memcpy(buf1 + sizeof(msg_type) , &swap_int , sizeof(offset)) ;

        swap_int = trick_byteswap_int( NumVariablesProcessed ) ;
        memcpy( buf1 + sizeof(msg_type) + sizeof(offset), &swap_int , sizeof(swap_int)) ;
    }
    else {
        memcpy(buf1 + sizeof(msg_type) , &offset , sizeof(offset)) ;
        memcpy( buf1 + sizeof(msg_type) + sizeof(offset), &NumVariablesProcessed , sizeof( NumVariablesProcessed )) ;
    }

    if (debug >= 2) {
        message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %u binary bytes containing %d variables.\n", &connection,
                connection.client_tag, (unsigned int)(offset + sizeof(offset)), NumVariablesProcessed);
    }

    len = offset + sizeof(msg_type) ;
    ret = tc_write(&connection, (char *) buf1, len);
    if ( ret != (int)len ) {
        return(-1) ;
    }

    /* return the index to the next symbol to send or V->num_vars if all done */
    return i;
}
int Trick::VariableServerThread::write_data() {

    int ret;
    unsigned int i ;
    char buf1[ MAX_MSG_LEN ];
    int len ;

    // do not send anything when there are no variables!
    if ( vars.size() == 0 or packets_copied == 0 ) {
        return(0);
    }

    /* Acquire sole access to vars[ii]->buffer_in. */
    if ( var_data_staged and pthread_mutex_trylock(&copy_mutex) == 0 ) {
        unsigned int ii;
        void * temp_p;
        // Swap buffer_in and buffer_out for each vars[ii].
        for ( ii = 0 ; ii < vars.size() ; ii++ ) {
                          temp_p = vars[ii]->buffer_in;
            vars[ii]->buffer_in  = vars[ii]->buffer_out;
            vars[ii]->buffer_out = temp_p;
        }
        var_data_staged = false;

        /* Relinquish sole access to vars[ii]->buffer_in. */
        pthread_mutex_unlock(&copy_mutex) ;

        if (binary_data) {
            int Index = 0;
            int PacketNumber = 0;

            do {
                ret = write_binary_data( Index, buf1, PacketNumber );
                if ( ret >= 0 ) {
                    Index = ret ;
                } else {
                    return(-1) ;
                }
                PacketNumber++;
            } while( Index < (int)vars.size() );

        } else { /* ascii mode */
            char val[MAX_MSG_LEN];

            sprintf(buf1, "0\t") ;

            for (i = 0; i < vars.size(); i++) {

                ret = vs_format_ascii( vars[i] , val);

                if (ret < 0) {
                    message_publish(MSG_WARNING, "%p Variable Server string buffer[%d] too small for symbol %s, TRUNCATED IT.\n",
                                    &connection, MAX_MSG_LEN, vars[i]->ref->reference );
                }

                /* make sure this message will fit in a packet by itself */
                if( strlen( val ) + 2 > MAX_MSG_LEN ) {
                    message_publish(MSG_WARNING, "%p Variable Server buffer[%d] too small for symbol %s, TRUNCATED IT.\n",
                                    &connection, MAX_MSG_LEN, vars[i]->ref->reference );
                    val[MAX_MSG_LEN - 1] = '\0';
                }

                len = strlen(buf1) ;

                /* make sure there is space for the next tab or next newline and null */
                if( len + strlen( val ) + 2 > MAX_MSG_LEN ) {

                    if (debug >= 2) {
                        message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d ascii bytes:",
                                        &connection, connection.client_tag, (int)strlen(buf1)) ;
                        message_publish(MSG_NORMAL, "%s\n", buf1);
                    }

                    ret = tc_write(&connection, (char *) buf1, len);
                    if ( ret != len ) {
                        return(-1) ;
                    }
                    buf1[0] = '\0';
                }

                strcat(buf1, val);
                strcat(buf1, "\t");
            }

            len = strlen(buf1) ;

            if ( len > 0 ) {
                buf1[ strlen(buf1) - 1 ] = '\n';

                if (debug >= 2) {
                    message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d ascii bytes:",
                                    &connection, connection.client_tag, (int)strlen(buf1)) ;
                    message_publish(MSG_NORMAL, "%s\n", buf1);
                }
                ret = tc_write(&connection, (char *) buf1, (int)strlen(buf1));
                if ( ret != (int)strlen(buf1) ) {
                    return(-1) ;
                }
            }
        }
    }

    return (0);
}
Exemplo n.º 26
0
int Trick::SlaveInfo::start() {

    int arg_i;
    char *display;

    std::stringstream startup_command ;
    std::stringstream temp_stream ;

    struct passwd *passp;

    int argc ;
    char ** argv ;

    std::string slave = "undefined";

    /** @par Detailed Design */
    argc = command_line_args_get_argc() ;
    argv = command_line_args_get_argv() ;

    /** @li If the slave connection type is not specified return an error */
    if ( connection == NULL ) {
        message_publish(MSG_ERROR , "Slave connection type not specified.\n") ;
        return(-1) ;
    }

    /** @li Start remote startup command with remote shell to use and remote machine name*/
    switch ( remote_shell ) {
        case TRICK_RSH:
            startup_command << unix_rsh << " " << remote_shell_args ;
            break;
        case TRICK_USER_REMOTE_SH:
            if ( user_remote_shell.empty() ) {
                message_publish(MSG_WARNING , "TRICK_USER_REMOTE_SH specified for Slave startup, but no shell given.\nDefaulting to %s.\n", unix_ssh) ;
                user_remote_shell = unix_ssh ;
            }
            startup_command << user_remote_shell << " " << remote_shell_args ;
            break;
        case TRICK_SSH:
        default:
            startup_command << unix_ssh << " " << remote_shell_args ;
            break;
    }
    startup_command << " " << machine_name ;

    /** @li Add the remote display. If a remote display has not been specified, use the environment's */
    if ( machine_display.empty() ) {
        if ((display = (char *) env_get_var("DISPLAY")) == NULL) {
            message_publish(MSG_ERROR, "Cannot get environment variable $DISPLAY for Slave.\n") ;
        } else {
            machine_display = display ;
        }
    }

    /** @li cd to the simulation path in the remote startup command */
    if ( sim_path.empty() ) {
        message_publish(MSG_ERROR, "Slave startup sim_path is empty.\n") ;
        return(-1) ;
    }
    /** @li Set the DISPLAY environment variable in the remote startup command.
            Use setenv for *csh or export for all other shells */
    passp = getpwuid(getuid());
    if ( ! machine_display.empty() ) {
        if (strstr(passp->pw_shell, "csh")) {
            startup_command << " 'setenv DISPLAY " << machine_display ;
        } else {
            startup_command << " 'export DISPLAY=" << machine_display ;
        }
        startup_command << " ; cd " << sim_path << " ; " ;
    } else {
        startup_command << " 'cd " << sim_path << " ; " ;
    }

    if (strstr(passp->pw_shell, "csh")) {
        startup_command << " setenv TRICK_HOST_CPU `trick-gte TRICK_HOST_CPU` ; " ;
    } else {
        startup_command << " export TRICK_HOST_CPU=`trick-gte TRICK_HOST_CPU` ; " ;
    }


    /** @li start the simulation in the remote startup command */
    if ( S_main_name.empty() ) {
        S_main_name = "./S_main_${TRICK_HOST_CPU}.exe" ;
    }
    startup_command << S_main_name ;

    /** @li add the user provided run input file if provided */
    if ( ! run_input_file.empty() ) {

        startup_command << " " << run_input_file ;

        /** @li check to see if master is running with dmtcp slave */
        if (run_input_file.find("dmtcp") != std::string::npos)
            slave_type = "dmtcp";
    }

    /** @li Add the connection specific arguments to the startup command */
    startup_command << " " << connection->add_sim_args( slave_type ) ;

    /* @li Add the additional user arguments to the remote command */
    if ( ! other_args.empty() ) {
        startup_command << " -u " << other_args ;
    }
    for (arg_i = 2; arg_i < argc ; arg_i++) {
        startup_command << " " << argv[arg_i] ;
    }

    /* @li start the remote command in the background */
    startup_command << "' &"  ;

    message_publish(MSG_INFO, startup_command.str().c_str()) ;

    /* @li Execute the startup command */
    if (system(startup_command.str().c_str())) {
        perror("Slave_start");
        return (-2) ;
    }

    /* @li Wait for the slave to connect to the master */
    connection->accept() ;

    /* @li Set the synchronization wait limit */
    connection->set_sync_wait_limit(sync_wait_limit) ;

    /* Set slave to activated */
    activated = true;

    return (0) ;
}
Exemplo n.º 27
0
int Trick::SlaveInfo::restart_dmtcp_slave() {
#ifdef _DMTCP
    FILE *fp;
    char *dmtcp_path, line[256];
    std::string config_file;
    std::string dmtcp_command;
    std::stringstream dmtcp_port_str;
    pid_t pid, dmtcp_pid;

    /** @par Detailed Design: */
    if ( enabled ) {
        if (slave_type != "dmtcp") {
            message_publish(MSG_ERROR, "Cannot auto-start slave because it was not running under dmtcp control.\n") ;
            return(0);
        }
        /** @li If chkpnt_load_auto is specified, restart the slave by executing the user-supplied chkpnt_name... */
        if (chkpnt_load_auto) {
            if (chkpnt_name[0] == MS_ERROR_NAME) {
                message_publish(MSG_WARNING, "Cannot auto-start slave because master did not receive chkpnt_name from slave.\n");
            } else {
                /** @li First kill slave's dmtcp_coordinator because sometimes it does not quit like it's supposed to. */
                if (dmtcp_port > 0) { // slave sends 0 if it can't get the port num from the environment
                    /** @li Get dmtcp path from trick's configure output file (dmtcp is only supported in linux). */
                    config_file = std::string(getenv("TRICK_HOME")) + "/config_Linux.mk";
                    if ((fp = fopen(config_file.c_str() , "r")) != NULL ) {
                        while (fgets(line, sizeof(line), fp) != NULL) {
                            if (strncmp(line, "DMTCP", 5)==0) {
                                dmtcp_path = strchr(line, '/');
                                dmtcp_path[strlen(dmtcp_path)-1] = '\0'; // remove newline character
                                break;
                            }
                        }
                    }
                    /** @li Issue a dmtcp_command to kill the dmtcp_coordinator. */
                    fprintf(stderr, "Master attempting to kill slave's dmtcp_coordinator port= %ld"
                                    " (it may not exist, that's ok)\n", dmtcp_port);
                    //dmtcp_command.str(""); // reset our command string
                    dmtcp_command = dmtcp_path + std::string("/bin/dmtcp_command");
                    if (access(dmtcp_command.c_str(), F_OK) != 0) {
                        fprintf(stderr, "\nCould not find %s in order to kill the dmtcp_coordinator.\n",
                                        dmtcp_command.c_str());
                    } else {
                        //dmtcp_command << " --quiet -p " << dmtcp_port << " q";
                        message_publish(MSG_WARNING, "Restarting DMTCP coordinator\n");
                        if((dmtcp_pid = fork()) == 0) {
                            setsid();
                            dmtcp_port_str << dmtcp_port;
                            int execReturn = execl(dmtcp_command.c_str(), "dmtcp_command", "--quiet", "-p", dmtcp_port_str.str().c_str(), "q", NULL);
                            _Exit(0);
                        } else {
                            int f_status = 0;
                            if(dmtcp_pid > 0) {
                                waitpid(dmtcp_pid, &f_status, 0);
                            } else {
                                message_publish(MSG_ERROR, "Unable to send DMTCP restart command\n");
                            }
                        }
                        //system(dmtcp_command.str().c_str());
                    }
                } // end if dmtcp_port > 0
                /** @li Finally invoke the slave's dmtcp checkpoint script. */
                message_publish(MSG_WARNING, "Auto-starting slave: %s.\n", chkpnt_name);
                if ((pid = fork()) == 0) {
                    setsid();
                    std::istringstream sChkpnt(chkpnt_name);
                    std::string fileName;
                    while (std::getline(sChkpnt, fileName, '/'));
                    //fprintf(stderr, "------> Starting: %s\n", fileName.c_str());
                    int execReturn = execl(chkpnt_name, fileName.c_str(), NULL);
                    _Exit(0);
                }
            }
        } // end chkpnt_auto
        /** @li If our connection is a socket, disconnect the socket and call accept again */
        if (dynamic_cast<MSSocket*>(connection)) {
            connection->disconnect();
            //TODO: this will block until slave restarts, possibly causing overruns in freeze mode
            connection->accept();
        }
        reconnect_count = 0; // start writing status to slave again
    }
#endif
    return(0) ;
}
Exemplo n.º 28
0
int Trick::SlaveInfo::read_slave_status() {

    MS_SIM_COMMAND slave_command ;
    MS_SIM_COMMAND exec_command ;

    /** @par Detailed Design: */
    /** @li If the slave is an active synchronization partner (activated == true) */
    if (activated == true) {

        /** @li read the current slave exec_command */
        slave_command = connection->read_command() ;
        //printf("DEBUG master read %d command from slave\n", slave_command);fflush(stdout);

        exec_command = (MS_SIM_COMMAND)exec_get_exec_command() ;
        // fixup: is it possible we won't get slave's Exit command over socket when it terminates?, set it here if that happens
        if (dynamic_cast<MSSocket*>(connection)) {
            if ((slave_command == MS_ErrorCmd) && (reconnect_wait_limit > 0.0) && (reconnect_count == 0)) {
                slave_command = MS_ExitCmd;
            }
        }

        /** @li If the master is not currently exiting, change modes if the slave is freezing/exiting or has an error */
        if ( exec_command != MS_ExitCmd ) {
            switch ( slave_command ) {
                case (MS_ErrorCmd):
                    /** @li if the user has set a reconnect_wait_limit, continue on if we are still under that limit, otherwise
                            if the current slave mode cannot be read, exit the master if sync_error_terminate == true,
                            otherwise set the activated flag to false */
                    if ( (reconnect_count * exec_get_freeze_frame()) < reconnect_wait_limit) {
                        reconnect_count++;
                    } else if (sync_error_terminate == true) {
                        message_publish(MSG_ERROR, "Master lost sync with slave, so master is terminating.\n") ;
                        exec_terminate_with_return(-1, __FILE__, __LINE__ , "Master lost sync with slave.") ;
                    }
                    else {
                        message_publish(MSG_ERROR, "Master lost sync with slave, so slave is being deactivated.\n") ;
                        activated = false ;
                        return(0) ;
                    }
                    break ;
                case (MS_ExitCmd):
                    /** @li if the current slave mode is exiting, exit the master if sync_error_terminate == true.
                            otherwise wait for slave to reconnect. when wait limit is 0, set the activated flag to false */
                    if  (sync_error_terminate == true){
                        message_publish(MSG_WARNING, "sync_error_terminate is true: Slave is exiting, so master is terminating.\n") ;
                        exec_terminate_with_return(-1, __FILE__, __LINE__ , "Slave is exiting, so is the master.") ;
                    }
                    else {
                        message_publish(MSG_WARNING, "Slave is exiting.\n") ;
                        // if reconnect_wait_limit is set, master waits for slave to reconnect (e.g. dmtcp restarting)
                        if (reconnect_wait_limit > 0.0) {
                            message_publish(MSG_WARNING, "Master will wait %f seconds for slave to reconnect.\n", reconnect_wait_limit) ;
                            // make reads (shared mem connection) return quickly so we don't overrun waiting for reconnect
                            // TODO: for socket connection we will overrun in the accept call (see restart_dmtcp_slave)
                            connection->set_sync_wait_limit(exec_get_freeze_frame());
                            if (chkpnt_binary) {
                                restart_dmtcp_slave(); // restart the slave dmtcp executable
                            }
                        }
                        else {
                            message_publish(MSG_WARNING, "reconnect_wait_limit: 0.0 - Master will stop communicating with slave.\n") ;
                            activated = false ;
                        }
                        return(0) ;
                    }
                    break ;
                case (MS_ChkpntLoadBinCmd):
                    // slave has received our load command and is now sending us his dmtcp port and checkpoint file name
                    dmtcp_port = connection->read_port() ;
                    connection->read_name(chkpnt_name, sizeof(chkpnt_name)); // dir/filename
                    message_publish(MSG_WARNING , "Master received DMTCP Port and Checkpoint Filename from slave.\n");
                    connection->write_command((MS_SIM_COMMAND)exec_get_exec_command()) ; // send this as an ack so slove can shut down
                    break ;
                case (MS_FreezeCmd):
                    /** @li if the current slave is freezing, freeze the master too */
                    message_publish(MSG_INFO, "Slave is freezing.\n") ;
                    exec_set_exec_command(FreezeCmd) ;
                    reconnect_count = 0;
                    break ;
                case (MS_ReconnectCmd):
                    // set the sync wait limit back to its default
                    connection->set_sync_wait_limit(sync_wait_limit);
                    message_publish(MSG_INFO, "Master has reconnected to slave.\n") ;
                    reconnect_count = 0;
                    break ;
                default:
                    break ;
            }
        }
    }
    return(0) ;
}
Exemplo n.º 29
0
//Create the DP files to display job timelines.
int Trick::FrameLog::create_DP_timeline_files() {

    FILE *fpx;
    int jj;
    std::string DP_buff;
    const char *headerx = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" \
                    "<!DOCTYPE product PUBLIC \"-//Tricklab//DTD Product V1.0//EN\" \"Product.dtd\">\n\n" \
                    "<!-- Description: Plot of Y(t) vs. t, with attributes, titles, labels, units -->\n\n" \
                    "<product version=\"1.0\">\n";

    // DP_rt_timeline --------------------------------------------------------------
    DP_buff = DP_dir + "/DP_rt_timeline.xml";
    if ((fpx = fopen(DP_buff.c_str(), "w")) == NULL) {
        message_publish(MSG_WARNING, "Could not open DP_rt_timeline.xml file for Frame Logging\n") ;
        return(0);
    }

    fprintf(fpx, "%s", headerx);
    fprintf(fpx, "    <title>Job Timeline</title>\n    <page vcells=\"3\">\n        <title>Job Timeline</title>\n");
    fprintf(fpx, "        <plot grid=\"yes\">\n            <title>User Job Timeline</title>\n");
    fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
    fprintf(fpx, "            <yaxis> <label>Job Id</label> </yaxis>\n");
    fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
    fprintf(fpx, "                <var line_color=\"red\" label=\"User Job Id\">trick_frame_log.frame_log.job_user_id</var>\n") ;
    fprintf(fpx, "            </curve>\n");
    fprintf(fpx, "        </plot>\n");
    fprintf(fpx, "        <plot grid=\"yes\">\n            <title>Trick Job Timeline</title>\n");
    fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
    fprintf(fpx, "            <yaxis> <label>Job Id</label> </yaxis>\n");
    fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
    fprintf(fpx, "                <var line_color=\"darkgreen\" label=\"Trick Job Id\">trick_frame_log.frame_log.job_trick_id</var>\n") ;
    fprintf(fpx, "            </curve>\n");
    fprintf(fpx, "        </plot>\n");
    // don't generate the plot without a curve
    if (num_threads > 1) {
        fprintf(fpx, "        <plot grid=\"yes\">\n            <title>Child Job Timeline</title>\n");
        fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
        fprintf(fpx, "            <yaxis> <label>Job Id</label> </yaxis>\n");
        for (jj=1; jj<num_threads; jj++) {
            fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
            fprintf(fpx, "                <var line_color=\"blue\" label=\"Child%d Job Id\">trick_frame_log.frame_log.job_userC%d_id</var>\n",
             jj,jj);
            fprintf(fpx, "            </curve>\n");
        }
        fprintf(fpx, "        </plot>\n");
    }
    fprintf(fpx, "    </page>\n");

    fprintf(fpx, "    <page>\n        <title>Job Timeline (combined)</title>\n");
    fprintf(fpx, "        <plot grid=\"yes\">\n            <title>User and Trick Job Timeline</title>\n");
    fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
    fprintf(fpx, "            <yaxis> <label>Job Id</label> </yaxis>\n");
    fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
    fprintf(fpx, "                <var line_color=\"darkgreen\" label=\"Trick Job Id\">trick_frame_log.frame_log.job_trick_id</var>\n") ;
    fprintf(fpx, "            </curve>\n");
    fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
    fprintf(fpx, "                <var line_color=\"red\" label=\"User Job Id\">trick_frame_log.frame_log.job_user_id</var>\n");
    fprintf(fpx, "            </curve>\n");
    for (jj=1; jj<num_threads; jj++) {
        fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
        fprintf(fpx, "                <var line_color=\"blue\" label=\"Child%d Job Id\">trick_frame_log.frame_log.job_userC%d_id</var>\n",
                     jj,jj);
        fprintf(fpx, "            </curve>\n");
    }
    fprintf(fpx, "        </plot>\n");
    fprintf(fpx, "    </page>\n</product>");
    fclose(fpx);

    // DP_rt_timeline_init ---------------------------------------------------------
    DP_buff = DP_dir + "/DP_rt_timeline_init.xml";
    if ((fpx = fopen(DP_buff.c_str(), "w")) == NULL) {
        message_publish(MSG_WARNING, "Could not open DP_rt_timeline_init.xml file for Frame Logging\n") ;
        return(0);
    }

    fprintf(fpx, "%s", headerx);
    fprintf(fpx, "    <title>Non-cyclic Job Timeline</title>\n    <page>\n        <title>Non-cyclic Job Timeline</title>\n");
    fprintf(fpx, "        <plot grid=\"yes\">\n            <title>User Job Timeline</title>\n");
    fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
    fprintf(fpx, "            <yaxis> <label>Job Id</label> </yaxis>\n");
    fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
    fprintf(fpx, "                <var line_color=\"red\" label=\"User Job Id\">trick_frame_log.frame_log.job_userinit_id</var>\n") ;
    fprintf(fpx, "            </curve>\n");
    fprintf(fpx, "        </plot>\n");
    fprintf(fpx, "        <plot grid=\"yes\">\n            <title>Trick Job Timeline</title>\n");
    fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
    fprintf(fpx, "            <yaxis> <label>Job Id</label> </yaxis>\n");
    fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
    fprintf(fpx, "                <var line_color=\"darkgreen\" label=\"Trick Job Id\">trick_frame_log.frame_log.job_trickinit_id</var>\n") ;
    fprintf(fpx, "            </curve>\n");
    fprintf(fpx, "        </plot>\n");
    fprintf(fpx, "    </page>\n");

    fprintf(fpx, "    <page>\n        <title>Non-cyclic Job Timeline (combined)</title>\n");
    fprintf(fpx, "        <plot grid=\"yes\">\n            <title>User and Trick Job Timeline</title>\n");
    fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
    fprintf(fpx, "            <yaxis> <label>Job Id</label> </yaxis>\n");
    fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
    fprintf(fpx, "                <var line_color=\"darkgreen\" label=\"Trick Job Id\">trick_frame_log.frame_log.job_trickinit_id</var>\n");
    fprintf(fpx, "            </curve>\n");
    fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
    fprintf(fpx, "                <var line_color=\"red\" label=\"Trick Job Id\">trick_frame_log.frame_log.job_userinit_id</var>\n");
    fprintf(fpx, "            </curve>\n");
    fprintf(fpx, "        </plot>\n");
    fprintf(fpx, "    </page>\n</product>");
    fclose(fpx);

    return(0);

}
Exemplo n.º 30
0
//Create the DP files to display trick and user job execution times.
int Trick::FrameLog::create_DP_job_files() {

    std::vector<std::string>::iterator job_iterator;
    FILE *fpx;
    int pages, plots, total_plots, vcells, dot;
    char *bg_color;
    double time_scale;
    std::string DP_buff;
    const char *headerx = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" \
                    "<!DOCTYPE product PUBLIC \"-//Tricklab//DTD Product V1.0//EN\" \"Product.dtd\">\n\n" \
                    "<!-- Description: Plot of Y(t) vs. t, with attributes, titles, labels, units -->\n\n" \
                    "<product version=\"1.0\">\n";

    time_scale = 1.0 / exec_get_time_tic_value();
    DP_buff = DP_dir + "/DP_rt_frame.xml";
    if ((fpx = fopen(DP_buff.c_str(), "w")) == NULL) {
        message_publish(MSG_WARNING, "Could not open DP_rt_frame.xml file for Frame Logging\n") ;
        return(0);
    }
    fprintf(fpx, "%s", headerx);
    fprintf(fpx, "    <title>Real-Time Frame Overrun/Underrun History</title>\n    <page>\n        <title>Real-Time Scheduling Frame</title>\n");
    fprintf(fpx, "        <plot grid=\"yes\">\n            <title>Frame Overrun/Underrun</title>\n");
    fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
    fprintf(fpx, "            <yaxis> <label>Frame Overrun/Underrun</label> </yaxis>\n");
    fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
    fprintf(fpx, "                <var scale=\"%g\" line_color=\"darkgreen\" label=\"Overrun/Underrun\">%s.rt_sync.frame_overrun_time</var>\n",
                 time_scale,rt_sim_object_name.c_str());
    fprintf(fpx, "            </curve>\n");
    fprintf(fpx, "        </plot>\n");
    fprintf(fpx, "        <plot grid=\"yes\">\n            <title>Frame Scheduled Jobs Time</title>\n");
    fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
    fprintf(fpx, "            <yaxis> <label>Frame Scheduled Jobs Time</label> </yaxis>\n");
    fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
    fprintf(fpx, "                <var scale=\"%g\" line_color=\"red\" label=\"Frame Sched Time\">%s.rt_sync.frame_sched_time</var>\n",
                 time_scale,rt_sim_object_name.c_str());
    fprintf(fpx, "            </curve>\n");
    fprintf(fpx, "        </plot>\n");
    fprintf(fpx, "    </page>\n");

    //unsigned int total_pages = (unsigned int)(drg_users.size() / 8) + 1 ;
    unsigned int total_pages ;
    if ( drg_users.size() <= 1 ) {
        total_pages = 1 ;
    } else {
        total_pages = (unsigned int)((drg_users.size() - 2)/ 8) + 1 ;
    }
    unsigned int page_count ;
    for ( page_count = 0 ; page_count < total_pages ; page_count++ ) {
        unsigned int ii = 0 ;
        // this check is to avoid empty page creation
        if ((page_count * 8 + ii + 1) >= drg_users.size()) {
        	continue;
        }
        fprintf(fpx, "    <page>\n");
        for ( ii = 0 ; ii < 8 and (page_count * 8 + ii + 1) < drg_users.size() ; ii++ ) {
            fprintf(fpx, "        <plot grid=\"yes\">\n");
            fprintf(fpx, "            <title>Child thread %d Frame Scheduled Jobs</title>\n", (page_count * 8 + ii + 1));
            fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
            fprintf(fpx, "            <yaxis> <label>Frame Scheduled Jobs Time</label> </yaxis>\n");
            fprintf(fpx, "            <curve>\n");
            fprintf(fpx, "                <var>sys.exec.out.time</var>\n");
            std::ostringstream group_name ;
            group_name << "frame_userjobs_C" << (page_count * 8 + ii + 1) ;
            fprintf(fpx, "                <var scale=\"%g\" line_color=\"red\" label=\"Frame Sched Time\">%s.frame_sched_time</var>\n",
                         time_scale,group_name.str().c_str());
            fprintf(fpx, "            </curve>\n");
            fprintf(fpx, "        </plot>\n");
        }
        fprintf(fpx, "    </page>\n");
    }

    fprintf(fpx, "    <table>\n        <title>Real-Time Frame Overrun/Underrun History</title>\n");
    fprintf(fpx, "        <column format=\"%%13.6f\">\n");
    fprintf(fpx, "            <label>Sim Time</label>\n            <var>sys.exec.out.time</var>\n");
    fprintf(fpx, "        </column>\n");
    fprintf(fpx, "        <column format=\"%%13.6f\">\n");
    fprintf(fpx, "            <label>Overrun/Underrun</label>\n            <var scale=\"%g\">%s.rt_sync.frame_overrun_time</var>\n",
                 time_scale,rt_sim_object_name.c_str());
    fprintf(fpx, "        </column>\n");
    fprintf(fpx, "        <column format=\"%%13.6f\">\n");
    fprintf(fpx, "            <label>Frame Sched Time</label>\n            <var scale=\"%g\">%s.rt_sync.frame_sched_time</var>\n",
                 time_scale,rt_sim_object_name.c_str());
    fprintf(fpx, "        </column>\n");
    fprintf(fpx, "    </table>\n</product>");
    fclose(fpx);

    // sort the saved job names
    sort(user_jobs.begin(), user_jobs.end());
    sort(trick_jobs.begin(), trick_jobs.end());

    // DP_rt_userjobs --------------------------------------------------------------
    int ii ;
    char numstr[21];
    for ( ii = 0 ; ii < num_threads ; ii++ ) {
        if ( ii == 0 ) {
             DP_buff = DP_dir + "/DP_rt_userjobs.xml";
        } else {
             sprintf(numstr, "%d", ii);
             DP_buff = DP_dir + "/DP_rt_userjobs_C" + numstr + ".xml";
        }

        if ((fpx = fopen(DP_buff.c_str(), "w")) == NULL) {
            message_publish(MSG_WARNING, "Could not open DP_rt_userjobs.xml file for Frame Logging\n") ;
            return(0);
        }

        fprintf(fpx, "%s", headerx);
        fprintf(fpx, "    <title>User Job Execution History</title>\n");
        pages = 0; plots = 0;
        total_plots = drg_users[ii]->rec_buffer.size();
        std::vector <Trick::DataRecordBuffer *>::iterator drb_it ;
        bg_color = (char *)"cornsilk2";
        for ( drb_it = drg_users[ii]->rec_buffer.begin() + 1 ; drb_it != drg_users[ii]->rec_buffer.end() ; drb_it++ ) {
            if ( ! (*drb_it)->name.compare(0, 5, "frame") ) continue ;
            // 8 job plots per page
            if ((plots == 0) || (plots > 8)) {
                pages++;
                vcells = (total_plots/pages > 8) * 4;
                if (pages > 1) {
                    fprintf(fpx, "    </page>\n");
                }
                fprintf(fpx, "    <page vcells=\"%d\">\n        <title>User Job Execution Times</title>\n", vcells);
                plots = 1;
            }
            fprintf(fpx, "        <plot grid=\"yes\" background_color=\"%s\">\n            <title>%s</title>\n", bg_color, (*drb_it)->name.c_str());
            fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
            fprintf(fpx, "            <yaxis> <label>Execution Time</label> </yaxis>\n");
            fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
            fprintf(fpx, "                <var line_color=\"red\" scale=\"%g\">%s</var>\n", time_scale, (*drb_it)->name.c_str());
            fprintf(fpx, "            </curve>\n");
            fprintf(fpx, "        </plot>\n");
            plots++;

        }
        fprintf(fpx, "    </page>\n</product>");
        fclose(fpx);
    }

    // DP_rt_trickjobs -------------------------------------------------------------
    DP_buff = DP_dir +  "/DP_rt_trickjobs.xml";
    if ((fpx = fopen(DP_buff.c_str(), "w")) == NULL) {
        message_publish(MSG_WARNING, "Could not open DP_rt_trickjobs.xml file for Frame Logging\n") ;
        return(0);
    }
    fprintf(fpx, "%s", headerx);
    fprintf(fpx, "    <title>Trick Job Execution History</title>\n");
    pages = 0; plots = 0;
    total_plots = trick_jobs.size();
    job_iterator = trick_jobs.begin();
    while (job_iterator != trick_jobs.end()) {
        dot = (*job_iterator).find_first_of(".");
        // default background color, for trick_whatever jobs and anything else we don't list here
        bg_color = (char *)"cornsilk3";
        // give the different types of trick jobs a different background color
        if (!(*job_iterator).compare(0,dot,std::string("JOB_") + msg_sim_object_name)) {
            bg_color = (char *)"lavenderblush3";
        }
        if (!(*job_iterator).compare(0,dot,std::string("JOB_") + dr_sim_object_name) ||
            !(*job_iterator).compare(0,21,std::string("JOB_data_record_group")) ) {
            bg_color = (char *)"slategray2";
        }
        if (!(*job_iterator).compare(0,dot,std::string("JOB_") + rt_sim_object_name)) {
            bg_color = (char *)"honeydew3";
        }
        if (!(*job_iterator).compare(0,dot,std::string("JOB_") + ms_sim_object_name)) {
            bg_color = (char *)"bisque2";
        }
        if (strncmp((*job_iterator).c_str(),"JOB_sys_integ",13)==0) {
            bg_color = (char *)"burlywood";
        }
        //other good colors in case you need more:
            //bg_color = "khaki3";
        // 8 job plots per page
        if ((plots == 0) || (plots > 8)) {
            pages++;
            vcells = (total_plots/pages > 8) * 4;
            if (pages > 1) {
                fprintf(fpx, "    </page>\n");
            }
            fprintf(fpx, "    <page vcells=\"%d\">\n        <title>Trick Job Execution Times</title>\n", vcells);
            plots = 1;
        }
        fprintf(fpx, "        <plot grid=\"yes\" background_color=\"%s\">\n            <title>%s</title>\n", bg_color, (*job_iterator).c_str());
        fprintf(fpx, "            <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
        fprintf(fpx, "            <yaxis> <label>Execution Time</label> </yaxis>\n");
        fprintf(fpx, "            <curve>\n                <var>sys.exec.out.time</var>\n");
        fprintf(fpx, "                <var line_color=\"darkgreen\" scale=\"%g\">%s</var>\n", time_scale, (*job_iterator).c_str());
        fprintf(fpx, "            </curve>\n");
        fprintf(fpx, "        </plot>\n");
        job_iterator++;
        plots++;
    }
    fprintf(fpx, "    </page>\n</product>");
    fclose(fpx);

    return(0) ;
}