diff --git a/FMU_Engine/FMU_Engine/FMUEngine.cpp b/FMU_Engine/FMU_Engine/FMUEngine.cpp
index 424d6ec5b643e521d6505b320a51f23e24e22821..639821ee0f698ea46c8fa7342596b0331718692e 100644
--- a/FMU_Engine/FMU_Engine/FMUEngine.cpp
+++ b/FMU_Engine/FMU_Engine/FMUEngine.cpp
@@ -22,19 +22,13 @@ namespace Simulation
_controlerId(id), _sendValuesCallback(valuesCallback), _logCallback(_logCallback)
{}
- DWORD WINAPI FmuEngine::staticSimThreadStart(void* instance)
- {
- FmuEngine* engine = (FmuEngine*)instance;
- return engine->simulate();
- }
- DWORD FmuEngine::simulate(void)
+ void FmuEngine::simulate()
{
// Time measuring
LARGE_INTEGER frequency, startCount, currentCount;
if (!QueryPerformanceFrequency(&frequency))
{
_logCallback("FmuEngine", "Precision timer nor available.");
- return 1;
}
std::string freqString = "PerformanceFrequency: " + std::to_string(frequency.QuadPart) + "1/sec";
std::cout << freqString << std::endl;
@@ -85,7 +79,6 @@ namespace Simulation
}
// Lower the accurracy when leaving
timeEndPeriod(1);
- return 0;
}
void FmuEngine::performChannelLinks()
{
@@ -189,26 +182,27 @@ namespace Simulation
}
}
- FResult FmuEngine::startSimulationThread()
+ FResult FmuEngine::startSimulation()
{
// Play from initialized or stopped state
if (!_simulating)
{
- // Make the fmus ready
for (auto &pair : _fmus)
{
Fmu &fmu = pair.second;
- // Exit the mode
+ // Exit the initalizationmode
+ // TODO check current state
fmi2Status status = fmu.ExitInitializationMode();
if (!(status == fmi2OK || status == fmi2Warning))
{
- return{ status, "Initialization failed, instance: " + fmu.GetInstanceName() };
+ _logCallback(fmu.GetInstanceName(), "ExitInitializationMode failed");
+ return{ status, "ExitInitializationMode failed, instance: " + fmu.GetInstanceName() };
}
}
// Start simulating
_simulating = true;
// Create new thread for the simulation
- _simThreadHandle = CreateThread(NULL, 0, staticSimThreadStart, (void*) this, 0, &_simThreadID);
+ _simThread = std::thread(&FmuEngine::simulate, this);
}
return{ fmi2OK, "" };
}
@@ -218,14 +212,14 @@ namespace Simulation
// Set endTime as large as possible (~5,67e300 annos)
_endTime_sec = DBL_MAX;
_playFast = false;
- return startSimulationThread();
+ return startSimulation();
}
FResult FmuEngine::PlayFast(double endTime_sec)
{
// Update the _endTime
_endTime_sec = endTime_sec;
_playFast = true;
- return startSimulationThread();
+ return startSimulation();
}
// Stop the simulation thread
FResult FmuEngine::Pause()
@@ -233,7 +227,7 @@ namespace Simulation
// Only try to obtain ownership over the thread without blocking the current thread
_simulating = false;
// Wait until the current run has finished
- WaitForSingleObject(_simThreadHandle, INFINITE);
+ _simThread.join();
return{ fmi2OK,"" };
}
// Stop the thread and reset the simulation
@@ -242,7 +236,7 @@ namespace Simulation
// Stop simulation
_simulating = false;
// Wait until the current run has finished
- WaitForSingleObject(_simThreadHandle, INFINITE);
+ _simThread.join();
// Reset simulation
_currentTime_sec = 0;
diff --git a/FMU_Engine/FMU_Engine/FmuEngine.hpp b/FMU_Engine/FMU_Engine/FmuEngine.hpp
index 9f0cd73bc98d599dc86855ae43146c6659ff0892..e9907a084e10c4812e160cec214fe1d9d003631c 100644
--- a/FMU_Engine/FMU_Engine/FmuEngine.hpp
+++ b/FMU_Engine/FMU_Engine/FmuEngine.hpp
@@ -2,11 +2,11 @@
#include "ChannelLink.h"
#include "templates.hpp"
#include "fmi2FunctionTypes.h"
-#include <memory>
+#include <atomic>
#include <map>
+#include <memory>
+#include <thread>
#include <vector>
-#define WIN32_LEAN_AND_MEAN // We don't want to include winsock.h, causes problems with asio
-#include <windows.h>
#include "boost/optional.hpp"
// Forward declaration
@@ -73,20 +73,17 @@ namespace Simulation
LogCallback _logCallback;
// Execeutes the simulation: DoStep, pushes the values into storage, performes ChannelLinks
- DWORD _simThreadID;
- HANDLE _simThreadHandle;
- bool _simulating; // Use atomic -> while(!_stopSim) will not be compiled to while(true)
- bool _playFast; // Do not sleep when we use the playFast mode
+ std::thread _simThread;
+ std::atomic_bool _simulating; // Use atomic -> while(!_stopSim) will not be compiled to while(true)
+ bool _playFast; // Do not sleep when we use the playFast mode
double _currentTime_sec = 0; // The current simulation timepoint
double _endTime_sec = 0;
const double STEP_SIZE_SEC = 0.01; // Default 10ms
- /// Start the simulation Task (if not already running)
- FResult startSimulationThread();
- /// Static method needed to execute the WINAPI thread
- static DWORD WINAPI staticSimThreadStart(void* instance);
- ///
- DWORD simulate(void);
+ /// Prepares and runs the simulation loop in a new thread
+ FResult startSimulation();
+ /// Simulation loop runs in here
+ void simulate();
void performChannelLinks();
void sendValues();