Return pointer to next function
This commit is contained in:
@@ -8,16 +8,18 @@
|
|||||||
|
|
||||||
struct Job {
|
struct Job {
|
||||||
int *input;
|
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) {
|
void *stepJob(Job *j) {
|
||||||
auto &val = *j->input;
|
auto done = --(*j->input) == 0;
|
||||||
auto result = --val == 0;
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
_mm_clflush(j->input);
|
_mm_clflush(j->input);
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return done ? nullptr : (void *)stepJob;
|
||||||
}
|
}
|
||||||
|
|
||||||
// So we can look at the disassembly more easily
|
// So we can look at the disassembly more easily
|
||||||
@@ -25,14 +27,15 @@ bool stepJob(Job *j) {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
void sequential(Job **jobs, int count) {
|
void sequential(Job **jobs, int count) {
|
||||||
for (int i = 0; i < count; ++i) {
|
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) {
|
void sequentialNoFuncPtr(Job **jobs, int count) {
|
||||||
for (int i = 0; i < count; ++i) {
|
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) {
|
void interleaveSwapping(Job **jobs, int remaining) {
|
||||||
int current = 0;
|
int current = 0;
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
bool done = jobs[current]->next(jobs[current]);
|
auto next = (Job::continuation)jobs[current]->next(jobs[current]);
|
||||||
if (done) {
|
jobs[current]->next = next;
|
||||||
|
if (next == nullptr) {
|
||||||
jobs[current] = jobs[remaining - 1];
|
jobs[current] = jobs[remaining - 1];
|
||||||
--remaining;
|
--remaining;
|
||||||
} else {
|
} else {
|
||||||
@@ -72,8 +76,9 @@ void interleaveBoundedCyclicList(Job **jobs, int count) {
|
|||||||
int prevJob = started - 1;
|
int prevJob = started - 1;
|
||||||
int job = 0;
|
int job = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bool done = inProgress[job]->next(inProgress[job]);
|
auto next = (Job::continuation)inProgress[job]->next(inProgress[job]);
|
||||||
if (done) {
|
inProgress[job]->next = next;
|
||||||
|
if (next == nullptr) {
|
||||||
if (started == count) {
|
if (started == count) {
|
||||||
if (prevJob == job)
|
if (prevJob == job)
|
||||||
break;
|
break;
|
||||||
@@ -100,8 +105,9 @@ void interleaveCyclicList(Job **jobs, int count) {
|
|||||||
int prevJob = count - 1;
|
int prevJob = count - 1;
|
||||||
int job = 0;
|
int job = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bool done = jobs[job]->next(jobs[job]);
|
auto next = (Job::continuation)jobs[job]->next(jobs[job]);
|
||||||
if (done) {
|
jobs[job]->next = next;
|
||||||
|
if (next == nullptr) {
|
||||||
if (prevJob == job)
|
if (prevJob == job)
|
||||||
break;
|
break;
|
||||||
nextJob[prevJob] = nextJob[job];
|
nextJob[prevJob] = nextJob[job];
|
||||||
|
Reference in New Issue
Block a user