Skip to content

Commit

Permalink
Construct globalMaximumIndex and related variables on first use.
Browse files Browse the repository at this point in the history
Avoid issues with static initialization order.
  • Loading branch information
jblueh committed Feb 1, 2024
1 parent 9b6b905 commit 9ca6c38
Showing 1 changed file with 28 additions and 22 deletions.
50 changes: 28 additions & 22 deletions include/codi/tapes/indices/parallelReuseIndexManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,39 @@ namespace codi {

private:

static Atomic<T_Index> globalMaximumIndex; ///< The largest index created across all instances of this class.
static bool globalMaximumIndexInitialized; ///< Indicates whether globalMaximumIndex is initialized.
static ReadWriteMutex globalMaximumIndexMutex; ///< Safeguards globalMaximumIndex, globalMaximumIndexInitialized.
/// The largest index created across all instances of this class. Construct on first use to avoid issues with
/// static initialization order.
static CODI_NO_INLINE Atomic<T_Index>& globalMaximumIndex() {
static Atomic<T_Index> _globalMaximumIndex;
return _globalMaximumIndex;
}

/// Indicates whether globalMaximumIndex is initialized. Construct on first use to avoid issues with static
/// initialization order.
static CODI_NO_INLINE bool& globalMaximumIndexInitialized() {
static bool _globalMaximumIndexInitialized = false;
return _globalMaximumIndexInitialized;
}

/// Safeguards globalMaximumIndex, globalMaximumIndexInitialized. Construct on first use to avoid issues with
/// static initialization order.
static CODI_NO_INLINE ReadWriteMutex& globalMaximumIndexMutex() {
static ReadWriteMutex _globalMaximumIndexMutex;
return _globalMaximumIndexMutex;
}

public:

/// Constructor
/// For a tape class that uses this index manager, all tape instances are expected to pass the same number of
/// reservedIndices to this constructor.
ParallelReuseIndexManager(Index const& reservedIndices) {
globalMaximumIndexMutex.lockWrite();
if (!globalMaximumIndexInitialized) {
globalMaximumIndex = reservedIndices;
globalMaximumIndexInitialized = true;
globalMaximumIndexMutex().lockWrite();
if (!globalMaximumIndexInitialized()) {
globalMaximumIndex() = reservedIndices;
globalMaximumIndexInitialized() = true;
}
globalMaximumIndexMutex.unlockWrite();
globalMaximumIndexMutex().unlockWrite();
generateNewIndices();
}

Expand All @@ -117,7 +134,7 @@ namespace codi {
/// \copydoc IndexManagerInterface::addToTapeValues <br><br>
/// Implementation: Adds max live indices, cur live indices, indices stored, memory used, memory allocated.
void addToTapeValues(TapeValues& values) const {
unsigned long maximumGlobalIndex = globalMaximumIndex;
unsigned long maximumGlobalIndex = globalMaximumIndex();

values.addUnsignedLongEntry("Max. live indices", maximumGlobalIndex);
// The number of current live indices cannot be computed from one instance alone.
Expand All @@ -131,7 +148,7 @@ namespace codi {
/// 1. tape resets do not change the largest created index,
/// 2. it is not guaranteed that the largest created index has been assigned to a variable already.
CODI_INLINE Index getLargestCreatedIndex() const {
return globalMaximumIndex;
return globalMaximumIndex();
}

/// @}
Expand All @@ -146,7 +163,7 @@ namespace codi {

codiAssert(this->unusedIndices.size() >= this->indexSizeIncrement);

Index upperIndexRangeBound = globalMaximumIndex += this->indexSizeIncrement; // note: atomic operation
Index upperIndexRangeBound = globalMaximumIndex() += this->indexSizeIncrement; // note: atomic operation
Index lowerIndexRangeBound = upperIndexRangeBound - this->indexSizeIncrement;

for (size_t pos = 0; pos < this->indexSizeIncrement; ++pos) {
Expand All @@ -156,15 +173,4 @@ namespace codi {
this->unusedIndicesPos = this->indexSizeIncrement;
}
};

template<typename Index, typename ParallelToolbox>
typename ParallelReuseIndexManager<Index, ParallelToolbox>::template Atomic<Index>
ParallelReuseIndexManager<Index, ParallelToolbox>::globalMaximumIndex;

template<typename Index, typename ParallelToolbox>
bool ParallelReuseIndexManager<Index, ParallelToolbox>::globalMaximumIndexInitialized = false;

template<typename Index, typename ParallelToolbox>
typename ParallelReuseIndexManager<Index, ParallelToolbox>::ReadWriteMutex
ParallelReuseIndexManager<Index, ParallelToolbox>::globalMaximumIndexMutex;
}

0 comments on commit 9ca6c38

Please sign in to comment.