Scheduler-test: investigate and fix further memory manager problem

In-depth investigation and reasoning highlighted another problem,
which could lead to memory corruption in rare cases; in the end
I found a solution by caching the ''address'' of the current Epoch
and re-validating this address on each Epoch-overflow.

After some difficulties getting any reliable measurement for a Release-build,
it turned out that this solution even ''improves performance by 22%''

Remark-1: the static blockFlow::Config prevents simple measurements by
  just recompiling one translation unit; it is necessary to build the
  relevant parts of Vault-layer with optimisation to get reliable numbers

Remark-2: performing a full non-DEBUG build highlighted two missing
  header-inclusions to allow for the necessary template specialisations.
This commit is contained in:
Fischlurch 2023-12-27 23:59:31 +01:00
parent 3716a5b3d4
commit 47ae4f237c
6 changed files with 965 additions and 33 deletions

View file

@ -410,6 +410,7 @@ namespace gear {
void
iterNext()
{
RawIter::validatePos(curr_);
RawIter::iterNext();
curr_ = accessEpoch();
}

View file

@ -55,6 +55,7 @@
namespace vault{
namespace mem {
namespace err = lumiera::error;
namespace {
const size_t ALLOC_SAFETY_LIMIT = 8_GiB;
@ -174,9 +175,33 @@ namespace mem {
// was in a segment that might be moved up
ENSURE (exFam->isValidPos (index));
}
/**
* Ensure this iterator is still in-sync with expected
* target position; attempt to re-establish proper sync
* after growing the Extents pool with position rotation.
* @remark typically steps up by number of new slots.
*/
void
validatePos (Extent* knownTarget)
{
if (knownTarget == & yield())
return;
size_t prevIdx = index;
do{
iterNext();
if (knownTarget == & yield())
return;
}
while (index != prevIdx);
// went full circle without hitting the expected target Extent....
throw err::Logic {"Unable to fix-up an iterator after Extent allocation. "
"Reference position obsolete or unknown to the memory manager."};
}
};
/* ==== Management Data ==== */
Extents extents_;
@ -337,12 +362,11 @@ namespace mem {
{
size_t resultSiz = slotCnt()+addCnt;
size_t requiredSpace = resultSiz * sizeof(Extent);
using namespace lumiera::error;
if (requiredSpace > ALLOC_SAFETY_LIMIT)
throw Fatal{"Raw allocation exceeds safety limit: "
+util::showSize(requiredSpace) +" > "
+util::showSize(ALLOC_SAFETY_LIMIT)
, LUMIERA_ERROR_CAPACITY};
throw err::Fatal{"Raw allocation exceeds safety limit: "
+util::showSize(requiredSpace) +" > "
+util::showSize(ALLOC_SAFETY_LIMIT)
,err::LUMIERA_ERROR_CAPACITY};
}

View file

@ -37,7 +37,7 @@
#include "steam/streamtype.hpp"
#include "lib/format-string.hpp"
#include "lib/query-util.hpp"
#include "common/query.hpp"
#include "common/query/defs-manager-impl.hpp"
using util::_Fmt;
using util::isnil;

View file

@ -29,6 +29,7 @@
#include "steam/play/diagnostic-output-slot.hpp"
#include "steam/engine/buffhandle.hpp"
#include "steam/engine/buffhandle-attach.hpp"
#include "steam/engine/testframe.hpp"

View file

@ -1264,7 +1264,7 @@ namespace test {
{
auto round = roundsNeeded (scaleStep);
Sink sink;
size_t scree;
size_t scree{0x55DEAD55};
for ( ; 0 < round; --round)
boost::hash_combine (scree,scree);
sink = scree;

File diff suppressed because it is too large Load diff