root/software/fss-parallel-tools/test_fib.c @ master
| 7e8045d8 | David Sorber | /**
|
|
* Copyright © 2019, Oracle and/or its affiliates. All rights reserved.
|
|||
*
|
|||
* Licensed under the Universal Permissive License v 1.0 as shown at
|
|||
* http://oss.oracle.com/licenses/upl
|
|||
*
|
|||
*/
|
|||
#include "sched.h"
|
|||
#include "malloc.h"
|
|||
#include <assert.h>
|
|||
#include <stdio.h>
|
|||
#include "common/spew.h"
|
|||
// Fib example
|
|||
magic_t pfib_magic = "pfib magic";
|
|||
struct pfib_frame {
|
|||
magic_t *magic;
|
|||
size_t n;
|
|||
size_t sum;
|
|||
};
|
|||
static struct pfib_frame *make_pfib_frame(size_t n) {
|
|||
struct pfib_frame *MALLOC(result);
|
|||
*result = (struct pfib_frame){.magic = &pfib_magic,
|
|||
.n = n,
|
|||
.sum = 0};
|
|||
spew(SPEW_DEBUG, "%p n=%lu", result, result->n);
|
|||
return result;
|
|||
}
|
|||
static struct pfib_frame *cast_pfib_frame(void *af) {
|
|||
assert(af);
|
|||
struct pfib_frame *pf = af;
|
|||
assert(pf->magic == &pfib_magic);
|
|||
return pf;
|
|||
}
|
|||
struct frame *pfib(struct frame *frame, void *app_frame);
|
|||
static struct frame *pfib2(struct frame *frame, void *app_frame);
|
|||
static struct frame *pfib3(struct frame *frame, void *app_frame);
|
|||
static struct frame *pfib4(struct frame *frame, void *app_frame);
|
|||
static void pfib_return_inlet(void *parent_app_frame, size_t result) {
|
|||
struct pfib_frame *pf = cast_pfib_frame(parent_app_frame);
|
|||
pf->sum += result;
|
|||
}
|
|||
struct frame *pfib(struct frame *frame, void *app_frame) {
|
|||
struct pfib_frame *f = cast_pfib_frame(app_frame);
|
|||
spew(SPEW_DEBUG, "fib(%lu)", f->n);
|
|||
if (f->n < 2) {
|
|||
//sleep((unsigned int)f->n);
|
|||
size_t r = f->n;
|
|||
free(f);
|
|||
return sched_return(frame, r);
|
|||
} else {
|
|||
struct pfib_frame *subf = make_pfib_frame(f->n-1);
|
|||
return pfib(sched_spawn(frame, pfib2, subf, pfib_return_inlet), subf);
|
|||
}
|
|||
}
|
|||
static struct frame *pfib2(struct frame *frame, void *app_frame) {
|
|||
struct pfib_frame *f = cast_pfib_frame(app_frame);
|
|||
struct pfib_frame *subf = make_pfib_frame(f->n-2);
|
|||
return pfib(sched_spawn(frame, pfib3, subf, pfib_return_inlet), subf);
|
|||
}
|
|||
static struct frame *pfib3(struct frame *frame, void *app_frame __attribute__((unused))) {
|
|||
return sched_sync(frame, pfib4);
|
|||
}
|
|||
static struct frame *pfib4(struct frame *frame, void *app_frame) {
|
|||
struct pfib_frame *f = cast_pfib_frame(app_frame);
|
|||
size_t sum = f->sum;
|
|||
free(f);
|
|||
return sched_return(frame, sum);
|
|||
}
|
|||
static size_t fib(size_t n) {
|
|||
struct pfib_frame *pf = make_pfib_frame((size_t)n);
|
|||
size_t fn = prun(4, pfib, pf);
|
|||
return fn;
|
|||
}
|
|||
int main(int argc, char *argv[]) {
|
|||
if (argc == 1) {
|
|||
assert(0 == fib(0));
|
|||
assert(1 == fib(1));
|
|||
assert(1 == fib(2));
|
|||
assert(2 == fib(3));
|
|||
assert(3 == fib(4));
|
|||
assert(5 == fib(5));
|
|||
assert(8 == fib(6));
|
|||
assert(6765 == fib(20));
|
|||
} else {
|
|||
int n = atoi(argv[1]);
|
|||
printf("fib(%u)=%lu\n", n, fib((size_t)n));
|
|||
}
|
|||
return 0;
|
|||
}
|