Return pointer to next function

This commit is contained in:
2024-09-09 21:59:49 -07:00
parent 4b8f7320d3
commit 867136ff1b

View File

@@ -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];