From 12f361f33a96a58b1d374c5a16728a01a5c953da Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Wed, 17 Jul 2024 18:12:45 -0700 Subject: [PATCH] Don't plumb impl and ReadContext --- ConflictSet.cpp | 67 ++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 44c40f7..faee47b 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -718,6 +718,7 @@ struct ReadContext { double prefix_read_iterations_accum = 0; double range_read_iterations_accum = 0; double range_read_node_scan_accum = 0; + ConflictSet::Impl *impl; }; // A type that's plumbed along the non-const call tree. Same lifetime as @@ -1769,13 +1770,13 @@ struct SearchStepWise { // point or range version according to cmp, but this version short circuits as // soon as it can prove that there's no conflict. bool checkPointRead(Node *n, const std::span key, - InternalVersionT readVersion, ConflictSet::Impl *impl, - ReadContext *tls) { + InternalVersionT readVersion, ReadContext *tls) { ++tls->point_read_accum; #if DEBUG_VERBOSE && !defined(NDEBUG) fprintf(stderr, "Check point read: %s\n", printable(key).c_str()); #endif auto remaining = key; + auto *impl = tls->impl; for (;; ++tls->point_read_iterations_accum) { if (maxVersion(n, impl) <= readVersion) { ++tls->point_read_short_circuit_accum; @@ -1849,13 +1850,13 @@ downLeftSpine: // max version or range version if this prefix doesn't exist, but this version // short circuits as soon as it can prove that there's no conflict. bool checkPrefixRead(Node *n, const std::span key, - InternalVersionT readVersion, ConflictSet::Impl *impl, - ReadContext *tls) { + InternalVersionT readVersion, ReadContext *tls) { ++tls->prefix_read_accum; #if DEBUG_VERBOSE && !defined(NDEBUG) fprintf(stderr, "Check prefix read: %s\n", printable(key).c_str()); #endif auto remaining = key; + auto *impl = tls->impl; for (;; ++tls->prefix_read_iterations_accum) { auto m = maxVersion(n, impl); if (remaining.size() == 0) { @@ -2363,11 +2364,12 @@ Vector getSearchPath(Arena &arena, Node *n) { template bool checkRangeStartsWith(Node *n, std::span key, int begin, int end, InternalVersionT readVersion, - ConflictSet::Impl *impl, ReadContext *tls) { + ReadContext *tls) { #if DEBUG_VERBOSE && !defined(NDEBUG) fprintf(stderr, "%s(%02x,%02x)*\n", printable(key).c_str(), begin, end); #endif auto remaining = key; + auto *impl = tls->impl; if (remaining.size() == 0) { return checkMaxBetweenExclusive(n, begin, end, readVersion, tls); } @@ -2435,10 +2437,9 @@ namespace { // that are >= key is <= readVersion template struct CheckRangeLeftSide { CheckRangeLeftSide(Node *n, std::span key, int prefixLen, - InternalVersionT readVersion, ConflictSet::Impl *impl, - ReadContext *tls) + InternalVersionT readVersion, ReadContext *tls) : n(n), remaining(key), prefixLen(prefixLen), readVersion(readVersion), - impl(impl), tls(tls) { + impl(tls->impl), tls(tls) { #if DEBUG_VERBOSE && !defined(NDEBUG) fprintf(stderr, "Check range left side from %s for keys starting with %s\n", printable(key).c_str(), @@ -2557,10 +2558,9 @@ template struct CheckRangeLeftSide { // that are < key is <= readVersion template struct CheckRangeRightSide { CheckRangeRightSide(Node *n, std::span key, int prefixLen, - InternalVersionT readVersion, ConflictSet::Impl *impl, - ReadContext *tls) + InternalVersionT readVersion, ReadContext *tls) : n(n), key(key), remaining(key), prefixLen(prefixLen), - readVersion(readVersion), impl(impl), tls(tls) { + readVersion(readVersion), impl(tls->impl), tls(tls) { #if DEBUG_VERBOSE && !defined(NDEBUG) fprintf(stderr, "Check range right side to %s for keys starting with %s\n", printable(key).c_str(), @@ -2695,23 +2695,23 @@ template struct CheckRangeRightSide { template bool checkRangeReadImpl(Node *n, std::span begin, std::span end, - InternalVersionT readVersion, ConflictSet::Impl *impl, - ReadContext *tls) { + InternalVersionT readVersion, ReadContext *tls) { int lcp = longestCommonPrefix(begin.data(), end.data(), std::min(begin.size(), end.size())); if (lcp == int(begin.size()) && end.size() == begin.size() + 1 && end.back() == 0) { - return checkPointRead(n, begin, readVersion, impl, tls); + return checkPointRead(n, begin, readVersion, tls); } if (lcp == int(begin.size() - 1) && end.size() == begin.size() && int(begin.back()) + 1 == int(end.back())) { - return checkPrefixRead(n, begin, readVersion, impl, tls); + return checkPrefixRead(n, begin, readVersion, tls); } ++tls->range_read_accum; SearchStepWise search{n, begin.subspan(0, lcp)}; Arena arena; + auto *impl = tls->impl; for (;; ++tls->range_read_iterations_accum) { assert(getSearchPath(arena, search.n) <=> begin.subspan(0, lcp - search.remaining.size()) == @@ -2737,22 +2737,22 @@ bool checkRangeReadImpl(Node *n, std::span begin, lcp -= consumed; if (lcp == int(begin.size())) { - CheckRangeRightSide checkRangeRightSide{n, end, lcp, - readVersion, impl, tls}; + CheckRangeRightSide checkRangeRightSide{n, end, lcp, readVersion, + tls}; while (!checkRangeRightSide.step()) ; return checkRangeRightSide.ok; } if (!checkRangeStartsWith(n, begin.subspan(0, lcp), begin[lcp], - end[lcp], readVersion, impl, tls)) { + end[lcp], readVersion, tls)) { return false; } - CheckRangeLeftSide checkRangeLeftSide{n, begin, lcp + 1, - readVersion, impl, tls}; - CheckRangeRightSide checkRangeRightSide{n, end, lcp + 1, - readVersion, impl, tls}; + CheckRangeLeftSide checkRangeLeftSide{n, begin, lcp + 1, readVersion, + tls}; + CheckRangeRightSide checkRangeRightSide{n, end, lcp + 1, readVersion, + tls}; for (;;) { bool leftDone = checkRangeLeftSide.step(); @@ -2796,7 +2796,7 @@ checkMaxBetweenExclusive(Node *n, int begin, int end, template __attribute__((target("avx512f"))) bool checkRangeStartsWith(Node *n, std::span key, int begin, int end, InternalVersionT readVersion, - ConflictSet::Impl *impl); + ReadContext *); template __attribute__((target("avx512f"))) bool CheckRangeLeftSide::step(); template __attribute__((target("avx512f"))) bool @@ -2804,27 +2804,27 @@ CheckRangeRightSide::step(); template __attribute__((target("avx512f"))) bool checkRangeReadImpl(Node *n, std::span begin, std::span end, - InternalVersionT readVersion, ConflictSet::Impl *impl); + InternalVersionT readVersion, ReadContext *); #endif #if defined(__SANITIZE_THREAD__) || !defined(__x86_64__) bool checkRangeRead(Node *n, std::span begin, std::span end, InternalVersionT readVersion, - ConflictSet::Impl *impl, ReadContext *tls) { - return checkRangeReadImpl(n, begin, end, readVersion, impl, tls); + ReadContext *tls) { + return checkRangeReadImpl(n, begin, end, readVersion, tls); } #else __attribute__((target("default"))) bool checkRangeRead(Node *n, std::span begin, std::span end, InternalVersionT readVersion, - ConflictSet::Impl *impl) { - return checkRangeReadImpl(n, begin, end, readVersion, impl); + ReadContext *tls) { + return checkRangeReadImpl(n, begin, end, readVersion, tls); } __attribute__((target("avx512f"))) bool checkRangeRead(Node *n, std::span begin, std::span end, InternalVersionT readVersion, - ConflictSet::Impl *impl) { - return checkRangeReadImpl(n, begin, end, readVersion, impl); + ReadContext *tls) { + return checkRangeReadImpl(n, begin, end, readVersion, tls); } #endif @@ -3127,6 +3127,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl { clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts_begin); #endif ReadContext tls; + tls.impl = this; int commits_accum = 0; int conflicts_accum = 0; int too_olds_accum = 0; @@ -3142,11 +3143,9 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl { reads[i].readVersion < oldestVersionFullPrecision ? TooOld : (end.size() > 0 ? checkRangeRead(root, begin, end, - InternalVersionT(reads[i].readVersion), this, - &tls) + InternalVersionT(reads[i].readVersion), &tls) : checkPointRead(root, begin, - InternalVersionT(reads[i].readVersion), this, - &tls)) + InternalVersionT(reads[i].readVersion), &tls)) ? Commit : Conflict; commits_accum += result[i] == Commit;