From 7cd3c926bd8eb42e265b8684c12b939f37061dae Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Thu, 3 Mar 2011 09:06:14 +0100 Subject: [PATCH] ENH: discard codeProperties in favour of using sha1-encoded library names --- .../fixedValueFvPatchScalarFieldTemplate.C | 12 +- src/finiteVolume/Make/files | 1 - .../derived/codedFixedValue/codeProperties.C | 73 ---- .../derived/codedFixedValue/codeProperties.H | 92 ----- .../codedFixedValueFvPatchScalarField.C | 390 +++++++++++------- .../codedFixedValueFvPatchScalarField.H | 32 +- 6 files changed, 275 insertions(+), 325 deletions(-) delete mode 100644 src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.C delete mode 100644 src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.H diff --git a/etc/codeTemplates/dynamicCode/fixedValueFvPatchScalarFieldTemplate.C b/etc/codeTemplates/dynamicCode/fixedValueFvPatchScalarFieldTemplate.C index 4c9d791eaf..9e88840aec 100644 --- a/etc/codeTemplates/dynamicCode/fixedValueFvPatchScalarFieldTemplate.C +++ b/etc/codeTemplates/dynamicCode/fixedValueFvPatchScalarFieldTemplate.C @@ -32,6 +32,7 @@ License ${codeInclude} //}}} end codeInclude + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam @@ -46,9 +47,16 @@ extern "C" // // unique function name that can be checked if the correct library version // has been loaded - bool ${typeName}_${SHA1sum}() + void ${typeName}_${SHA1sum}(bool load) { - return true; + if (load) + { + // code that can be explicitly executed after loading + } + else + { + // code that can be explicitly executed before unloading + } } } diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files index ff57597532..e6f6c26148 100644 --- a/src/finiteVolume/Make/files +++ b/src/finiteVolume/Make/files @@ -115,7 +115,6 @@ $(derivedFvPatchFields)/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorFi $(derivedFvPatchFields)/advective/advectiveFvPatchFields.C $(derivedFvPatchFields)/codedFixedValue/codedFixedValueFvPatchScalarField.C -$(derivedFvPatchFields)/codedFixedValue/codeProperties.C $(derivedFvPatchFields)/directMappedFixedValue/directMappedFixedValueFvPatchFields.C $(derivedFvPatchFields)/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C $(derivedFvPatchFields)/fan/fanFvPatchFields.C diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.C b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.C deleted file mode 100644 index c104d3d71b..0000000000 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.C +++ /dev/null @@ -1,73 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see . - -\*---------------------------------------------------------------------------*/ - -#include "codeProperties.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -defineTypeNameAndDebug(Foam::codeProperties, 0); - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::codeProperties::codeProperties(const IOobject& io) -: - IOdictionary(io), - modified_(true) -{} - - -// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // - -bool Foam::codeProperties::modified() const -{ - modified_ = modified_ || regIOobject::modified(); - - return modified_; -} - - -void Foam::codeProperties::setUnmodified() const -{ - modified_ = false; -} - - -bool Foam::codeProperties::read() -{ - if (regIOobject::read()) - { - modified_ = true; - - return true; - } - else - { - return false; - } -} - - -// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.H b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.H deleted file mode 100644 index f8d855274f..0000000000 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.H +++ /dev/null @@ -1,92 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see . - -Class - Foam::codeProperties - -Description - IOdictionary with an internal flag to explicitly track when a file changed. - -SourceFiles - codeProperties.C - -\*---------------------------------------------------------------------------*/ - -#ifndef codeProperties_H -#define codeProperties_H - -#include "IOdictionary.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class codeProperties Declaration -\*---------------------------------------------------------------------------*/ - -class codeProperties -: - public IOdictionary -{ - // Private data - - //- Monitor file change - mutable bool modified_; - -public: - - // Declare name of the class and its debug switch - ClassName("codeDict"); - - // Constructors - - //- Construct from IOobject - codeProperties(const IOobject&); - - - // Member Functions - - //- A sticky version of regIOobject::modified() - // Must explicitly clear with setUnmodified() - virtual bool modified() const; - - //- Make modification unsticky - void setUnmodified() const; - - //- Read the dictionary - virtual bool read(); - -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C index 8175f1b5ed..3d9ab07523 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C @@ -35,7 +35,6 @@ License #include "SHA1Digest.H" #include "dynamicCode.H" #include "dynamicCodeContext.H" -#include "codeProperties.H" #include "stringOps.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -46,34 +45,184 @@ const Foam::word Foam::codedFixedValueFvPatchScalarField::codeTemplateC const Foam::word Foam::codedFixedValueFvPatchScalarField::codeTemplateH = "fixedValueFvPatchScalarFieldTemplate.H"; +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + + +Foam::string Foam::codedFixedValueFvPatchScalarField::libraryGlobalName +( + const fileName& libPath +) +{ + // global function name (SHA1-encoded) + // that can be used for version control and/or explicit loading/unloading + string globalFuncName = libPath.name(); + + // remove ".so" extension + string::size_type dot = globalFuncName.find('.'); + if (dot != string::npos) + { + globalFuncName.resize(dot); + } + + // remove leading 'lib' from name + globalFuncName.erase(0, 3); + + return globalFuncName; +} + + + + +void* Foam::codedFixedValueFvPatchScalarField::loadLibrary +( + const fileName& libPath, + const string& globalFuncName, + const dictionary& contextDict +) +{ + void* lib = 0; + + // global function name (SHA1-encoded) + // that can be used for version control and/or explicit loading/unloading + + // avoid compilation by loading an existing library + if (dlLibraryTable::open(libPath, false)) + { + lib = dlLibraryTable::findLibrary(libPath); + + // verify the loaded version and unload if needed + if (lib) + { + if (dlSymFound(lib, globalFuncName)) + { + // Find the function handle in the library + loaderFunctionType function = + reinterpret_cast + ( + dlSym(lib, globalFuncName) + ); + + if (function) + { + // force load + (*function)(true); + } + else + { + FatalIOErrorIn + ( + "codedFixedValueFvPatchScalarField::updateLibrary()", + contextDict + ) << "Failed looking up symbol " << globalFuncName << nl + << "from " << libPath << exit(FatalIOError); + } + } + else + { + FatalIOErrorIn + ( + "codedFixedValueFvPatchScalarField::loadLibrary()", + contextDict + ) << "Failed looking up symbol " << globalFuncName << nl + << "from " << libPath << exit(FatalIOError); + + lib = 0; + if (!dlLibraryTable::close(libPath, false)) + { + FatalIOErrorIn + ( + "codedFixedValueFvPatchScalarField::loadLibrary()", + contextDict + ) << "Failed unloading library " + << libPath + << exit(FatalIOError); + } + } + } + } + + return lib; +} + + +void Foam::codedFixedValueFvPatchScalarField::unloadLibrary +( + const fileName& libPath, + const string& globalFuncName, + const dictionary& contextDict +) +{ + void* lib = dlLibraryTable::findLibrary(libPath); + + if (!lib) + { + return; + } + + // provision for manual execution of code before unloading + if (dlSymFound(lib, globalFuncName)) + { + // Find the function handle in the library + loaderFunctionType function = + reinterpret_cast + ( + dlSym(lib, globalFuncName) + ); + + if (function) + { + // force unload + (*function)(false); + } + else + { + FatalIOErrorIn + ( + "codedFixedValueFvPatchScalarField::unloadLibrary()", + contextDict + ) << "Failed looking up symbol " << globalFuncName << nl + << "from " << libPath + << exit(FatalIOError); + } + } + + if (!dlLibraryTable::close(libPath, false)) + { + FatalIOErrorIn + ( + "codedFixedValueFvPatchScalarField::" + "updateLibrary()", + contextDict + ) << "Failed unloading library " << libPath + << exit(FatalIOError); + } +} + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -const Foam::codeProperties& -Foam::codedFixedValueFvPatchScalarField::dict() const +const Foam::IOdictionary& Foam::codedFixedValueFvPatchScalarField::dict() const { - if (db().foundObject(codeProperties::typeName)) + if (db().foundObject("codeDict")) { - return db().lookupObject - ( - codeProperties::typeName - ); + return db().lookupObject("codeDict"); } else { - codeProperties* props = new codeProperties + return db().store ( - IOobject + new IOdictionary ( - codeProperties::typeName, - db().time().system(), - db(), - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE + IOobject + ( + "codeDict", + db().time().system(), + db(), + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE + ) ) ); - - return db().store(props); } } @@ -96,6 +245,14 @@ void Foam::codedFixedValueFvPatchScalarField::createLibrary // copy filtered H template dynCode.addCopyFile(codeTemplateH); + // take no chances - typeName must be identical to redirectType_ + dynCode.setFilterVariable("typeName", redirectType_); + + // debugging: make BC verbose +// dynCode.setFilterVariable("verbose", "true"); +// Info<<"compile " << redirectType_ << " sha1: " +// << context.sha1() << endl; + // define Make/options dynCode.setMakeOptions ( @@ -119,10 +276,7 @@ void Foam::codedFixedValueFvPatchScalarField::createLibrary } -void Foam::codedFixedValueFvPatchScalarField::updateLibrary -( - bool firstTime -) const +void Foam::codedFixedValueFvPatchScalarField::updateLibrary() const { dynamicCode::checkSecurity ( @@ -130,109 +284,66 @@ void Foam::codedFixedValueFvPatchScalarField::updateLibrary dict_ ); - // use codeProperties or in-line - const bool useCodeProps = !dict_.found("code"); - + // use system/codeDict or in-line const dictionary& codeDict = ( - useCodeProps - ? this->dict().subDict(redirectType_) - : dict_ + dict_.found("code") + ? dict_ + : this->dict().subDict(redirectType_) ); + dynamicCodeContext context(codeDict); - autoPtr contextPtr; - // write code into redirectType_ subdir as well - dynamicCode dynCode(redirectType_); + // codeName: redirectType + _ + // codeDir : redirectType + dynamicCode dynCode + ( + redirectType_ + context.sha1().str(true), + redirectType_ + ); const fileName libPath = dynCode.libPath(); + // see if library is loaded void* lib = dlLibraryTable::findLibrary(libPath); - bool reuseLib = false; - bool waiting = false; - - if (useCodeProps) + // library not loaded, and also need to unload old version + if (!lib && !oldLibPath_.empty()) { - // library may be loaded, but out-of-date - const codeProperties& codeProps = this->dict(); - if (codeProps.modified()) - { - codeProps.setUnmodified(); + // unload code + // Remove instantiation of fvPatchField provided by library + redirectPatchFieldPtr_.clear(); - // Remove instantiation of fvPatchField provided by library - redirectPatchFieldPtr_.clear(); - - contextPtr.reset(new dynamicCodeContext(codeDict)); - - // unload code - if (lib) - { - firstTime = false; - reuseLib = false; - lib = 0; - - if (!dlLibraryTable::close(libPath, false)) - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchScalarField::" - "updateLibrary()", - contextPtr().dict() - ) << "Failed unloading library " - << libPath - << exit(FatalIOError); - } - } - } + unloadLibrary + ( + oldLibPath_, + libraryGlobalName(oldLibPath_), + context.dict() + ); } - // library exists (and was not unloaded) - we can leave now + // retain for future reference + oldLibPath_ = libPath; + + bool waiting = false; + if (lib) { return; } - // Remove instantiation of fvPatchField provided by library redirectPatchFieldPtr_.clear(); - if (contextPtr.empty()) - { - contextPtr.reset(new dynamicCodeContext(codeDict)); - } - - // function name serving as version control - based on the SHA1 - const string sentinelName - = dynCode.codeName() + contextPtr().sha1().str(true); - - // avoid compilation (first time only) by loading an existing library - if (firstTime && dlLibraryTable::open(libPath, false)) - { - lib = dlLibraryTable::findLibrary(libPath); - - // verify the loaded version and unload if needed - if (lib) - { - reuseLib = dlSymFound(lib, sentinelName); - if (!reuseLib) - { - lib = 0; - if (!dlLibraryTable::close(libPath, false)) - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchScalarField::updateLibrary()", - contextPtr().dict() - ) << "Failed unloading library " - << libPath - << exit(FatalIOError); - } - } - } - } + // avoid compilation by loading an existing library + lib = loadLibrary + ( + libPath, + dynCode.codeName(), + context.dict() + ); // really do need to create library @@ -240,14 +351,14 @@ void Foam::codedFixedValueFvPatchScalarField::updateLibrary { if (Pstream::master()) { - createLibrary(dynCode, contextPtr()); + createLibrary(dynCode, context); if (!dynCode.wmakeLibso()) { FatalIOErrorIn ( "codedFixedValueFvPatchScalarField::updateLibrary()", - contextPtr().dict() + context.dict() ) << "Failed wmake " << libPath << exit(FatalIOError); } @@ -257,48 +368,13 @@ void Foam::codedFixedValueFvPatchScalarField::updateLibrary waiting = true; reduce(waiting, orOp()); - if (!dlLibraryTable::open(libPath, false)) - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchScalarField::updateLibrary()", - contextPtr().dict() - ) << "Failed loading library " << libPath - << exit(FatalIOError); - } - - lib = dlLibraryTable::findLibrary(libPath); - if (!lib) - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchScalarField::" - "updateLibrary()", - contextPtr().dict() - ) << "Failed to load library " << libPath - << exit(FatalIOError); - } - -//#if 0 -// Info<<"check " << libPath << " for " << sentinelName << nl; -// // paranoid - check that signature function is really there -// lib = dlLibraryTable::findLibrary(libPath); -// if (!lib || !dlSymFound(lib, sentinelName)) -// { -// FatalIOErrorIn -// ( -// "codedFixedValueFvPatchScalarField::" -// "updateLibrary()", -// contextPtr().dict() -// ) << "Failed to load library with correct signature " -// << libPath -// << exit(FatalIOError); -// } -//#endif - } - else if (reuseLib) - { - Info<< "Reusing library in " << libPath << nl; + // load newly compiled libray + lib = loadLibrary + ( + libPath, + dynCode.codeName(), + context.dict() + ); } } @@ -313,6 +389,7 @@ codedFixedValueFvPatchScalarField ) : fixedValueFvPatchField(p, iF), + oldLibPath_(), redirectPatchFieldPtr_() {} @@ -329,6 +406,7 @@ codedFixedValueFvPatchScalarField fixedValueFvPatchField(ptf, p, iF, mapper), dict_(ptf.dict_), redirectType_(ptf.redirectType_), + oldLibPath_(), redirectPatchFieldPtr_() {} @@ -344,9 +422,10 @@ codedFixedValueFvPatchScalarField fixedValueFvPatchField(p, iF, dict), dict_(dict), redirectType_(dict.lookup("redirectType")), + oldLibPath_(), redirectPatchFieldPtr_() { - updateLibrary(true); + updateLibrary(); } @@ -359,6 +438,7 @@ codedFixedValueFvPatchScalarField fixedValueFvPatchField(ptf), dict_(ptf.dict_), redirectType_(ptf.redirectType_), + oldLibPath_(), redirectPatchFieldPtr_() {} @@ -373,6 +453,7 @@ codedFixedValueFvPatchScalarField fixedValueFvPatchField(ptf, iF), dict_(ptf.dict_), redirectType_(ptf.redirectType_), + oldLibPath_(), redirectPatchFieldPtr_() {} @@ -385,15 +466,15 @@ Foam::codedFixedValueFvPatchScalarField::redirectPatchField() const if (!redirectPatchFieldPtr_.valid()) { // Construct a patch - // Make sure to construct the patchfield with uptodate value. + OStringStream os; os.writeKeyword("type") << redirectType_ << token::END_STATEMENT << nl; static_cast(*this).writeEntry("value", os); IStringStream is(os.str()); dictionary dict(is); - Info<< "constructing patchField from :" << dict << endl; +// Info<< "constructing patchField from :" << dict << endl; // if (fvPatchScalarField::dictionaryConstructorTablePtr_) // { @@ -460,15 +541,18 @@ void Foam::codedFixedValueFvPatchScalarField::evaluate void Foam::codedFixedValueFvPatchScalarField::write(Ostream& os) const { - //dict_.set("value", static_cast(*this)); - //os << dict_ << token::END_STATEMENT << nl; fixedValueFvPatchField::write(os); - os.writeKeyword("redirectType") << redirectType_ << token::END_STATEMENT - << nl; + os.writeKeyword("redirectType") << redirectType_ + << token::END_STATEMENT << nl; + if (dict_.found("code")) { - os.writeKeyword("code") << string(dict_["code"]) << token::END_STATEMENT - << nl; + os.writeKeyword("code") + << token::HASH << token::BEGIN_BLOCK; + + os.writeQuoted(string(dict_["code"]), false) + << token::HASH << token::END_BLOCK + << token::END_STATEMENT << nl; } } diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H index 7b0ef5a642..7adf8e156c 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H @@ -87,9 +87,9 @@ namespace Foam { // Forward declaration of classes -class codeProperties; class dynamicCode; class dynamicCodeContext; +class IOdictionary; /*---------------------------------------------------------------------------*\ Class codedFixedValueFvPatchScalarField Declaration @@ -106,18 +106,42 @@ class codedFixedValueFvPatchScalarField const word redirectType_; + //- Previously loaded library + mutable fileName oldLibPath_; + mutable autoPtr redirectPatchFieldPtr_; // Private Member Functions - const codeProperties& dict() const; + // Generic library management pieces + + //- Global loader/unloader function type + typedef void (*loaderFunctionType)(bool); + + static string libraryGlobalName(const fileName& libPath); + + static void* loadLibrary + ( + const fileName& libPath, + const string& globalFuncName, + const dictionary& contextDict + ); + + static void unloadLibrary + ( + const fileName& libPath, + const string& globalFuncName, + const dictionary& contextDict + ); + + + const IOdictionary& dict() const; void createLibrary(dynamicCode&, const dynamicCodeContext&) const; //- Update library as required - // Use 'firstTime' to alter behaviour - void updateLibrary(bool firstTime=false) const; + void updateLibrary() const; public: