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:
parent
3716a5b3d4
commit
47ae4f237c
6 changed files with 965 additions and 33 deletions
|
|
@ -410,6 +410,7 @@ namespace gear {
|
|||
void
|
||||
iterNext()
|
||||
{
|
||||
RawIter::validatePos(curr_);
|
||||
RawIter::iterNext();
|
||||
curr_ = accessEpoch();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in a new issue