Require musttail and preserve_none for interleaved
This commit is contained in:
@@ -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 {
|
||||||
|
Reference in New Issue
Block a user