Require musttail and preserve_none for interleaved

This commit is contained in:
2024-11-11 21:40:05 -08:00
parent 94a4802824
commit b37feb58dd

View File

@@ -3183,6 +3183,12 @@ Node *firstGeqPhysical(Node *n, const TrivialSpan key) {
#define PRESERVE_NONE #define PRESERVE_NONE
#endif #endif
#if __has_attribute(musttail) && __has_attribute(preserve_none)
constexpr bool kEnableInterleaved = true;
#else
constexpr bool kEnableInterleaved = false;
#endif
namespace check { namespace check {
typedef PRESERVE_NONE void (*Continuation)(struct Job *, struct Context *); typedef PRESERVE_NONE void (*Continuation)(struct Job *, struct Context *);
@@ -4969,51 +4975,50 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
check::Context context; check::Context context;
context.readContext.impl = this; context.readContext.impl = this;
#if __has_attribute(musttail) if constexpr (kEnableInterleaved) {
if (count == 1) { if (count == 1) {
useSequential(reads, result, count, context); useSequential(reads, result, count, context);
} else { } else {
constexpr int kConcurrent = 16; constexpr int kConcurrent = 16;
check::Job inProgress[kConcurrent]; check::Job inProgress[kConcurrent];
context.count = count; context.count = count;
context.oldestVersionFullPrecision = oldestVersionFullPrecision; context.oldestVersionFullPrecision = oldestVersionFullPrecision;
context.root = root; context.root = root;
context.queries = reads; context.queries = reads;
context.results = result; context.results = result;
int64_t started = std::min(kConcurrent, count); int64_t started = std::min(kConcurrent, count);
context.started = started; context.started = started;
for (int i = 0; i < started; i++) { for (int i = 0; i < started; i++) {
inProgress[i].init(reads + i, result + i, root, inProgress[i].init(reads + i, result + i, root,
oldestVersionFullPrecision); oldestVersionFullPrecision);
} }
for (int i = 0; i < started - 1; i++) { for (int i = 0; i < started - 1; i++) {
inProgress[i].next = inProgress + i + 1; inProgress[i].next = inProgress + i + 1;
} }
for (int i = 1; i < started; i++) { for (int i = 1; i < started; i++) {
inProgress[i].prev = inProgress + i - 1; inProgress[i].prev = inProgress + i - 1;
} }
inProgress[0].prev = inProgress + started - 1; inProgress[0].prev = inProgress + started - 1;
inProgress[started - 1].next = inProgress; inProgress[started - 1].next = inProgress;
// Kick off the sequence of tail calls that finally returns once all jobs // Kick off the sequence of tail calls that finally returns once all
// are done // jobs are done
inProgress->continuation(inProgress, &context); inProgress->continuation(inProgress, &context);
#ifndef NDEBUG #ifndef NDEBUG
Arena arena; Arena arena;
auto *results2 = new (arena) Result[count]; auto *results2 = new (arena) Result[count];
check::Context context2; check::Context context2;
context2.readContext.impl = this; context2.readContext.impl = this;
useSequential(reads, results2, count, context2); useSequential(reads, results2, count, context2);
assert(memcmp(result, results2, count) == 0); assert(memcmp(result, results2, count) == 0);
assert(context.readContext == context2.readContext); assert(context.readContext == context2.readContext);
#endif #endif
}
} else {
useSequential(reads, result, count, context);
} }
#else
useSequential(reads, result, count, context);
#endif
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
assert(reads[i].readVersion >= 0); assert(reads[i].readVersion >= 0);
assert(reads[i].readVersion <= newestVersionFullPrecision); assert(reads[i].readVersion <= newestVersionFullPrecision);
@@ -5186,11 +5191,6 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
assert(allPointWrites || sorted); assert(allPointWrites || sorted);
#endif #endif
#if __has_attribute(musttail)
constexpr bool kEnableInterleaved = true;
#else
constexpr bool kEnableInterleaved = false;
#endif
if (kEnableInterleaved && count > 1) { if (kEnableInterleaved && count > 1) {
interleavedWrites(writes, count, InternalVersionT(writeVersion)); interleavedWrites(writes, count, InternalVersionT(writeVersion));
} else { } else {