Commit 68da4f12 authored by Georg Kunz's avatar Georg Kunz

[master] enable endSimulation() from threaded context

parent b781545c
......@@ -126,6 +126,8 @@ class SIM_API cSimulation : public cNamedObject, noncopyable
cStopWatch sequentialWatch;
bool endSimulation; // used to signal shutdown from threaded context
private:
// internal
void checkActive() {if (getActiveSimulation()!=this) throw cRuntimeError(this, eWRONGSIM);}
......@@ -389,6 +391,11 @@ class SIM_API cSimulation : public cNamedObject, noncopyable
* all modules and deleting the messages in the scheduled-event list.
*/
void deleteNetwork();
/**
* signal shutdown from thread
*/
void signalShutdown() { endSimulation = true; }
//@}
/** @name Information about the current simulation run. */
......
......@@ -106,6 +106,8 @@ Register_GlobalConfigOption(CFGID_DEBUG_ON_ERRORS, "debug-on-errors", CFG_BOOL,
Register_GlobalConfigOption(CFGID_PRINT_UNDISPOSED, "print-undisposed", CFG_BOOL, "true", "Whether to report objects left (that is, not deallocated by simple module destructors) after network cleanup.");
Register_GlobalConfigOption(CFGID_SIMTIME_SCALE, "simtime-scale", CFG_INT, "-12", "Sets the scale exponent, and thus the resolution of time for the 64-bit fixed-point simulation time representation. Accepted values are -18..0; for example, -6 selects microsecond resolution. -12 means picosecond resolution, with a maximum simtime of ~110 days.");
Register_GlobalConfigOption(CFGID_NED_PATH, "ned-path", CFG_PATH, "", "A semicolon-separated list of directories. The directories will be regarded as roots of the NED package hierarchy, and all NED files will be loaded from their subdirectory trees. This option is normally left empty, as the OMNeT++ IDE sets the NED path automatically, and for simulations started outside the IDE it is more convenient to specify it via a command-line option or the NEDPATH environment variable.");
Register_GlobalConfigOption(CFGID_WRITE_RUNTIME_TO_FILE, "write-runtime-to-file", CFG_BOOL, "false", "Enables or disables writing of the simulation runtime to file.");
Register_GlobalConfigOption(CFGID_WRITE_RUNTIME_TO_FILENAME, "write-runtime-to-filename", CFG_STRING, "runtimes.dat", "Defines the name of the file in which the runtimes are stored.");
Register_PerRunConfigOption(CFGID_NETWORK, "network", CFG_STRING, NULL, "The name of the network to be simulated. The package name can be omitted if the ini file is in the same directory as the NED file that contains the network.");
Register_PerRunConfigOption(CFGID_WARNINGS, "warnings", CFG_BOOL, "true", "Enables warnings.");
......@@ -1673,6 +1675,16 @@ void EnvirBase::stopClock()
gettimeofday(&simendtime, NULL);
elapsedtime = elapsedtime + simendtime - laststarted;
simulatedtime = simulation.getSimTime();
bool storeRuntimes = getConfig()->getAsBool(CFGID_WRITE_RUNTIME_TO_FILE);
if (storeRuntimes)
{
std::string filename = getConfig()->getAsString(CFGID_WRITE_RUNTIME_TO_FILENAME);
std::ofstream outfile;
outfile.open(filename.c_str(), std::ios::out | std::ios::app);
outfile << elapsedtime.tv_sec << "." << (elapsedtime.tv_usec/1000) << endl;
outfile.close();
}
}
timeval EnvirBase::totalElapsed()
......
......@@ -731,7 +731,10 @@ void cSimpleModule::handleMessage(cMessage *)
void cSimpleModule::endSimulation()
{
throw cTerminationException(eENDSIM);
// throwing an exception from a worker thread is not caught and the simulation
// is not cleanly shut down. Workaround: signal shutdown directly to scheduler
//throw cTerminationException(eENDSIM);
simulation.signalShutdown();
}
bool cSimpleModule::snapshot(cObject *object, const char *label)
......
......@@ -75,7 +75,8 @@ Register_PerRunConfigOption(CFGID_SIMUL_THREADPOOL_SIZE, "thread-pool-size", CFG
cSimulation::cSimulation(const char *name, cEnvir *env) :
cNamedObject(name, false), isrunning(false)
cNamedObject(name, false), isrunning(false),
endSimulation(false)
{
ASSERT(cStaticFlag::isSet()); // cannot be instantiated as global variable
......@@ -649,6 +650,10 @@ void cSimulation::doOneEvent(cMessage* msg)
try
{
// a worker signaled to shutdown the simulation
if(endSimulation)
throw cTerminationException(eENDSIM);
// update the number of events that occur at the same simtime
simtime_t currentTime = cThreadPool::getSimTime();
if (currentTime < msg->getArrivalTime())
......
......@@ -56,7 +56,7 @@ static __thread cThreadLocalData* localData = NULL;
cThreadPool::cThreadPool() :
shutdownDone(false)
shutdownDone(false)
{
}
......@@ -67,12 +67,12 @@ cThreadPool::~cThreadPool()
static void* startWorker(void* arg)
{
{
cThreadPool* pool = (cThreadPool*)arg;
pool->worker();
return NULL;
}
}
void cThreadPool::activate()
......@@ -217,7 +217,7 @@ void cThreadPool::setContext(cComponent* mod)
cThreadLocalData::cThreadLocalData() :
defaultOwner(NULL)
defaultOwner(NULL)
{
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment