Skip to content

Commit

Permalink
Make product_early use a linked list instead of array, and make it no…
Browse files Browse the repository at this point in the history
…n-tail recursive
  • Loading branch information
codrutiftode committed Jun 5, 2024
1 parent 9dec3ed commit dc348bd
Showing 1 changed file with 37 additions and 18 deletions.
55 changes: 37 additions & 18 deletions benchmarks/libseff/product_early/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@

DEFINE_EFFECT(done, 0, int64_t, { int64_t value; });

static int64_t handleDone(seff_coroutine_t *k, int* xs) {
// Using a linked list to mirror the other languages
typedef struct list {
int64_t head;
struct list* next;
} list_t;

static int64_t handleDone(seff_coroutine_t *k, list_t* xs) {
effect_set handles_done = HANDLES(done);
seff_request_t req = seff_handle(k, NULL, handles_done);

Expand All @@ -21,43 +27,56 @@ static int64_t handleDone(seff_coroutine_t *k, int* xs) {
}

static void* product(void* parameter) {
int* xs = (int*) parameter;
int64_t prod = 1;

int i = 0;
while (i <= ENUMERATE_SIZE) {
if (xs[i] == 0) {
PERFORM (done, 0);
}
else {
prod *= xs[i];
i++;
}
list_t list = *(list_t*) parameter;
if (list.head == 0) {
PERFORM(done, 0);
}
else {
int64_t res = (int64_t) product(list.next);
return (void*) (list.head * res);
}
return NULL;
}

static int run_product(int* xs) {
static int run_product(list_t* xs) {
seff_coroutine_t *k = seff_coroutine_new(product, (void*) xs);
int64_t result = handleDone(k, xs);
seff_coroutine_delete(k);
return result;
}

static void enumerate(size_t n, int xs[n]) {
// Allocate a linked list on the heap
static list_t* enumerate(size_t n) {
list_t* top = malloc(sizeof(list_t));
list_t* current = top;

for (size_t i = 0; i < n; i++) {
xs[i] = (int) (n - 1) - i;
current->head = (n - 1) - i;
if (i == n - 1) current->next = NULL;
else current->next = malloc(sizeof(list_t));
current = current->next;
}
return top;
}

// Free linked list
static void free_list(list_t* xs) {
while (xs != NULL) {
list_t* next = xs->next;
free(xs);
xs = next;
}
}

static int64_t run(int64_t n) {
int xs[ENUMERATE_SIZE + 1];
enumerate(ENUMERATE_SIZE + 1, xs);
list_t* xs = enumerate(ENUMERATE_SIZE + 1);

int64_t a = 0;
for (int i = 0; i < n; i++) {
a += run_product(xs);
}

free_list(xs);
return a;
}

Expand Down

0 comments on commit dc348bd

Please sign in to comment.