Ejemplo n.º 1
0
int Trick::DataRecordGroup::call_function( Trick::JobData * curr_job ) {

    int ret = 0 ;

    switch (curr_job->id) {
        case 1:
            ret = init() ;
            break ;
        case 2:
            ret = write_data(false) ;
            break ;
        case 3:
            ret = checkpoint() ;
            break ;
        case 4:
            clear_checkpoint_vars() ;
            break ;
        case 5:
            ret = restart() ;
            break ;
        case 6:
            ret = shutdown() ;
            break ;
        default:
            ret = data_record(exec_get_sim_time()) ;
            break ;
    }

    return(ret) ;

}
Ejemplo n.º 2
0
int Trick::DataRecordDispatcher::record_now_group( const char * in_name ) {
    unsigned int ii ;
    if ( in_name != NULL ) {
        for ( ii = 0 ; ii < groups.size() ; ii++ ) {
            if ( !groups[ii]->get_group_name().compare(in_name) )
                groups[ii]->data_record(exec_get_sim_time()) ;
        }
    }
    return 0 ;
}
Ejemplo n.º 3
0
/*
@details
-# if the path is empty after /commands create commands top level page.
-# else if the path is exec_get_sim_time return create a message with the sim time.
-# else create an error message.
*/
int Trick::JSONVariableServerThread::get_commands( std::stringstream & body , char * path ) {
    int ret = 200 ;
    if ( path[strlen(path) - 1] == '/') {
        path[strlen(path) - 1] = '\0' ;
    }
    if ( path[0] == '\0' ) {
        body << "   \"exec_get_sim_time\": \"exec_get_sim_time()\"" << std::endl ;
    } else if ( ! strcmp( path , "/exec_get_sim_time" ) ) {
        body << "   \"sim_time\": \"" << exec_get_sim_time() << "\"" << std::endl ;
    } else {
        body << "    \"message\" : \"Not Found\"" << std::endl ;
        ret = 404 ;
    }
    return ret ;
}
Ejemplo n.º 4
0
double Trick::SimTime::get_mettime() {
    
    return(exec_get_sim_time() + met_sec_ref);

}
Ejemplo n.º 5
0
double Trick::SimTime::get_rettime() {
    
    return(exec_get_sim_time());

}
Ejemplo n.º 6
0
/**
@details
-# Block all signals to the child.
-# Set the thread cancel type to asynchronous to allow master to this child at any time.
-# Lock the go mutex so the master has to wait until this child is ready before staring execution.
-# Set thread priority and CPU affinity
-# The child enters an infinite loop
    -# Blocks on mutex or frame trigger until master signals to start processing
    -# Switch if the child is a synchronous thread
        -# For each scheduled jobs whose next call time is equal to the current simulation time [@ref ScheduledJobQueue]
            -# Call call_next_job(Trick::JobData * curr_job, Trick::ScheduledJobQueue & job_queue, bool rt_nap, long long curr_time_tics)
    -# Switch if the child is a asynchronous must finish thread
        -# Do while the job queue time is less than the time of the next AMF sync time.
            -# For each scheduled jobs whose next call time is equal to the current queue time
                -# Call call_next_job(Trick::JobData * curr_job, Trick::ScheduledJobQueue & job_queue, bool rt_nap, long long curr_time_tics)
    -# Switch if the child is a asynchronous thread
        -# For each scheduled jobs 
            -# Call call_next_job(Trick::JobData * curr_job, Trick::ScheduledJobQueue & job_queue, bool rt_nap, long long curr_time_tics)
    -# Set the child complete flag
*/
void * Trick::Threads::thread_body() {

    /* Lock the go mutex so the master has to wait until this child is ready before staring execution. */
    pthread_mutex_lock(&go_mutex);

    /* signal the master that the child is ready and running */
    child_complete = true;
    running = true ;

    try {
        do {

            /* Block child on go mutex or frame trigger until master signals. */
            if (rt_semaphores == true) {
                pthread_cond_wait(&go_cv, &go_mutex);
            } else {
                /* Else the child process frame is being started when a shared memory flag... */
                while (frame_trigger == false) {} ;
                frame_trigger = false ;
            }

            if ( enabled ) {

                switch ( process_type ) {
                    case PROCESS_TYPE_SCHEDULED:
                    /* Loop through all jobs currently scheduled to run at this simulation time step. */
                    job_queue.reset_curr_index() ;
                    job_queue.set_next_job_call_time(TRICK_MAX_LONG_LONG) ;
                    while ( (curr_job = job_queue.find_next_job( curr_time_tics )) != NULL ) {
                        call_next_job(curr_job, job_queue, rt_nap, curr_time_tics) ;
                    }
                    break ;

                    case PROCESS_TYPE_AMF_CHILD:
                    /* call the AMF top of frame jobs */
                    top_of_frame_queue.reset_curr_index() ;
                    while ( (curr_job = top_of_frame_queue.get_next_job()) != NULL ) {
                        int ret ;
                        ret = curr_job->call() ;
                        if ( ret != 0 ) {
                            exec_terminate_with_return(ret , curr_job->name.c_str() , 0 , " top_of_frame job did not return 0") ;
                        }
                    }

                    /* Loop through all jobs currently up to the point of the next AMF frame sync */
                    do {
                        job_queue.reset_curr_index() ;
                        job_queue.set_next_job_call_time(amf_next_tics) ;
                        while ( (curr_job = job_queue.find_next_job( curr_time_tics )) != NULL ) {
                            call_next_job(curr_job, job_queue, rt_nap, curr_time_tics) ;
                        }
                        curr_time_tics = job_queue.get_next_job_call_time() ;
                    } while ( curr_time_tics < amf_next_tics ) ;

                    /* call the AMF end of frame jobs */
                    end_of_frame_queue.reset_curr_index() ;
                    while ( (curr_job = end_of_frame_queue.get_next_job()) != NULL ) {
                        int ret ;
                        ret = curr_job->call() ;
                        if ( ret != 0 ) {
                            exec_terminate_with_return(ret , curr_job->name.c_str() , 0 , " end_of_frame job did not return 0") ;
                        }
                    }
                    break ;

                    case PROCESS_TYPE_ASYNC_CHILD:
                    /* Loop through all jobs once */
                    if ( amf_cycle_tics == 0 ) {
                        // Old behavior, run all jobs once and return.
                        job_queue.reset_curr_index() ;
                        job_queue.set_next_job_call_time(TRICK_MAX_LONG_LONG) ;
                        while ( (curr_job = job_queue.get_next_job()) != NULL ) {
                            call_next_job(curr_job, job_queue, rt_nap, curr_time_tics) ;
                        }
                    } else {

                        // catch up job next times to current frame.
                        job_queue.reset_curr_index() ;
                        while ( (curr_job = job_queue.get_next_job()) != NULL ) {
                            long long start_frame = amf_next_tics - amf_cycle_tics ;
                            while ( curr_job->next_tics < start_frame ) {
                                curr_job->next_tics += curr_job->cycle_tics ;
                            }
                        }

                        // New behavior, run a mini scheduler.
                        /* call the AMF top of frame jobs */
                        top_of_frame_queue.reset_curr_index() ;
                        while ( (curr_job = top_of_frame_queue.get_next_job()) != NULL ) {
                            int ret ;
                            ret = curr_job->call() ;
                            if ( ret != 0 ) {
                                exec_terminate_with_return(ret , curr_job->name.c_str() , 0 , " top_of_frame job did not return 0") ;
                            }
                        }

                        /* Loop through all jobs currently up to the point of the next AMF frame sync */
                        do {
                            job_queue.reset_curr_index() ;
                            job_queue.set_next_job_call_time(amf_next_tics) ;
                            while ( (curr_job = job_queue.find_next_job( curr_time_tics )) != NULL ) {
                                call_next_job(curr_job, job_queue, rt_nap, curr_time_tics) ;
                            }
                            curr_time_tics = job_queue.get_next_job_call_time() ;
                        } while ( curr_time_tics < amf_next_tics ) ;

                        /* call the AMF end of frame jobs */
                        end_of_frame_queue.reset_curr_index() ;
                        while ( (curr_job = end_of_frame_queue.get_next_job()) != NULL ) {
                            int ret ;
                            ret = curr_job->call() ;
                            if ( ret != 0 ) {
                                exec_terminate_with_return(ret , curr_job->name.c_str() , 0 , " end_of_frame job did not return 0") ;
                            }
                        }
                    }
                    break ;

                    default:
                    break ;
                }
            }

            /* After all jobs have completed, set the child_complete flag to true. */
            child_complete = true;

        } while (1);
    } catch (Trick::ExecutiveException & ex ) {
        fprintf(stderr, "\nCHILD THREAD %d TERMINATED with exec_terminate\n  ROUTINE: %s\n  DIAGNOSTIC: %s\n"
         "  THREAD STOP TIME: %f\n" ,
         thread_id, ex.file.c_str(), ex.message.c_str(), exec_get_sim_time()) ;
        exit(ex.ret_code) ;
    } catch (const std::exception &ex) {
        std::string except_file ;
        if ( curr_job != NULL ) {
            except_file = curr_job->name ;
        } else {
            except_file = "somewhere in Executive::run" ;
        }
        fprintf(stderr, "\nCHILD THREAD %d TERMINATED with exec_terminate\n  ROUTINE: %s\n  DIAGNOSTIC: %s\n"
         "  THREAD STOP TIME: %f\n" ,
         thread_id, except_file.c_str() , ex.what(), exec_get_sim_time()) ;
        exit(-1) ;
#ifdef __linux
#ifdef __GNUC__
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 2
    // for post gcc 4.1.2
    } catch (abi::__forced_unwind&) {
        //pthread_exit and pthread_cancel will cause an abi::__forced_unwind to be thrown. Rethrow it.
        throw;
#endif
#endif
#endif
    } catch (...) {
        /*
           In gcc 4.1.2 I cannot find the catch type for the pthread_cancel forced_unwind exception so I changed
           the catch here to just rethrow all unknown exceptions.  For the other architectures
           we signal the main thread for an orderly shutdown.
         */
#ifdef __linux
#ifdef __GNUC__
#if __GNUC__ == 4 && __GNUC_MINOR__ == 1
        throw;
#else
        std::string except_file ;
        std::string except_message ;
        if ( curr_job != NULL ) {
            except_file = curr_job->name ;
        } else {
            except_file = "somewhere in Executive::run" ;
        }
        except_message = "unknown error" ;
        fprintf(stderr, "\nExecutive::loop terminated with unknown exception\n  ROUTINE: %s\n  DIAGNOSTIC: %s\n"
         "  STOP TIME: %f\n" , except_file.c_str() , except_message.c_str() , exec_get_sim_time()) ;
        exit(-1) ;
#endif
#endif
#endif
    }

    pthread_exit(NULL) ;
    return 0 ;
}
Ejemplo n.º 7
0
bool Trick::IPPythonEvent::process_user_event( long long curr_time ) {

    int ii ;
    int return_val ;
    bool it_fired, it_ran;

    fired = false ;
    ran = false ;
    /** @li No need to evaluate any conditions if in manual mode. */
    if (! manual) {
        hold = false ;
        /** @li Loop thru all conditions. */
        for (ii=0; ii<condition_count; ii++) {
            /** @li Skip condition if it's been disabled. */
            if (! condition_list[ii]->enabled ) {
                condition_list[ii]->fired = false ;
                continue ;
            }
            /** @li No need to evaluate condition if previously fired and hold is on. */
            if (condition_list[ii]->hold && condition_list[ii]->fired) {
                ;
            } else {
                /** @li Evaluate the condition and set its fired state. */
                condition_list[ii]->fired = false ;
                return_val = 0 ;
                if (condition_list[ii]->ref != NULL) {
                // if it's a variable, get it as a boolean
                    if ( condition_list[ii]->ref->pointer_present ) {
                        condition_list[ii]->ref->address = follow_address_path(condition_list[ii]->ref) ;
                    }
                    if ( condition_list[ii]->ref->address != NULL ) {
                        return_val = *(bool *)condition_list[ii]->ref->address ;
                    }
                } else if (condition_list[ii]->job != NULL) {
                // if it's a job, get its return value
                    bool save_disabled_state = condition_list[ii]->job->disabled;
                    condition_list[ii]->job->disabled = false;
                    return_val = condition_list[ii]->job->call();
                    condition_list[ii]->job->disabled = save_disabled_state;
                } else {
                // otherwise use python to evaluate string
                    std::string full_in_string ;
                    ip->parse_condition(condition_list[ii]->str, return_val) ;
                }
                if (return_val) {
                //TODO: write to log/send_hs that trigger fired
                    condition_list[ii]->fired = true ;
                    condition_list[ii]->fired_count++ ;
                    condition_list[ii]->fired_time = curr_time ;
                }
            } // end evaluate condition
            /** @li If cond_all is true, only set event fired/hold after all enabled conditions evaluated. */
            if (ii==0) {
                fired = condition_list[ii]->fired ;
                hold  = condition_list[ii]->hold ;
            }  else {
                if (cond_all) {
                    fired &= condition_list[ii]->fired ;
                    hold  &= condition_list[ii]->hold ;
                } else {
                    fired |= condition_list[ii]->fired ;
                    hold  |= condition_list[ii]->hold ;
                }
            }
        } //end condition loop
    }
    it_fired = manual_fired || fired ;
    /** @li Set the event's fired state...cond_all: if all conditions fired , otherwise if any condition fired. */
    if (it_fired) {
        fired_count++ ;
        fired_time = curr_time ;
        if (info_msg) {
            message_publish( MSG_INFO , "%12.6f Event %s fired.\n" , exec_get_sim_time() , name.c_str()) ;
        }
        if (!manual_fired) {
            active = false ;
        }
    }

    /** @li If the user specified any actions, run them here if a condition fired or manually fired. */
    it_ran = false ;
    if (it_fired && (action_count > 0)) {
        /** @li Loop thru all actions. */
        for (ii=0; ii<action_count; ii++) {
            /** @li No need to run action if it's been disabled. */
            if (! action_list[ii]->enabled ) {
                action_list[ii]->ran = false ;
                continue ;
            }
            /** @li Run the action and set its ran state. */
            if (action_list[ii]->job != NULL) {
            // if it's a job, do what the action type tells you
                switch (action_list[ii]->act_type) {
                    case 0 : // python, should not get here
                        break;
                    case 1 : // On
                        action_list[ii]->job->disabled = false;
                        break;
                    case 2 : // Off
                        action_list[ii]->job->disabled = true;
                        break;
                    case 3 : // Call
                        bool save_disabled_state = action_list[ii]->job->disabled;
                        action_list[ii]->job->disabled = false;
                        action_list[ii]->job->call();
                        action_list[ii]->job->disabled = save_disabled_state;
                        break;
                }
            } else {
            // otherwise use python to evaluate string
                ip->parse(action_list[ii]->str) ;
            }
            it_ran = true ;
            action_list[ii]->ran = true ;
            action_list[ii]->ran_count++ ;
            action_list[ii]->ran_time = curr_time ;
            ran = true ;
        }
        /** @li Leave event fired state on if hold is on. */
        manual_fired &= hold ;
        fired &= hold ;
    }
    /** @li Set the event's ran state if any actions were run. */
    if (it_ran) {
        ran_count++ ;
        ran_time = curr_time ;
    }

    /** @li Return true if the event fired. */
    return(it_fired) ;
}