Esempio n. 1
0
/**
@details
-# If real-time synchronization has been enabled:
   -# Set the active flag to true.
-# If real-time synchronization has been disabled set the active flag to false.
*/
int Trick::RealtimeSync::initialize() {

    if ( enable_flag ) {
        active = true ;
        enable_flag = false ;
    }

    if ( disable_flag ) {
        active = false ;
        disable_flag = false ;
    }

    tics_per_sec =  exec_get_time_tic_value();

    /* Start the sleep timer hardware if realtime is active */
    start_sleep_timer();

    if ( align_sim_to_wall_clock ) {
        rt_clock->sync_to_wall_clock( align_tic_mult , tics_per_sec ) ;
        message_publish(MSG_INFO, "Syncing sim to %f second wall clock interval\n", align_tic_mult ) ;
        if ( exec_get_mode() == Freeze ) {
            rt_clock->clock_spin(exec_get_freeze_time_tics()) ;
        } else {
            rt_clock->clock_spin(exec_get_time_tics()) ;
        }
    }

    return(0) ;
}
Esempio n. 2
0
int Trick::Master::init() {

    unsigned int ii ;

    /** @li Call Trick::SlaveInfo::start() for each slave */
    if ( enabled ) {
        for ( ii = 0 ; ii < slaves.size() ; ii++ ) {
            slaves[ii]->start() ;
            /** @li Write the master's software frame to each slave */
            slaves[ii]->connection->write_time(exec_get_software_frame_tics()) ;
            /** @li Write the master's time tic value to each slave */
            slaves[ii]->connection->write_time(exec_get_time_tic_value()) ;
            /** @li Write the master's sync_wait_limit to each slave */
            slaves[ii]->connection->write_time((long long)(slaves[ii]->sync_wait_limit * exec_get_time_tic_value())) ;
            /** @li Cast the freeze command and write it to the slave */
            slaves[ii]->connection->write_command((MS_SIM_COMMAND)exec_get_freeze_command()) ;
            /** @li Write a flag word containing the checkpoint pre_init, post_init, and end flags to the slave */
            slaves[ii]->connection->write_time((long long) ((get_checkpoint_pre_init() << 2) +
                                                            (get_checkpoint_post_init() << 1) +
                                                            (get_checkpoint_end())) );
        }

        // Freezes are only allowed on frame boundaries when Master/Slave is enabled.
        exec_set_freeze_on_frame_boundary(true) ;

    }

    return(0) ;
}
Esempio n. 3
0
TEST_F(ExecutiveTest , JobCycleNotDivisibleByTimeTic) {
    //req.add_requirement("r_exec_jobs");
	//"The Executive Scheduler shall provide the capability to list jobs not handled by any scheduler."

    EXPECT_EQ(exec_get_time_tic_value(), 1000000) ;
    exec_add_sim_object(&empty_so , "empty_so") ;
    EXPECT_EQ(exec.check_all_job_cycle_times() , -1 ) ;
}
Esempio n. 4
0
Trick::VariableServerThread::VariableServerThread(TCDevice * in_listen_dev) :
 Trick::ThreadBase("VarServer") ,
 listen_dev(in_listen_dev) {

    debug = 0 ;
    enabled = true ;
    log = false ;
    connection_accepted = false ;
    conn_type = TCP ;
    copy_mode = VS_COPY_ASYNC ;
    write_mode = VS_WRITE_ASYNC ;
    frame_multiple = 1 ;
    frame_offset = 0 ;
    freeze_frame_multiple = 1 ;
    freeze_frame_offset = 0 ;
    binary_data = false;
    multicast = false;
    byteswap = false ;
    retry_bad_ref = false ;

    pause_cmd = false ;
    exit_cmd = false ;

    send_stdio = false ;

    update_rate = 0.1 ;
    cycle_tics = (long long)(update_rate * exec_get_time_tic_value()) ;

    next_tics = TRICK_MAX_LONG_LONG ;
    freeze_next_tics = TRICK_MAX_LONG_LONG ;

    connection.disabled = TC_COMM_FALSE ;
    connection.disable_handshaking = TC_COMM_TRUE ;
    connection.blockio_limit = 0.0 ;
    connection.blockio_type = TC_COMM_BLOCKIO ;
    connection.client_id = 0 ;
    connection.dmtcp_use_real = 1 ;
    strcpy(connection.client_tag, "") ;
    connection.error_handler = (TrickErrorHndlr *) calloc(1, (int)sizeof(TrickErrorHndlr));
    connection.error_handler->report_level = TRICK_ERROR_CAUTION;

    pthread_mutex_init(&copy_mutex, NULL);

    var_data_staged = false;
    packets_copied = 0 ;

    incoming_msg = (char *) calloc(1, MAX_CMD_LEN);
    stripped_msg = (char *) calloc(1, MAX_CMD_LEN);

}
Esempio n. 5
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) ;
}
Esempio n. 6
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::copy_sim_data() {

    unsigned int ii ;
    VariableReference * curr_var ;

    if ( vars.size() == 0 ) {
        return 0 ;
    }

    if ( pthread_mutex_trylock(&copy_mutex) == 0 ) { 

        // Get the simulation time we start this copy
        time = (double)exec_get_time_tics() / exec_get_time_tic_value() ;

        for ( ii = 0 ; ii < vars.size() ; ii++ ) {
            curr_var = vars[ii] ;

            // if this variable is unresolved, try to resolve it
            if ( retry_bad_ref ) {
                if (curr_var->ref->address == &bad_ref_int) {
                    REF2 *new_ref = ref_attributes(const_cast<char*>(curr_var->ref->reference));
                    if (new_ref != NULL) {
                        curr_var->ref = new_ref;
                    }
                }
            }

            // if there's a pointer somewhere in the address path, follow it in case pointer changed
            if ( curr_var->ref->pointer_present == 1 ) {
                curr_var->address = follow_address_path(curr_var->ref) ;
                if ( curr_var->address == NULL ) {
                    std::string save_name(curr_var->ref->reference) ;
                    if ( curr_var->ref->attr) {
                        free(curr_var->ref->attr) ;
                    }
                    free(curr_var->ref) ;
                    curr_var->ref = make_error_ref(save_name) ;
                    curr_var->address = curr_var->ref->address ;
                } else {
                    curr_var->ref->address = curr_var->address ;
                }
            }

            // if this variable is a string we need to get the raw character string out of it.
            if (( curr_var->string_type == TRICK_STRING ) && !curr_var->need_deref) {
                std::string * str_ptr = (std::string *)curr_var->ref->address ;
                curr_var->address = (void *)(str_ptr->c_str()) ;
            }

            // if this variable itself is a pointer, dereference it
            if ( curr_var->need_deref) {
                curr_var->address = *(void**)curr_var->ref->address ;
            }

            // handle c++ string and char*
            if ( curr_var->string_type == TRICK_STRING ) {
                if (curr_var->address == NULL) {
                    curr_var->size = 0 ;
                } else {
                    curr_var->size = strlen((char*)curr_var->address) + 1 ;
                }
            }
            // handle c++ wstring and wchar_t*
            if ( curr_var->string_type == TRICK_WSTRING ) {
                if (curr_var->address == NULL) {
                    curr_var->size = 0 ;
                } else {
                    curr_var->size = wcslen((wchar_t *)curr_var->address) * sizeof(wchar_t);
                }
            }
            memcpy( curr_var->buffer_in , curr_var->address , curr_var->size ) ;
        }

        retry_bad_ref = false ;

        // Indicate that sim data has been written and is now ready in the buffer_in's of the vars variable list.
        var_data_staged = true;
        packets_copied++ ;

        pthread_mutex_unlock(&copy_mutex) ;
    }


    return (0) ;

}
Esempio n. 8
0
TEST_F(ExecutiveTest , DefaultTimeTicValue) {
    //req.add_requirement("2436759852");
	// "The Executive Scheduler shall default to 1,000,000 tics/second") ;
    EXPECT_EQ(exec_get_time_tic_value(), 1000000) ;
}
int Trick::VariableServerThread::var_cycle(double in_rate) {
    update_rate = in_rate ;
    cycle_tics = (long long)(update_rate * exec_get_time_tic_value()) ;
    return(0) ;
}