From 867136ff1bca4e551a0180e9015309902cc70601 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Mon, 9 Sep 2024 21:59:49 -0700 Subject: [PATCH] Return pointer to next function --- InterleavingTest.cpp | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/InterleavingTest.cpp b/InterleavingTest.cpp index 035a700..dbc166a 100644 --- a/InterleavingTest.cpp +++ b/InterleavingTest.cpp @@ -8,16 +8,18 @@ struct Job { int *input; - bool (*next)(Job *); + // Returned void* is a function pointer to the next continuation. We have to + // use void* because otherwise the type would be recursive. + typedef void *(*continuation)(Job *); + continuation next; }; -bool stepJob(Job *j) { - auto &val = *j->input; - auto result = --val == 0; +void *stepJob(Job *j) { + auto done = --(*j->input) == 0; #ifdef __x86_64__ _mm_clflush(j->input); #endif - return result; + return done ? nullptr : (void *)stepJob; } // So we can look at the disassembly more easily @@ -25,14 +27,15 @@ bool stepJob(Job *j) { extern "C" { void sequential(Job **jobs, int count) { for (int i = 0; i < count; ++i) { - while (!jobs[i]->next(jobs[i])) - ; + do { + jobs[i]->next = (Job::continuation)jobs[i]->next(jobs[i]); + } while (jobs[i]->next); } } void sequentialNoFuncPtr(Job **jobs, int count) { for (int i = 0; i < count; ++i) { - while (!stepJob(jobs[i])) + while (stepJob(jobs[i])) ; } } @@ -40,8 +43,9 @@ void sequentialNoFuncPtr(Job **jobs, int count) { void interleaveSwapping(Job **jobs, int remaining) { int current = 0; while (remaining > 0) { - bool done = jobs[current]->next(jobs[current]); - if (done) { + auto next = (Job::continuation)jobs[current]->next(jobs[current]); + jobs[current]->next = next; + if (next == nullptr) { jobs[current] = jobs[remaining - 1]; --remaining; } else { @@ -72,8 +76,9 @@ void interleaveBoundedCyclicList(Job **jobs, int count) { int prevJob = started - 1; int job = 0; for (;;) { - bool done = inProgress[job]->next(inProgress[job]); - if (done) { + auto next = (Job::continuation)inProgress[job]->next(inProgress[job]); + inProgress[job]->next = next; + if (next == nullptr) { if (started == count) { if (prevJob == job) break; @@ -100,8 +105,9 @@ void interleaveCyclicList(Job **jobs, int count) { int prevJob = count - 1; int job = 0; for (;;) { - bool done = jobs[job]->next(jobs[job]); - if (done) { + auto next = (Job::continuation)jobs[job]->next(jobs[job]); + jobs[job]->next = next; + if (next == nullptr) { if (prevJob == job) break; nextJob[prevJob] = nextJob[job];