Project

General

Profile

Download (2.83 KB) Statistics
| Branch: | Tag: | Revision:
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;
}