diff --git a/VERSION.txt b/VERSION.txt index f2a72c157..5d5656576 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.20260723.1 +1.20260723.2 diff --git a/src/support/cellml/cellmlfile.cpp b/src/support/cellml/cellmlfile.cpp index ed01f8136..d8654b3ba 100644 --- a/src/support/cellml/cellmlfile.cpp +++ b/src/support/cellml/cellmlfile.cpp @@ -27,8 +27,20 @@ limitations under the License. #include "libopencor/solvercvode.h" #include "libopencor/solverkinsol.h" +#include +#include + namespace libOpenCOR { +namespace { + +// Cache of compiled runtimes, keyed by CellmlFile pointer. + +std::mutex sRuntimesMutex; // NOLINT +std::unordered_map sRuntimes; // NOLINT + +} // namespace + CellmlFile::Impl::Impl(const FilePtr &pFile, const libcellml::ModelPtr &pModel, bool pStrict) : mFile(pFile) , mModel(pModel) @@ -116,7 +128,28 @@ libcellml::AnalyserModelPtr CellmlFile::Impl::analyserModel() const CellmlFileRuntimePtr CellmlFile::Impl::runtime(const CellmlFilePtr &pCellmlFile, const SolverNlaPtr &pNlaSolver) { - return CellmlFileRuntime::create(pCellmlFile, pNlaSolver); + // Check whether we already have a compiled runtime and if so then return it. + + { + const std::scoped_lock lock(sRuntimesMutex); + const auto it = sRuntimes.find(pCellmlFile.get()); + + if (it != sRuntimes.end()) { + return it->second; + } + } + + // There is no compiled runtime for this CellML file, so create one, track it, and return it. + + auto runtime = CellmlFileRuntime::create(pCellmlFile, pNlaSolver); + + { + const std::scoped_lock lock(sRuntimesMutex); + + sRuntimes.try_emplace(pCellmlFile.get(), runtime); + } + + return runtime; } CellmlFile::CellmlFile(const FilePtr &pFile, const libcellml::ModelPtr &pModel, bool pStrict) @@ -124,6 +157,17 @@ CellmlFile::CellmlFile(const FilePtr &pFile, const libcellml::ModelPtr &pModel, { } +CellmlFile::~CellmlFile() +{ + // Stop tracking our compiled runtime. + + { + const std::scoped_lock lock(sRuntimesMutex); + + sRuntimes.erase(this); + } +} + CellmlFile::Impl *CellmlFile::pimpl() { return static_cast(Logger::mPimpl.get()); diff --git a/src/support/cellml/cellmlfile.h b/src/support/cellml/cellmlfile.h index e0ec93bba..cbc4e5a2b 100644 --- a/src/support/cellml/cellmlfile.h +++ b/src/support/cellml/cellmlfile.h @@ -46,6 +46,7 @@ class LIBOPENCOR_UNIT_TESTING_EXPORT CellmlFile: public Logger { public: CellmlFile() = delete; + ~CellmlFile() override; CellmlFile(const CellmlFile &pOther) = delete; CellmlFile(CellmlFile &&pOther) noexcept = delete;