Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a1f8811
Created hello_switch.c (hello_.c but using fiber_switch)
yinamy Dec 15, 2025
542f29c
Revert "Created hello_switch.c (hello_.c but using fiber_switch)"
yinamy Dec 15, 2025
abdffba
Reapply "Created hello_switch.c (hello_.c but using fiber_switch)"
yinamy Dec 15, 2025
7fe2296
Updated hello_switch.c to working version
yinamy Dec 15, 2025
f8d0a0b
Implemented fiber-switch interface with asyncify, it works with hello…
yinamy Dec 15, 2025
0d22c5f
Apply suggestions from code review
yinamy Dec 16, 2025
80e4fee
Renamed fiber-switch.h to fiber_switch.h
yinamy Dec 16, 2025
43ab195
Created `fiber_main` in `asyncify_switch_impl.c` as per Daniel's sugg…
yinamy Dec 19, 2025
a0c1475
Removed fiber-switch.h
yinamy Dec 21, 2025
83f8a28
Update inc/fiber_switch.h
yinamy Dec 21, 2025
8b9f0c5
Update src/asyncify/asyncify_switch_impl.c
yinamy Dec 21, 2025
190d183
Update src/asyncify/asyncify_switch_impl.c
yinamy Dec 21, 2025
8ababac
Update src/asyncify/asyncify_switch_impl.c
yinamy Dec 21, 2025
4158af5
Merge branch 'switch' of github.com:yinamy/fiber-c into switch
yinamy Dec 21, 2025
400ba86
Changed get_active_fiber() to get_main_fiber(), added a check to fibe…
yinamy Dec 21, 2025
d583ef1
Added/implemented a function `fiber_return_switch` to interface, whic…
yinamy Dec 22, 2025
8e225e6
Changed `fiber_entry_point_t` to take one more argument
yinamy Jan 8, 2026
1266cad
Added itersum_switch.c
yinamy Jan 22, 2026
322bc02
Added treesum_switch.c
yinamy Jan 23, 2026
401859c
Update src/asyncify/asyncify_switch_impl.c
yinamy Jan 29, 2026
536fd58
Update src/asyncify/asyncify_switch_impl.c
yinamy Jan 29, 2026
4b95ee9
Update src/asyncify/asyncify_switch_impl.c
yinamy Jan 29, 2026
7078500
Update src/asyncify/asyncify_switch_impl.c
yinamy Jan 29, 2026
b956688
Update inc/fiber_switch.h
yinamy Jan 29, 2026
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
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ endif
all: hello sieve itersum treesum

.PHONY: hello
hello: hello_asyncify.wasm hello_wasmfx.wasm
hello: hello_asyncify.wasm hello_asyncify_switch.wasm hello_wasmfx.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
$(ASYNCIFY) hello_asyncfiy.pre.wasm -o hello_asyncify.wasm
chmod +x hello_asyncify.wasm

# new stuff: build with switch
hello_asyncify_switch.wasm: inc/fiber-switch.h src/asyncify/asyncify_switch_impl.c examples/hello_switch.c
$(WASICC) -DSTACK_POOL_SIZE=$(STACK_POOL_SIZE) -DASYNCIFY_DEFAULT_STACK_SIZE=$(ASYNCIFY_DEFAULT_STACK_SIZE) src/asyncify/asyncify_switch_impl.c $(WASIFLAGS) examples/hello_switch.c -o hello_asyncfiy_switch.pre.wasm
$(ASYNCIFY) hello_asyncfiy_switch.pre.wasm -o hello_asyncify_switch.wasm
chmod +x hello_asyncify_switch.wasm

hello_wasmfx.wasm: inc/fiber.h src/wasmfx/imports.wat src/wasmfx/wasmfx_impl.c examples/hello.c
$(WASICC) $(SHADOW_STACK_FLAG) -DWASMFX_CONT_SHADOW_STACK_SIZE=$(WASMFX_CONT_SHADOW_STACK_SIZE) -DWASMFX_CONT_TABLE_INITIAL_CAPACITY=$(WASMFX_CONT_TABLE_INITIAL_CAPACITY) -Wl,--export-table,--export-memory,--export=__stack_pointer src/wasmfx/wasmfx_impl.c $(WASIFLAGS) examples/hello.c -o hello_wasmfx.pre.wasm
$(WASM_INTERP) -d -i src/wasmfx/imports.wat -o fiber_wasmfx_imports.wasm
Expand Down
70 changes: 70 additions & 0 deletions examples/hello_switch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Cooperative printing of "hello world"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fiber-switch.h>

static volatile fiber_t hello_fiber;
static volatile fiber_t world_fiber;

fiber_result_t status;

bool hello_done;
bool world_done;


void* hello(void *arg) {
uint32_t i = (uint32_t)(uintptr_t)arg;

static const char s[] = "hlowrd";

if (!hello_done){
while (i < strlen(s)) {
putc(s[i], stdout);
i = (uint32_t)(uintptr_t)fiber_switch(world_fiber, (void*)(uintptr_t)i, &status);
if (status == FIBER_OK) hello_done = true;
}
}

return NULL;
}

void* world(void *arg) {
uint32_t i = (uint32_t)(uintptr_t)arg;
static const char s[] = "el ol";

if (!world_done) {
putc(s[i], stdout);
i++;
i = (uint32_t)(uintptr_t)fiber_switch(hello_fiber, (void*)(uintptr_t)i, &status);
if (status == FIBER_OK) world_done = true;
}

return NULL;
}

int main(void) {
fiber_init();

hello_fiber = fiber_alloc(hello);
world_fiber = fiber_alloc(world);

hello_done = false;
world_done = false;

uint32_t i = 0;

(void)fiber_resume(hello_fiber, (void*)(uintptr_t)i, &status);

putc('\n', stdout);
fflush(stdout);

fiber_free(hello_fiber);
fiber_free(world_fiber);

fiber_finalize();
return 0;
}
56 changes: 56 additions & 0 deletions inc/fiber-switch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/** A basic fiber interface. **/
#ifndef WASMFX_FIBER_C_H
#define WASMFX_FIBER_C_H

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

/** The signature of a fiber entry point. **/
typedef void* (*fiber_entry_point_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 its parent context. This function must be called
from within a fiber context. **/
export("fiber_yield")
void* fiber_yield(void *arg);

/** Possible status codes for `fiber_switch`. **/
typedef enum { FIBER_OK = 0, FIBER_YIELD = 1, FIBER_ERROR = 2 } 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")
void* fiber_resume(fiber_t fiber, void *arg, fiber_result_t *status);

/** Switches to 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_switch")
void* fiber_switch(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);

#undef export
#endif
Loading