Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ WASMFX_CONT_TABLE_INITIAL_CAPACITY?=1024
WASMFX_PRESERVE_SHADOW_STACK?=1
# Only relevant if WASMFX_PRESERVE_SHADOW_STACK is 1
WASMFX_CONT_SHADOW_STACK_SIZE?=65536
ASYNCIFY=../binaryen/bin/wasm-opt --enable-exception-handling --enable-reference-types --enable-multivalue --enable-bulk-memory --enable-gc --enable-stack-switching -O2 --asyncify
ASYNCIFY=../binaryen/bin/wasm-opt --enable-exception-handling --enable-reference-types --enable-multivalue --enable-bulk-memory --enable-gc --enable-stack-switching -O2 -g --asyncify --no-inline="fiber_yield,fiber_yield_to,fiber_resume,fiber_resume_with"
WASICC=../benchfx/wasi-sdk-22.0/bin/clang
WASIFLAGS=--sysroot=../benchfx/wasi-sdk-22.0/share/wasi-sysroot -std=c17 -Wall -Wextra -Werror -Wpedantic -Wno-strict-prototypes -O3 -I inc
WASIFLAGS=-g --sysroot=../benchfx/wasi-sdk-22.0/share/wasi-sysroot -std=c17 -Wall -Wextra -Werror -Wpedantic -Wno-strict-prototypes -O0 -I inc
WASM_INTERP=../spec/interpreter/wasm
WASM_MERGE=../binaryen/bin/wasm-merge --enable-multimemory --enable-exception-handling --enable-reference-types --enable-multivalue --enable-bulk-memory --enable-gc --enable-stack-switching

Expand All @@ -20,7 +20,7 @@ endif
all: hello sieve itersum treesum

.PHONY: hello
hello: hello_asyncify.wasm hello_wasmfx.wasm
hello: hello_asyncify.wasm hello_wasmfx.wasm hello_prompt_asyncify.wasm hello_forward_prompt_asyncify.wasm

hello_asyncify.wasm: inc/fiber.h src/asyncify/asyncify_impl.c examples/hello.c
$(WASICC) -DSTACK_POOL_SIZE=$(STACK_POOL_SIZE) -DASYNCIFY_DEFAULT_STACK_SIZE=$(ASYNCIFY_DEFAULT_STACK_SIZE) src/asyncify/asyncify_impl.c $(WASIFLAGS) examples/hello.c -o hello_asyncfiy.pre.wasm
Expand All @@ -33,6 +33,17 @@ hello_wasmfx.wasm: inc/fiber.h src/wasmfx/imports.wat src/wasmfx/wasmfx_impl.c e
$(WASM_MERGE) fiber_wasmfx_imports.wasm "fiber_wasmfx_imports" hello_wasmfx.pre.wasm "main" -o hello_wasmfx.wasm
chmod +x hello_wasmfx.wasm

hello_prompt_asyncify.wasm: inc/fiber.h src/asyncify/asyncify_prompt_impl.c examples/prompt/hello.c
$(WASICC) -DSTACK_POOL_SIZE=$(STACK_POOL_SIZE) -DASYNCIFY_DEFAULT_STACK_SIZE=$(ASYNCIFY_DEFAULT_STACK_SIZE) src/asyncify/asyncify_prompt_impl.c $(WASIFLAGS) examples/prompt/hello.c -o hello_prompt_asyncfiy.pre.wasm
$(ASYNCIFY) hello_prompt_asyncfiy.pre.wasm -o hello_prompt_asyncify.wasm
chmod +x hello_prompt_asyncify.wasm

hello_forward_prompt_asyncify.wasm: inc/fiber.h src/asyncify/asyncify_prompt_impl.c examples/prompt/hello_forward.c
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think the examples/prompt folder wasn't committed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. The latest commit adds them.

