#include #include #include #include #include #include #include #include "trick/FrameLog.hh" #include "trick/FrameDataRecordGroup.hh" #include "trick/exec_proto.hh" #include "trick/exec_proto.h" #include "trick/clock_proto.h" #include "trick/data_record_proto.h" #include "trick/command_line_protos.h" #include "trick/message_proto.h" #include "trick/message_type.h" Trick::FrameLog * the_fl = NULL ; //Constructor. Trick::FrameLog::FrameLog() { frame_log_flag = false ; drg_trick = NULL ; drg_frame = NULL ; log_init_start = false; log_init_end = false; fp_time_main = NULL; fp_time_other = NULL; tl_max_samples = 100000; // default maximum # of jobs we can timeline time_value_attr.type = TRICK_LONG_LONG ; time_value_attr.size = sizeof(long long) ; time_value_attr.units = strdup("s") ; the_fl = this ; } Trick::FrameLog::~FrameLog() { free((char *)time_value_attr.units) ; // leaking all of the FrameDataRecordGroups // leaking timeline memory. } /** @details This routine is called during the "default_data" phase of initialization. At that time the number of threads in the sim will be known and this ensure that everything is allocated before the input_processor is initially run. -# Allocate a FrameDataRecordGroup to hold user job information on the main thread -# Push the FrameDataRecordGroup to drg_users. -# For each child thread in the sim -# Allocate a FrameDataRecordGroup to hold user job information on the child thread -# Push the FrameDataRecordGroup to drg_users. -# Allocate a FrameDataRecordGroup to hold trick job information -# Allocate a FrameDataRecordGroup to hold frame information -# Allocate space for timeline for each thread. */ void Trick::FrameLog::allocate_recording_groups() { Trick::FrameDataRecordGroup * fdrg ; int ii ; /* Create log_user_jobs group and log_trick_jobs group to record job frame_times. */ fdrg = new ("trick_frame_userjobs_main") Trick::FrameDataRecordGroup(0, "frame_userjobs_main") ; drg_users.push_back(fdrg) ; num_threads = exec_get_num_threads(); for ( ii = 1 ; ii < num_threads ; ii++ ) { std::ostringstream group_name ; group_name << "trick_frame_userjobs_C" << ii ; fdrg = new (group_name.str().c_str()) Trick::FrameDataRecordGroup(ii, group_name.str()) ; drg_users.push_back(fdrg) ; } drg_trick = new ("trick_frame_trick_jobs") FrameDataRecordGroup(0, "frame_trickjobs") ; drg_frame = new ("trick_frame") FrameDataRecordGroup(0, "frame") ; /* Allocate space for timeline for each thread according to user settable tl_max_samples variable. */ timeline = (Trick::timeline_t **)calloc( num_threads, sizeof(Trick::timeline_t*)); timeline_other = (Trick::timeline_t **)calloc( num_threads, sizeof(Trick::timeline_t*)); for (ii=0; ii all_jobs_vector ; exec_get_all_jobs_vector(all_jobs_vector) ; for ( ii = 0 ; ii < all_jobs_vector.size() ; ii++ ) { /** @li only makes sense to record frame time for scheduled, integ, and end_of_frame jobs */ /** @li exclude system jobs because they are excluded in instrument_before/after */ /** @li exclude frame_log jobs */ if ( (all_jobs_vector[ii]->job_class >= exec_get_scheduled_start_index() || (! all_jobs_vector[ii]->job_class_name.compare("integration")) || (! all_jobs_vector[ii]->job_class_name.compare("derivative")) || (! all_jobs_vector[ii]->job_class_name.compare("dynamic_event")) || (! all_jobs_vector[ii]->job_class_name.compare("post_integration")) || (! all_jobs_vector[ii]->job_class_name.compare("top_of_frame")) || (! all_jobs_vector[ii]->job_class_name.compare("end_of_frame"))) ) { dot = all_jobs_vector[ii]->name.find_first_of("."); if (!all_jobs_vector[ii]->name.compare(dot,11,".frame_log.")) { continue; } new_ref = (REF2 *)calloc(1 , sizeof(REF2)) ; /** @li add job frame id, job class and cycle time to displayed job name, and prepend "JOB_" so it stands out in quickplot */ if ( all_jobs_vector[ii]->job_class >= exec_get_scheduled_start_index() ) { if ( all_jobs_vector[ii]->thread == 0 ) { sprintf(job_name, "JOB_%s.%2.2f(%s_%2.3f)", all_jobs_vector[ii]->name.c_str(), all_jobs_vector[ii]->frame_id, all_jobs_vector[ii]->job_class_name.c_str(), all_jobs_vector[ii]->cycle); } else { // add child thread # to name sprintf(job_name, "JOB_%s_C%d.%2.2f(%s_%2.3f)", all_jobs_vector[ii]->name.c_str(), all_jobs_vector[ii]->thread, all_jobs_vector[ii]->frame_id, all_jobs_vector[ii]->job_class_name.c_str(), all_jobs_vector[ii]->cycle); } } else { // non-scheduled class sprintf(job_name, "JOB_%s.%2.2f(%s)", all_jobs_vector[ii]->name.c_str(), all_jobs_vector[ii]->frame_id, all_jobs_vector[ii]->job_class_name.c_str()); } // replace any colons in (C++) job name with underscores char *colon = strchr(job_name, ':') ; while (colon) { colon[0] = '#'; colon = strchr(job_name, ':') ; } new_ref->reference = strdup(job_name); new_ref->address = &(all_jobs_vector[ii]->frame_time) ; new_ref->attr = &time_value_attr ; /** @li use TRK tag in S_define to identify trick jobs */ // trick jobs if ( all_jobs_vector[ii]->tags.count("TRK") ) { trick_jobs.push_back(std::string(job_name)); drg_trick->add_variable(new_ref) ; drg_trick->add_rec_job(all_jobs_vector[ii]) ; // save names of trick sim objects (ones that user can change) so we can color code jobs in DP file if (!all_jobs_vector[ii]->name.compare(dot,5,".drd.")) { dr_sim_object_name = all_jobs_vector[ii]->parent_object->name; } if (!all_jobs_vector[ii]->name.compare(dot,8,".master.")) { ms_sim_object_name = all_jobs_vector[ii]->parent_object->name; } if (!all_jobs_vector[ii]->name.compare(dot,9,".rt_sync.")) { rt_sim_object_name = all_jobs_vector[ii]->parent_object->name; } //TODO: no message jobs yet - fill this in when messaging has a job to look at here // if () { msg_sim_object_name = std::string("message"); //} // user jobs } else { user_jobs.push_back(std::string(job_name)); drg_users[all_jobs_vector[ii]->thread]->add_variable(new_ref) ; drg_users[all_jobs_vector[ii]->thread]->add_rec_job(all_jobs_vector[ii]) ; } } } /* set the recoring job be and end of frame job. Set each recording group to it's proper thread. */ std::vector< Trick::FrameDataRecordGroup *>::iterator fdrg_it ; for ( fdrg_it = drg_users.begin() , ii = 0 ; fdrg_it != drg_users.end() ; fdrg_it++ , ii++ ) { (*fdrg_it)->set_job_class("end_of_frame") ; (*fdrg_it)->set_phase(65533); (*fdrg_it)->set_thread(ii); if ( ii > 0 ) { std::ostringstream group_name ; group_name << "frame_userjobs_C" << ii ; (*fdrg_it)->add_variable( group_name.str() + ".frame_sched_time") ; } } drg_trick->set_job_class("end_of_frame") ; drg_trick->set_phase(65535); } /** @details -# Add the log_userjob frame time we created above to the log_frame group -# Add the log_trickjob frame time we created above to the log_frame group -# Set the recording job data_record_group.frame to end of frame - phase it last (after rt_monitor) because time set in rt_monitor */ void Trick::FrameLog::add_recording_vars_for_frame() { REF2 * new_ref ; char job_name[256]; int ii ; drg_frame->add_variable(rt_sim_object_name + std::string(".rt_sync.frame_sched_time")) ; drg_frame->add_variable(rt_sim_object_name + std::string(".rt_sync.frame_overrun_time")) ; /* add the log_userjob frame time we created above to the log_frame group */ for ( ii = 0 ; ii < num_threads ; ii++ ) { new_ref = (REF2 *)calloc(1 , sizeof(REF2)) ; if (ii > 0) { sprintf(job_name, "JOB_data_record_group_frame_userjobs_C%d.data_record.%2.2f(end_of_frame)", ii,drg_users[ii]->write_job->frame_id); } else { sprintf(job_name, "JOB_data_record_group_frame_userjobs.data_record.%2.2f(end_of_frame)", drg_users[ii]->write_job->frame_id); } trick_jobs.push_back(std::string(job_name)); new_ref->reference = strdup(job_name); new_ref->address = &(drg_users[ii]->write_job->frame_time); new_ref->attr = &time_value_attr ; drg_frame->add_variable(new_ref) ; drg_frame->add_rec_job(drg_users[ii]->write_job) ; } /* add the log_trickjob frame time we created above to the log_frame group */ new_ref = (REF2 *)calloc(1 , sizeof(REF2)) ; sprintf(job_name, "JOB_data_record_group.trickjobs.%2.2f(end_of_frame)",drg_trick->jobs[0]->frame_id); trick_jobs.push_back(std::string(job_name)); new_ref->reference = strdup(job_name); new_ref->address = &(drg_trick->write_job->frame_time); new_ref->attr = &time_value_attr ; drg_frame->add_variable(new_ref) ; drg_frame->add_rec_job(drg_trick->write_job) ; /* set the recording job data_record_group.frame to end of frame - phase it last (after rt_monitor) because time set in rt_monitor */ drg_frame->set_job_class("end_of_frame") ; drg_frame->set_phase(65535); } /** @details -# For each FrameDataRecordGroup in drg_users -# Call add_data_record_group -# Call add_data_record_group for drg_trick -# Call add_data_record_group for drg_frame */ void Trick::FrameLog::add_recording_groups_to_sim() { std::vector< Trick::FrameDataRecordGroup *>::iterator fdrg_it ; for ( fdrg_it = drg_users.begin() ; fdrg_it != drg_users.end() ; fdrg_it++ ) { add_data_record_group( *fdrg_it , Trick::DR_Ring_Buffer) ; } add_data_record_group(drg_trick, Trick::DR_Ring_Buffer) ; add_data_record_group(drg_frame, Trick::DR_Ring_Buffer) ; } /** @details -# For each FrameDataRecordGroup in drg_users -# Call remove_data_record_group -# Call remove_data_record_group for drg_trick -# Call remove_data_record_group for drg_frame */ void Trick::FrameLog::remove_recording_groups_from_sim() { std::vector< Trick::FrameDataRecordGroup *>::iterator fdrg_it ; for ( fdrg_it = drg_users.begin() ; fdrg_it != drg_users.end() ; fdrg_it++ ) { remove_data_record_group( *fdrg_it) ; } remove_data_record_group(drg_trick) ; remove_data_record_group(drg_frame) ; } /** @details -# For each FrameDataRecordGroup in drg_users -# Call enable -# Call enable for drg_trick -# Call enable for drg_frame */ void Trick::FrameLog::enable_recording_groups() { std::vector< Trick::FrameDataRecordGroup *>::iterator fdrg_it ; for ( fdrg_it = drg_users.begin() ; fdrg_it != drg_users.end() ; fdrg_it++ ) { (*fdrg_it)->enable() ; } drg_trick->enable() ; drg_frame->enable() ; } /** @details -# For each FrameDataRecordGroup in drg_users -# Call disable -# Call disable for drg_trick -# Call disable for drg_frame */ void Trick::FrameLog::disable_recording_groups() { std::vector< Trick::FrameDataRecordGroup *>::iterator fdrg_it ; for ( fdrg_it = drg_users.begin() ; fdrg_it != drg_users.end() ; fdrg_it++ ) { (*fdrg_it)->disable() ; } drg_trick->disable() ; drg_frame->disable() ; } /** @details -# For each FrameDataRecordGroup in drg_users -# Call init -# Call init for drg_trick -# Call init for drg_frame */ void Trick::FrameLog::init_recording_groups() { std::vector< Trick::FrameDataRecordGroup *>::iterator fdrg_it ; for ( fdrg_it = drg_users.begin() ; fdrg_it != drg_users.end() ; fdrg_it++ ) { (*fdrg_it)->init() ; } drg_trick->init() ; drg_frame->init() ; } /** @details -# Insert frame log clock jobs in queue before and after all jobs we want to log the time of. */ void Trick::FrameLog::add_instrument_jobs() { exec_instrument_before("trick_frame_log.frame_log.frame_clock_start") ; exec_instrument_after("trick_frame_log.frame_log.frame_clock_stop") ; } /** @details -# Removes frame log clock jobs in queue before and after all jobs. */ void Trick::FrameLog::remove_instrument_jobs() { exec_instrument_remove("trick_frame_log.frame_log.frame_clock_start") ; exec_instrument_remove("trick_frame_log.frame_log.frame_clock_stop") ; } //Instrumentation job to save job timeline start time. int Trick::FrameLog::frame_clock_start(Trick::JobData * curr_job ) { Trick::JobData * target_job = (Trick::JobData *)curr_job->sup_class_data ; /** @par Detailed Design: */ if ( target_job != NULL ) { /** @li Set target job's start time. */ target_job->rt_start_time = clock_time() ; } return(0) ; } //Instrumentation job to save job timeline stop time and frame time. int Trick::FrameLog::frame_clock_stop(Trick::JobData * curr_job) { Trick::JobData * target_job = (Trick::JobData *)curr_job->sup_class_data ; int thread, mode; /** @par Detailed Design: */ if ( target_job != NULL ) { if ( target_job->rt_start_time >= 0 ) { /** @li Set current job's stop time and frame time. */ target_job->rt_stop_time = clock_time() ; target_job->frame_time += (target_job->rt_stop_time - target_job->rt_start_time); thread = target_job->thread; mode = exec_get_mode(); /** @li Whatever inits run after & including start_realtime, make them be timelined as cyclic. */ if (mode == Initialization) { if (! target_job->name.compare(rt_sim_object_name + std::string(".rt_sync.start_realtime")) ) { log_init_end = true; // fixup: set start_realtime function's start time to 0 because it will have reset the clock target_job->rt_start_time = 0; } if (log_init_end) { mode = Run; } } /** @li Save all cyclic job start & stop times for this frame into timeline structure. */ if ((mode==Run) || (mode==Step)) { // cyclic job if (tl_count[thread] < tl_max_samples) { timeline[thread][tl_count[thread]].id = target_job->frame_id; timeline[thread][tl_count[thread]].start = target_job->rt_start_time; timeline[thread][tl_count[thread]].stop = target_job->rt_stop_time; timeline[thread][tl_count[thread]].trick_job = target_job->tags.count("TRK"); tl_count[thread]++; } /** @li Save all non-cyclic job start & stop times for this frame into timeline_other structure. */ } else { // non-cyclic job if (tl_other_count[thread] < tl_max_samples) { timeline_other[thread][tl_other_count[thread]].id = target_job->frame_id; timeline_other[thread][tl_other_count[thread]].start = target_job->rt_start_time; timeline_other[thread][tl_other_count[thread]].stop = target_job->rt_stop_time; timeline_other[thread][tl_other_count[thread]].trick_job = target_job->tags.count("TRK"); tl_other_count[thread]++; } } // start timeline over target_job->rt_start_time = 0; target_job->rt_stop_time = 0; } else { target_job->frame_time = 0 ; } } return(0) ; } /** @details -# If we are enabled already, return -# If the frame log data recording groups are not in the sim -# Add the frame log data recording groups to the sim -# Initialize the frame log data recording groups. -# Add instrument jobs -# Enable the recording groups -# Set the frame log flag to true */ int Trick::FrameLog::framelog_on() { if ( frame_log_flag == true ) { return(0) ; } // test if we have added the frame logging objects to the sim or not. // If we haven't add them now and initialize the data recording groups. // We do this in framelog_on so we don't add unnecessary jobs and create // log_rt files until we have to. if ( get_data_record_group(drg_trick->get_group_name()) == NULL ) { add_recording_groups_to_sim() ; init_recording_groups() ; } add_instrument_jobs() ; enable_recording_groups() ; frame_log_flag = true ; return(0) ; } /** @details -# If we are disabled already, return -# Remove instrument jobs -# Disable the recording groups -# Set the frame log flag to false. */ int Trick::FrameLog::framelog_off() { if ( frame_log_flag == false ) { return(0) ; } remove_instrument_jobs() ; disable_recording_groups() ; frame_log_flag = false ; return(0) ; } /** @details Command to set the maximum number of job timeline samples to be taken (default = 100000). -# If num > 0 -# Set new maximum to num. -# For each thread -# Reallocate the timeline data array -# Reallocate the timeline_other data array */ int Trick::FrameLog::set_max_samples(int num) { int ii ; if (num > 0) { tl_max_samples = num ; for (ii=0; ii::iterator it ; for ( it = drg_users.begin() ; it != drg_users.end() ; it++ ) { (*it)->clear_checkpoint_vars() ; } drg_trick->clear_checkpoint_vars() ; drg_frame->clear_checkpoint_vars() ; return 0 ; } /** @details Restart job that restores framelogging on checkpoint restart. This is run after clear_data_record_info. -# Call data record group restart jobs -# Add data recording variables for the jobs and frame -# If frame log is on in checkpoint, turn frame log on. */ int Trick::FrameLog::restart() { // removing the data record groups removed the restart jobs too. call them here. std::vector< Trick::FrameDataRecordGroup *>::iterator it ; for ( it = drg_users.begin() ; it != drg_users.end() ; it++ ) { (*it)->restart() ; } drg_trick->restart() ; drg_frame->restart() ; add_recording_vars_for_jobs() ; add_recording_vars_for_frame() ; create_DP_files(); // if frame log is on in the checkpoint, turn it back on now if ( frame_log_flag == true ) { frame_log_flag = false ; remove_instrument_jobs() ; // these will be added back when frame log turned on framelog_on() ; } return 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::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 = "\n" \ "\n\n" \ "\n\n" \ "\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, " Real-Time Frame Overrun/Underrun History\n \n Real-Time Scheduling Frame\n"); fprintf(fpx, " \n Frame Overrun/Underrun\n"); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " %s.rt_sync.frame_overrun_time\n", time_scale,rt_sim_object_name.c_str()); fprintf(fpx, " \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n Frame Scheduled Jobs Time\n"); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " %s.rt_sync.frame_sched_time\n", time_scale,rt_sim_object_name.c_str()); fprintf(fpx, " \n"); fprintf(fpx, " \n"); fprintf(fpx, " \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, " \n"); for ( ii = 0 ; ii < 8 and (page_count * 8 + ii + 1) < drg_users.size() ; ii++ ) { fprintf(fpx, " \n"); fprintf(fpx, " Child thread %d Frame Scheduled Jobs\n", (page_count * 8 + ii + 1)); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n"); fprintf(fpx, " sys.exec.out.time\n"); std::ostringstream group_name ; group_name << "frame_userjobs_C" << (page_count * 8 + ii + 1) ; fprintf(fpx, " %s.frame_sched_time\n", time_scale,group_name.str().c_str()); fprintf(fpx, " \n"); fprintf(fpx, " \n"); } fprintf(fpx, " \n"); } fprintf(fpx, " \n Real-Time Frame Overrun/Underrun History\n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n %s.rt_sync.frame_overrun_time\n", time_scale,rt_sim_object_name.c_str()); fprintf(fpx, " \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n %s.rt_sync.frame_sched_time\n", time_scale,rt_sim_object_name.c_str()); fprintf(fpx, " \n"); fprintf(fpx, "
\n
"); 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, " User Job Execution History\n"); pages = 0; plots = 0; total_plots = drg_users[ii]->rec_buffer.size(); std::vector ::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, " \n"); } fprintf(fpx, " \n User Job Execution Times\n", vcells); plots = 1; } fprintf(fpx, " \n %s\n", bg_color, (*drb_it)->name.c_str()); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " %s\n", time_scale, (*drb_it)->name.c_str()); fprintf(fpx, " \n"); fprintf(fpx, " \n"); plots++; } fprintf(fpx, " \n"); 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, " Trick Job Execution History\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, " \n"); } fprintf(fpx, " \n Trick Job Execution Times\n", vcells); plots = 1; } fprintf(fpx, " \n %s\n", bg_color, (*job_iterator).c_str()); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " %s\n", time_scale, (*job_iterator).c_str()); fprintf(fpx, " \n"); fprintf(fpx, " \n"); job_iterator++; plots++; } fprintf(fpx, " \n"); fclose(fpx); return(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 = "\n" \ "\n\n" \ "\n\n" \ "\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, " Job Timeline\n \n Job Timeline\n"); fprintf(fpx, " \n User Job Timeline\n"); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " trick_frame_log.frame_log.job_user_id\n") ; fprintf(fpx, " \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n Trick Job Timeline\n"); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " trick_frame_log.frame_log.job_trick_id\n") ; fprintf(fpx, " \n"); fprintf(fpx, " \n"); // don't generate the plot without a curve if (num_threads > 1) { fprintf(fpx, " \n Child Job Timeline\n"); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); for (jj=1; jj\n sys.exec.out.time\n"); fprintf(fpx, " trick_frame_log.frame_log.job_userC%d_id\n", jj,jj); fprintf(fpx, " \n"); } fprintf(fpx, " \n"); } fprintf(fpx, " \n"); fprintf(fpx, " \n Job Timeline (combined)\n"); fprintf(fpx, " \n User and Trick Job Timeline\n"); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " trick_frame_log.frame_log.job_trick_id\n") ; fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " trick_frame_log.frame_log.job_user_id\n"); fprintf(fpx, " \n"); for (jj=1; jj\n sys.exec.out.time\n"); fprintf(fpx, " trick_frame_log.frame_log.job_userC%d_id\n", jj,jj); fprintf(fpx, " \n"); } fprintf(fpx, " \n"); fprintf(fpx, " \n"); 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, " Non-cyclic Job Timeline\n \n Non-cyclic Job Timeline\n"); fprintf(fpx, " \n User Job Timeline\n"); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " trick_frame_log.frame_log.job_userinit_id\n") ; fprintf(fpx, " \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n Trick Job Timeline\n"); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " trick_frame_log.frame_log.job_trickinit_id\n") ; fprintf(fpx, " \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n Non-cyclic Job Timeline (combined)\n"); fprintf(fpx, " \n User and Trick Job Timeline\n"); fprintf(fpx, " s \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " trick_frame_log.frame_log.job_trickinit_id\n"); fprintf(fpx, " \n"); fprintf(fpx, " \n sys.exec.out.time\n"); fprintf(fpx, " trick_frame_log.frame_log.job_userinit_id\n"); fprintf(fpx, " \n"); fprintf(fpx, " \n"); fprintf(fpx, " \n"); fclose(fpx); return(0); }