JITEvents are not checkpointable

Changed the way JITEvents are created and handled. Instead of taking a function pointer directly we save a name of a function to the JITEvent class.  The class will dynamically look up a function that matches the name both during event creation and during checkpoint restart.

Fixes #53
This commit is contained in:
Alex Lin 2015-05-14 13:41:17 -05:00
parent eb46419951
commit 24fe5adaec
8 changed files with 108 additions and 27 deletions

View File

@ -21,4 +21,4 @@ S_sie.resource
S_source.cpp
S_source.hh
trick
jitlib

View File

@ -12,6 +12,7 @@ LIBRARY DEPENDENCY:
#include <iostream>
#include <string>
#include "sim_services/include/mm_macros.hh"
#include "sim_services/EventManager/include/Event.hh"
namespace Trick {
@ -26,8 +27,12 @@ namespace Trick {
*/
class JITEvent : public Trick::Event {
TRICK_MM_FRIENDS(Trick__JITEvent)
public:
JITEvent(int(*in_func_ptr)(void), std::string in_name = "JIT_no_name" , double in_cycle = 1.0) ;
JITEvent() ;
JITEvent(std::string func_name, std::string in_name = "JIT_no_name" , double in_cycle = 1.0) ;
/** calls the function_ptr job */
virtual int process( long long curr_time ) ;
@ -38,13 +43,16 @@ class JITEvent : public Trick::Event {
/** called when the event is removed from the event manager */
virtual void remove() {} ;
virtual void restart() {} ;
virtual void restart() ;
std::string func_name ;
protected:
void get_func_ptr_from_name() ;
/** pointer to funtion to run when event fires */
int (*func_ptr)(void) ;
int (*func_ptr)(void) ; // trick_io(**)
} ;

View File

@ -8,6 +8,7 @@ LIBRARY DEPENDENCY:
#ifndef JITINPUTFILE_HH
#define JITINPUTFILE_HH
#include <dlfcn.h>
#include <string>
#include <queue>
#include <map>
@ -34,6 +35,8 @@ struct JITLibInfo {
/** handle returned by dlopen to the library */
void * handle ;
void * find_symbol(std::string sym) { return dlsym(handle, sym.c_str()) ; }
} ;
/**
@ -94,6 +97,7 @@ class JITInputFile {
*/
int add_library(std::string lib_name) ;
void * find_symbol(std::string sym) ;
private:
/** C++ input file from the command line if one was specified. */
std::string input_file ;

View File

@ -8,11 +8,12 @@ int jit_compile(std::string file_name) ;
int jit_run(std::string library_name , std::string run_function ) ;
int jit_compile_and_run(std::string file_name, std::string run_function = "run_me" ) ;
int jit_add_library(std::string lib_name) ;
void * jit_find_symbol(std::string sym ) ;
int jit_add_read( unsigned int thread_id , double time , int (*func_ptr)(void) ) ;
int jit_add_read( double time , int (*func_ptr)(void) ) ;
int jit_add_event( int (*func_ptr)(void), std::string name , double cycle ) ;
int jit_add_event_before( int (*func_ptr)(void), std::string name , std::string target_name , unsigned int target_inst = 1 ) ;
int jit_add_event_after( int (*func_ptr)(void), std::string name , std::string target_name , unsigned int target_inst = 1 ) ;
int jit_add_read( unsigned int thread_id , double time , std::string func_name ) ;
int jit_add_read( double time , std::string func_name ) ;
int jit_add_event( std::string func_name , std::string name , double cycle ) ;
int jit_add_event_before( std::string func_name , std::string name , std::string target_name , unsigned int target_inst = 1 ) ;
int jit_add_event_after( std::string func_name , std::string name , std::string target_name , unsigned int target_inst = 1 ) ;
#endif

View File

@ -1,19 +1,54 @@
#include "sim_services/JITInputFile/include/JITEvent.hh"
#include "sim_services/JITInputFile/include/jit_input_file_proto.hh"
#include "sim_services/Executive/include/exec_proto.h"
#include "sim_services/Message/include/message_proto.h"
Trick::JITEvent::JITEvent(int (*in_func_ptr)(void), std::string in_name , double in_cycle ) :
Trick::Event(in_name, in_cycle),
func_ptr(in_func_ptr) {
// Default constructor used by Trick for checkpoints.
Trick::JITEvent::JITEvent() :
func_ptr(NULL) {
active = false ;
}
Trick::JITEvent::JITEvent(std::string in_func_name , std::string in_name , double in_cycle ) :
Trick::Event(in_name, in_cycle) ,
func_name(in_func_name) {
// Set active to true by default for all JITEvents
active = true ;
}
get_func_ptr_from_name() ;
}
/**
@details
-# call the function and return it's return value.
*/
int Trick::JITEvent::process( long long curr_time __attribute__ ((unused)) ) {
return (*func_ptr)() ;
if ( func_ptr != NULL ) {
return (*func_ptr)() ;
}
return 1 ;
}
/**
@details
-# Get the function pointer associated with this event.
*/
void Trick::JITEvent::restart() {
get_func_ptr_from_name() ;
}
/**
@details
-# If func_name is not empty
-# Get the function pointer associated with the func_name
-# If the function is not found
-# Print an error message saying we can't find the function
*/
void Trick::JITEvent::get_func_ptr_from_name() {
if ( ! func_name.empty() ) {
func_ptr = (int (*)(void))jit_find_symbol(func_name) ;
if ( func_ptr == NULL ) {
message_publish( MSG_WARNING, "JITEvent could not find function named %s", func_name.c_str() ) ;
}
}
}

View File

@ -24,8 +24,16 @@
Trick::JITInputFile * the_jit = NULL ;
//TODO: Move JITLibInfo code into the JITLibInfo object.
Trick::JITInputFile::JITInputFile() {
the_jit = this ;
JITLibInfo li ;
li.library_name = "S_main" ;
li.handle = dlopen( NULL , RTLD_LAZY ) ;
file_to_libinfo_map["S_main"] = li ;
}
/**
@ -246,11 +254,23 @@ int Trick::JITInputFile::add_library(std::string lib_name) {
// Add library name to map
JITLibInfo li ;
li.library_name = lib_name ;
li.handle = dlopen( li.library_name.c_str() , RTLD_LAZY ) ;
file_to_libinfo_map[lib_name] = li ;
return 0 ;
}
void * Trick::JITInputFile::find_symbol(std::string sym) {
std::map< std::string , JITLibInfo >::iterator it ;
for ( it = file_to_libinfo_map.begin() ; it != file_to_libinfo_map.end() ; it++ ) {
void * ret = (*it).second.find_symbol(sym) ;
if (ret != NULL) {
return ret ;
}
}
return NULL ;
}
/**
@details
-# Call compile_and_run with the input_file from the command line

View File

@ -35,28 +35,40 @@ int jit_add_library(std::string lib_name ) {
return -1 ;
}
int jit_add_read( unsigned int thread_id , double in_time , int (*func_ptr)(void) ) {
Trick::JITEvent * event = new Trick::JITEvent(func_ptr, "jit_read_event" , 0) ;
void * jit_find_symbol(std::string sym ) {
if ( the_jit != NULL ) {
return the_jit->find_symbol(sym) ;
}
return NULL ;
}
int jit_add_read( unsigned int thread_id , double in_time , std::string func_name ) {
Trick::JITEvent * event = (Trick::JITEvent *)TMM_declare_var_1d("Trick::JITEvent", 1) ;
new (event) Trick::JITEvent(func_name, "jit_read_event" , 0) ;
event->set_thread(thread_id) ;
event->set_next_tics((long long)round(in_time * exec_get_time_tic_value())) ;
return event_manager_add_event(event) ;
}
int jit_add_read( double in_time , int (*func_ptr)(void) ) {
return jit_add_read( 0 , in_time , func_ptr) ;
int jit_add_read( double in_time , std::string func_name) {
return jit_add_read( 0 , in_time , func_name) ;
}
int jit_add_event( int (*func_ptr)(void), std::string name , double cycle ) {
Trick::JITEvent * my_event = new Trick::JITEvent( func_ptr, name , cycle ) ;
return event_manager_add_event(my_event) ;
int jit_add_event( std::string func_name, std::string name , double cycle ) {
Trick::JITEvent * event = (Trick::JITEvent *)TMM_declare_var_1d("Trick::JITEvent", 1) ;
new (event) Trick::JITEvent(func_name , name , cycle ) ;
return event_manager_add_event(event) ;
}
int jit_add_event_before( int (*func_ptr)(void), std::string name , std::string target_name , unsigned int target_inst ) {
Trick::JITEvent * my_event = new Trick::JITEvent( func_ptr, name ) ;
return event_manager_add_event_before(my_event, target_name , target_inst) ;
int jit_add_event_before( std::string func_name , std::string name , std::string target_name , unsigned int target_inst ) {
Trick::JITEvent * event = (Trick::JITEvent *)TMM_declare_var_1d("Trick::JITEvent", 1) ;
new (event) Trick::JITEvent(func_name , name ) ;
return event_manager_add_event_before(event, target_name , target_inst) ;
}
int jit_add_event_after( int (*func_ptr)(void), std::string name , std::string target_name , unsigned int target_inst ) {
Trick::JITEvent * my_event = new Trick::JITEvent( func_ptr, name ) ;
return event_manager_add_event_after(my_event, target_name , target_inst) ;
int jit_add_event_after( std::string func_name, std::string name , std::string target_name , unsigned int target_inst ) {
Trick::JITEvent * event = (Trick::JITEvent *)TMM_declare_var_1d("Trick::JITEvent", 1) ;
new (event) Trick::JITEvent(func_name , name ) ;
return event_manager_add_event_after(event, target_name , target_inst) ;
}

View File

@ -15,6 +15,7 @@
#include "sim_services/InputProcessor/include/IPPython.hh"
#include "sim_services/InputProcessor/include/IPPythonEvent.hh"
#include "sim_services/InputProcessor/include/MTV.hh"
#include "sim_services/JITInputFile/include/JITEvent.hh"
#include "sim_services/JITInputFile/include/JITInputFile.hh"
#include "sim_services/JSONVariableServer/include/JSONVariableServer.hh"
#include "sim_services/JSONVariableServer/include/JSONVariableServerThread.hh"