$(WASICC) -DSTACK_POOL_SIZE=$(STACK_POOL_SIZE) -DASYNCIFY_DEFAULT_STACK_SIZE=$(ASYNCIFY_DEFAULT_STACK_SIZE) src/asyncify/asyncify_prompt_impl.c $(WASIFLAGS) examples/prompt/hello_forward.c -o hello_forward_prompt_asyncfiy.pre.wasm
$(ASYNCIFY) hello_forward_prompt_asyncfiy.pre.wasm -o hello_forward_prompt_asyncify.wasm
chmod +x hello_forward_prompt_asyncify.wasm


.PHONY: sieve
sieve: sieve_asyncify.wasm sieve_wasmfx.wasm

Expand Down
8 changes: 5 additions & 3 deletions examples/hello.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ void* world(void *arg) {
return NULL;
}

int main(void) {
fiber_init();
int prog(int __attribute__((unused)) argc, char** __attribute__((unused)) argv) {
fiber_result_t status;
fiber_t hello_fiber = fiber_alloc(hello);
fiber_t world_fiber = fiber_alloc(world);
Expand Down Expand Up @@ -61,6 +60,9 @@ int main(void) {
fiber_free(hello_fiber);
fiber_free(world_fiber);

fiber_finalize();
return 0;
}

int main(int argc, char** argv) {
return fiber_main(prog, argc, argv);
}
11 changes: 7 additions & 4 deletions examples/itersum.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@


void* sum(void *arg) {
int32_t max = (int32_t)(intptr_t)arg;
int32_t max = 0;
max = (int32_t)(intptr_t)arg;
for (int32_t i = 0; i < max; i++) {
fiber_yield((void*)(intptr_t)i);
}
Expand All @@ -29,19 +30,21 @@ int32_t run(int32_t max) {
return result;
}

int main(int argc, char** argv) {
int prog(int argc, char** argv) {
if (argc != 2) {
fprintf(stderr, "Wrong number of arguments. Expected: 1");
return -1;
}
fiber_init();

int i = atoi(argv[1]);

int32_t result = run(i);

printf("%d\n", result);

fiber_finalize();
return 0;
}

int main(int argc, char** argv) {
return (int)fiber_main(prog, argc, argv);
}
8 changes: 5 additions & 3 deletions examples/sieve.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static void print_input_error_and_exit(void) {
exit(1);
}

int main(int argc, char **argv) {
int prog(int argc, char **argv) {
if (argc != 2) {
printf("usage: %s <n>\n", argv[0]);
exit(1);
Expand All @@ -53,7 +53,6 @@ int main(int argc, char **argv) {
uint32_t p = 0; // number of primes computed so far.
int32_t i = 2; // the current candidate prime number.

fiber_init();
fiber_t *filters = (fiber_t*)malloc(sizeof(fiber_t) * max_primes);
fiber_result_t status;

Expand Down Expand Up @@ -91,7 +90,10 @@ int main(int argc, char **argv) {
fiber_free(filters[i]);
}
free(filters);
fiber_finalize();

return 0;
}

int main(int argc, char** argv) {
return fiber_main(prog, argc, argv);
}
8 changes: 5 additions & 3 deletions examples/treesum.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,11 @@ int32_t run(node_t* tree) {
return sum;
}

int main(int argc, char** argv) {
int prog(int argc, char** argv) {
if (argc != 2) {
fprintf(stderr, "Wrong number of arguments. Expected: 1");
return -1;
}
fiber_init();

int i = atoi(argv[1]);
node_t *tree = build_tree((int32_t)i, 0);
Expand All @@ -86,6 +85,9 @@ int main(int argc, char** argv) {

printf("%d\n", result);

fiber_finalize();
return 0;
}

int main(int argc, char** argv) {
return fiber_main(prog, argc, argv);
}
12 changes: 3 additions & 9 deletions inc/fiber.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,9 @@ export("fiber_resume")
void* fiber_resume(fiber_t fiber, void *arg, fiber_result_t *status);


/** Initialises the fiber runtime. It must be called exactly once
before using any of the other fiber_* functions. **/
export("fiber_init")
void fiber_init(void);

/** Tears down the fiber runtime. It must be called after the final
use of any of the other fiber_* functions. **/
export("fiber_finalize")
void fiber_finalize(void);
/** Runs the provided `main` function in a fiber context. **/
export("fiber_main")
int fiber_main(int (*main)(int,char**), int, char**);

#undef export
#endif
57 changes: 57 additions & 0 deletions inc/fiber/prompt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/** A basic fiber interface. **/
#ifdef WASMFX_FIBER_C_H
#error "the prompt implementation conflicts with the standard implementation"
#endif
#ifndef WASMFX_FIBER_C_PROMPT_H
#define WASMFX_FIBER_C_PROMPT_H

#define export(NAME) __attribute__((export_name(NAME)))

#include <stdint.h>

/** Type of a prompt. **/
typedef uint32_t prompt_t;

/** The result type of a yield. **/
typedef struct yield_result {
prompt_t prompt;
void* value;
} yield_result_t;

/** The signature of a fiber entry point. **/
typedef void* (*fiber_entry_point_t)(prompt_t, void*);

/** The abstract type of a fiber object. **/
typedef struct fiber* fiber_t;

/** Allocates a new fiber with the default stack size. **/
export("fiber_alloc")
fiber_t fiber_alloc(fiber_entry_point_t entry);

/** Reclaims the memory occupied by the fiber object. **/
export("fiber_free")
void fiber_free(fiber_t fiber);

/** Yields control to the context of the provided prompt. This
function must be called from within a fiber context. **/
export("fiber_yield_to")
yield_result_t fiber_yield_to(prompt_t p, void *arg);

/** Possible status codes for `fiber_resume`. **/
typedef enum { FIBER_OK = 0, FIBER_YIELD = 1, FIBER_ERROR = 2, FIBER_FORWARD = 3 } fiber_result_t;

/** Resumes a given `fiber` with argument `arg`, returning some value
of type `void*`. The output parameter `status` indicates whether
the fiber ran to completion (`FIBER_OK`), yielded control
(`FIBER_YIELD`), or failed (`FIBER_ERROR`), in the latter case the
return value will always be `NULL`. **/
export("fiber_resume_with")
void* fiber_resume_with(fiber_t fiber, void *arg, fiber_result_t *status);


/** Runs the provided `main` function in a fiber context. **/
export("fiber_main")
int fiber_main(int (*main)(int,char**), int, char**);

#undef export
#endif
27 changes: 27 additions & 0 deletions inc/wasi-io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef __WASI_IO_H
#define __WASI_IO_H

#include <stdint.h>
#include <unistd.h>
#include <wasi/api.h>

// NOTE: We cannot use printf() and most friends because asyncify
// attempts to transform them and inadvertently ending up corrupting
// its own state resulting in an "unreachable" error at runtime.
// The following code is adapted from
// https://gist.github.com/s-macke/6dd78c78be46214d418454abb667a1ba
#define wasi_print(str) do { \
const uint8_t *start = (uint8_t *)str; \
const uint8_t *end = start; \
for (; *end != '\0'; end++) {} \
__wasi_ciovec_t iov = {.buf = start, .buf_len = end - start}; \
size_t nwritten; \
(void)__wasi_fd_write(STDOUT_FILENO, &iov, 1, &nwritten); \
} while (0)
#define wasi_print_debug(str) \
wasi_print(__FILE__ ":" STRINGIZE(__LINE__) ": " str "\n")
#define wasi_printc(ch) do { \
const char str[] = { ch }; \
wasi_print(str); \
} while (0)
#endif
9 changes: 8 additions & 1 deletion src/asyncify/asyncify_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// * asyncify_start_rewind(iptr): initiates a continuation
// reinstatement. The argument `iptr` is a pointer to an asyncify
// stack.
// * asyncfiy_stop_rewind(): delimits the extent of a continuation
// * asyncify_stop_rewind(): delimits the extent of a continuation
// reinstatement.
extern
import("start_unwind")
Expand Down Expand Up @@ -226,4 +226,11 @@ void fiber_finalize(void) {
#endif
}

int fiber_main(int (*main)(int, char**), int argc, char** argv) {
fiber_init();
int ans = main(argc, argv);
fiber_finalize();
return ans;
}

#undef import
Loading