Return pointer to next function
This commit is contained in:
@@ -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];
|
||||
|
Reference in New Issue
Block a user