00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Component/JobServerConfigurator.H"
00039 #include "Component/ModelManager.H"
00040 #include "Image/Image.H"
00041 #include "Image/Pixels.H"
00042 #include "Image/Point2D.H"
00043 #include "Media/SimFrameSeries.H"
00044 #include "Neuro/NeuroOpts.H"
00045 #include "Raster/Raster.H"
00046 #include "Simulation/SimEventQueueConfigurator.H"
00047 #include "Simulation/SimEventQueue.H"
00048 #include "Util/AllocAux.H"
00049 #include "Util/Pause.H"
00050 #include "Util/Types.H"
00051 #include "Util/csignals.H"
00052 #include "Util/log.H"
00053 #include "Util/sformat.H"
00054 #include "Util/StringUtil.H"
00055 #include "Util/Timer.H"
00056 #include "rutz/trace.h"
00057
00058 #include <signal.h>
00059 #include <stdio.h>
00060 #include <sys/types.h>
00061 #include <dlfcn.h>
00062
00063 #ifdef HAVE_LIBXML
00064 #include <libxml/parser.h>
00065 #include <libxml/tree.h>
00066 #endif
00067
00068 typedef int mainLoopFunc(const int argc, const char** argv);
00069
00070 mainLoopFunc* loadObject(ModelManager& manager,
00071 const std::string& libFile,
00072 const std::string& name,
00073 const std::string& mainOverrideName = "")
00074 {
00075 void* libPtr = dlopen(libFile.c_str(), RTLD_NOW | RTLD_GLOBAL);
00076 if (!libPtr)
00077 LFATAL("Can not load library: %s (%s)", libFile.c_str(), dlerror());
00078
00079 std::string modInstFuncName = "createModule" + name;
00080 dlerror();
00081 createSimEventModule* createObj = (createSimEventModule*) dlsym(libPtr, modInstFuncName.c_str());
00082
00083 if (!createObj)
00084 LFATAL("Can not find the %s symbol: %s. \nCheck the module Name", modInstFuncName.c_str(), dlerror());
00085
00086 mainLoopFunc* mainLoop = NULL;
00087 if(mainOverrideName != "")
00088 {
00089 dlerror();
00090 mainLoop = (mainLoopFunc*) dlsym(libPtr, mainOverrideName.c_str());
00091 if(!mainLoop)
00092 LFATAL("Can not find mainLoop symbol (%s): %s. \nCheck the module Name", mainOverrideName.c_str(), dlerror());
00093
00094 }
00095
00096 nub::ref<SimModule> obj = createObj(manager);
00097 manager.addSubComponent(obj);
00098
00099
00100
00101 return mainLoop;
00102 }
00103
00104 void getNodeMatchText(xmlDocPtr doc, xmlNodePtr nodePtr,
00105 const char* nodeName, std::string &result)
00106 {
00107 xmlChar *tmp = NULL;
00108 if (!xmlStrcmp(nodePtr->name, (const xmlChar *)nodeName))
00109 tmp = xmlNodeListGetString(doc, nodePtr->xmlChildrenNode, 1);
00110
00111 if (tmp != NULL) {
00112 result = std::string((const char*)tmp);
00113 xmlFree(tmp);
00114 }
00115 }
00116
00117 mainLoopFunc* configModules(const char* xmlFile, ModelManager& manager,
00118 const int argc, const char **argv, bool skipFirstArgs)
00119 {
00120 std::vector<const char*> argvals;
00121
00122 int argcnt=0;
00123
00124 for(int i=0; i<argc; i++)
00125 {
00126 if (skipFirstArgs && (i==1) ) continue;
00127 argvals.push_back(argv[i]);
00128 argcnt++;
00129 }
00130
00131
00132
00133 xmlDocPtr doc = xmlReadFile(xmlFile, NULL, 0);
00134 if (doc == NULL) {
00135 LFATAL("Failed to parse %s", xmlFile);
00136 }
00137
00138
00139 xmlNode *root_element = xmlDocGetRootElement(doc);
00140
00141
00142 xmlNodePtr cur = root_element;
00143
00144
00145 if ((!xmlStrcmp(cur->name, (const xmlChar *)"SimModules")))
00146 cur = root_element->xmlChildrenNode;
00147
00148 mainLoopFunc* mainLoop = NULL;
00149
00150 while (cur != NULL) {
00151 if ((!xmlStrcmp(cur->name, (const xmlChar *)"Module"))) {
00152
00153 xmlNodePtr modulePtr = cur->xmlChildrenNode;
00154
00155 std::string name, location, mainLoopFuncName;
00156
00157 while(modulePtr != NULL) {
00158 getNodeMatchText(doc, modulePtr, "Name", name);
00159 getNodeMatchText(doc, modulePtr, "Location", location);
00160 getNodeMatchText(doc, modulePtr, "MainLoop", mainLoopFuncName);
00161
00162
00163 if ((!xmlStrcmp(modulePtr->name, (const xmlChar *)"Args"))) {
00164 xmlNodePtr argPtr = modulePtr->xmlChildrenNode;
00165
00166 while(argPtr != NULL)
00167 {
00168
00169 if ((!xmlStrcmp(argPtr->name, (const xmlChar *)"arg"))) {
00170 xmlChar* name = xmlGetProp(argPtr, (const xmlChar*)"name");
00171 xmlChar* value = xmlGetProp(argPtr, (const xmlChar*)"value");
00172
00173 std::string arg = "--" + std::string((const char*)name) +
00174 "=" + std::string((const char*)value);
00175 argvals.push_back(strdup(arg.c_str()));
00176 argcnt++;
00177
00178 xmlFree(name);
00179 xmlFree(value);
00180 }
00181 argPtr = argPtr->next;
00182 }
00183
00184 }
00185
00186 modulePtr = modulePtr->next;
00187 }
00188
00189 mainLoopFunc* tmpMainLoop = loadObject(manager, location, name, mainLoopFuncName);
00190 if(tmpMainLoop)
00191 {
00192 if(!mainLoop)
00193 mainLoop = tmpMainLoop;
00194 else
00195 LFATAL("ERROR! Two Main Loops Defined In XML!");
00196 }
00197
00198 }
00199 cur = cur->next;
00200 }
00201 xmlFreeDoc(doc);
00202 xmlCleanupParser();
00203
00204 if (manager.parseCommandLine(
00205 (const int)argcnt, &argvals[0], "", 0, 0) == false)
00206 LFATAL("Bad Arguments!");
00207
00208 return mainLoop;
00209 }
00210
00211 volatile int signum = 0;
00212
00213 void* RunSimOS(void* seq_p)
00214 {
00215 nub::ref<SimEventQueue> seq = *((nub::ref<SimEventQueue>*)seq_p);
00216
00217 PauseWaiter p;
00218 SimStatus status = SIM_CONTINUE;
00219
00220 Timer timer;
00221
00222 while(status == SIM_CONTINUE)
00223 {
00224
00225 if (p.checkPause()) continue;
00226
00227 if (signum != 0) {
00228 char msg[255];
00229 snprintf(msg, 255, "quitting because %s was caught", signame(signum));
00230 LINFO("%s", msg);
00231 seq->post(rutz::make_shared(new SimEventBreak(seq.get(), msg)));
00232 status = seq->evolve();
00233 break;
00234 }
00235
00236 status = seq->evolve();
00237 }
00238 pthread_exit(NULL);
00239 }
00240
00241 int main(const int argc, const char **argv)
00242 {
00243
00244
00245
00246
00247
00248
00249 catchsignals(&signum);
00250
00251 MYLOGVERB = LOG_INFO;
00252 ModelManager manager("SimEvent Kernel");
00253
00254 nub::ref<SimEventQueueConfigurator>
00255 seqc(new SimEventQueueConfigurator(manager));
00256 manager.addSubComponent(seqc);
00257
00258
00259 REQUEST_OPTIONALIAS_NEURO(manager);
00260
00261 std::string xmlFile = std::string(getenv("HOME")) + "/.SimEventOS.xml";
00262
00263 mainLoopFunc* mainLoop = NULL;
00264 if (argc > 1)
00265 {
00266 if (argv[1][0] != '-')
00267 mainLoop = configModules(argv[1], manager, argc, argv, true);
00268 else
00269 mainLoop = configModules(xmlFile.c_str(), manager, argc, argv, false);
00270 } else {
00271 mainLoop = configModules(xmlFile.c_str(), manager, argc, argv, false);
00272 }
00273
00274 nub::ref<SimEventQueue> seq = seqc->getQ();
00275
00276 manager.start();
00277
00278
00279 seq->printCallbacks();
00280
00281
00282
00283 pthread_t SimOSThread;
00284 int rc = pthread_create(&SimOSThread, NULL, RunSimOS, (void*)(&seq));
00285
00286
00287 if(mainLoop)
00288 rc = mainLoop(argc, argv);
00289
00290
00291 void* status;
00292 rc = pthread_join(SimOSThread, &status);
00293
00294
00295 LINFO("Simulation terminated.");
00296
00297
00298 manager.stop();
00299
00300 return rc;
00301 }