Skip to content
/ cfiber Public

A lightweight, portable fiber library (stackful coroutines) for cooperative multitasking on bare-metal and hosted environments.

License

Notifications You must be signed in to change notification settings

aotodev/cfiber

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cfiber

License: MIT format x86-64 aarch64 cortex-m0 cortex-m3 cortex-m4 cortex-m7

Overview

cfiber provides an efficient implementation of fibers (also known as stackful coroutines, non-preemptive threads, or cooperative threads) with support for multiple architectures:

  • x86_64 (Linux only)
  • AArch64 (ARM 64-bit)
  • ARM Cortex-M (M0, M0+, M3, M4, M7) with optional FPU support

Fibers enable cooperative multitasking where tasks explicitly yield control, making them ideal for:

  • Async I/O frameworks
  • Embedded systems with resource constraints
  • Game engines and simulation loops
  • Any scenario where deterministic, low-overhead task switching is required

Features

  • Zero dependencies - Pure C and assembly implementation
  • Minimal overhead - Direct context switching without OS scheduler involvement, no dynamic memory allocation
  • Portable - Clean separation of architecture-specific code
  • Embedded-friendly - Designed for bare-metal ARM Cortex-M microcontrollers
  • ABI-compliant - Follows platform calling conventions (System V AMD64, AAPCS, AAPCS64)
  • FPU support - Optional floating-point context preservation on ARM Cortex-M4F/M7F

Freestanding Support

This library is freestanding-compatible and can be used in environments without a standard C library. It only depends on freestanding headers (<stdint.h>, <stddef.h>) and requires no runtime support.

Suitable for:

  • Embedded systems
  • Bootloaders
  • Kernel development
  • Any -ffreestanding compilation target

Architecture Support

Architecture Status Notes
x86_64 Supported Linux (System V AMD64 ABI)
AArch64 (ARM64) Supported 64-bit ARM (AAPCS64)
ARM Cortex-M0 Supported ARMv6-M (Thumb-1)
ARM Cortex-M0+ Supported ARMv6-M (Thumb-1)
ARM Cortex-M3 Supported ARMv7-M (Thumb-2)
ARM Cortex-M4 Supported ARMv7-M with optional FPU
ARM Cortex-M7 Supported ARMv7E-M with optional FPU

Integrating cfiber into Your Project

Using CMake add_subdirectory

The easiest way to integrate cfiber into your CMake project is using add_subdirectory:

  1. Add cfiber as a subdirectory in your project:

    # Option 1: Clone as a git submodule
    git submodule add https://github.com/aotodev/cfiber.git external/cfiber
    
    # Option 2: Copy the cfiber directory into your project
    cp -r /path/to/cfiber_external/cfiber
  2. Update your CMakeLists.txt:

    cmake_minimum_required(VERSION 3.28)
    project(my_project)
    
    # Add cfiber as a subdirectory
    add_subdirectory(external/cfiber)
    
    # Create your executable
    add_executable(my_app main.c)
    
    # Link against cfiber
    target_link_libraries(my_app PRIVATE cfiber)
    
    # cfiber's include directories are automatically available
  3. Use in your code:

    #include "cfiber/fiber.h"
    #include "cfiber/context.h"
    
    // Your code here

The cfiber library will automatically detect your target architecture and build accordingly. For cross-compilation to ARM Cortex-M, ensure you set up your toolchain file before calling add_subdirectory().

Building

Prerequisites

  • CMake 3.28 or newer
  • GCC/Clang for x86_64 and AArch64
  • ARM GCC toolchain for ARM Cortex-M targets

Note: cfiber uses GNU extensions and is supported only by GNU compilers (GCC, aarch64-linux-gnu-gcc, arm-none-eabi-gcc, etc.) and LLVM (Clang). Other compilers are not supported.

Quick Start (x86_64/AArch64)

# Build library
mkdir build && cd build
cmake ..
make

# Build with sample
cmake -DBUILD_SAMPLE=ON ..
make
./sample/sample

# Build with tests
cmake -DBUILD_TESTS=ON ..
make
ctest

Cross-Compilation for ARM Cortex-M

# Example for Cortex-M4 with FPU
mkdir build-arm && cd build-arm
cmake .. \
    -DCMAKE_TOOLCHAIN_FILE=../utils/cmake/toolchain-arm.cmake \
    -DCFIBER_SYSTEM_PROCESSOR=arm \
    -DCFIBER_TARGET_CPU=cortex-m4 \
    -DCFIBER_ARM_FLOAT_ABI=hard \
    -DCFIBER_ARM_FPU=fpv4-sp-d16 \
    -DBUILD_TESTS=ON
make

Cortex-M Build Options

  • CFIBER_TARGET_CPU: cortex-m0, cortex-m0plus, cortex-m3, cortex-m4, cortex-m7
  • CFIBER_ARM_FLOAT_ABI: soft, softfp, hard (required for FPU support)
  • CFIBER_ARM_FPU: fpv4-sp-d16, fpv5-d16, etc. (defines FPU to use)

For Cortex-M4/M7 with FPU (hardware floating-point):

-DCFIBER_ARM_FLOAT_ABI=hard -DCFIBER_ARM_FPU=fpv4-sp-d16

For Cortex-M0/M0+/M3 (no FPU):

-DCFIBER_ARM_FLOAT_ABI=soft

Build Convenience Script

The project includes a helper script for common build configurations:

./utils/make.sh

# Examples:
./utils/make.sh --arch=aarch64
./utils/make.sh --arch=arm --cpu=cortex-m4

# for debug build. Default is release
./utils/make.sh --arch=aarch64 -d 

# native build
./utils/make.sh 

Usage

Basic Fiber Example

#include "cfiber/fiber.h"
#include "cfiber/context.h"
#include <stdio.h>
#include <stdlib.h>

// Define a fiber function
void my_fiber(void* user_data) {
    int* counter = (int*)user_data;
    
    while (*counter > 0) {
        printf("Fiber running: %d\n", *counter);
        (*counter)--;
        
        // Yield control back to scheduler
        yield();
    }
    
    printf("Fiber complete!\n");
}

int main() {
    // Allocate stack for the fiber
    const size_t stack_size = 8192;
    uint8_t* stack = malloc(stack_size);
    
    // Create and initialize fiber
    fiber_t fiber = {
        .stack = stack,
        .stack_size = stack_size
    };
    
    int counter = 5;
    init_fiber(&fiber, my_fiber, &counter);
    
    // In a real scheduler, you would call switch_context
    // to switch between fibers and the main scheduler context
    
    free(stack);
    return 0;
}

Complete Scheduler Example

See the sample/ directory for a complete working example with:

  • Multiple fiber scheduling
  • Nested fiber spawning
  • Graceful fiber completion handling
  • Round-robin scheduling implementation

The sample demonstrates:

// Initialize runtime with stack size
scheduler_init(8192);

// Spawn fibers
scheduler_spawn(my_function, user_data);
scheduler_spawn(another_function, other_data);

// Start scheduler (blocks until all fibers complete)
scheduler_run();

// Cleanup
scheduler_cleanup();

Building and runing the example:

  • using the host architecture
# Release by default
./utils/make.sh -s

# try in debug
./utils/make.sh -s -d
  • cross compiling and running with qemu
./utils/make.sh --arch=aarch64 -s
./utils/make.sh --arch=arm --cpu=cortex-m4 -s

# with FPU(script sets all FPU required flags)
./utils/make.sh --arch=arm --cpu=cortex-m7 -s

API Reference

For complete API documentation including all types, functions, and architecture-specific details, see:

API Reference Documentation

Quick Reference

Core Types:

  • fiber_t - Fiber structure (context, stack pointer, stack size)
  • fiber_fn - Function signature for fiber entry points

Core Functions:

  • init_fiber() - Initialize a fiber with a function and user data
  • switch_context() - Switch between execution contexts
  • scheduler_return_fiber() - Scheduler callback (you implement this)

See the full API reference for detailed documentation, usage examples, and platform-specific information.

Documentation

For comprehensive documentation about how cfiber works internally, see:

Architecture Documentation

This includes:

  • How context switching works
  • Fiber initialization process
  • Memory layout and stack management
  • Platform-specific implementation details
  • Performance characteristics and optimization tips
  • FPU handling on ARM Cortex-M
  • Integration with RTOS
  • Usage guidelines and best practices

Testing

The project includes comprehensive unit tests for all architectures:

# Native tests (x86_64/AArch64)
./utils/make.sh -t

# Cross-compile and test with qemu
./utils/make.sh --arch=aarch64 -t
./utils/make.sh --arch=arm --cpu=cortex-m0 -t # armv6
./utils/make.sh --arch=arm --cpu=cortex-m3 -t # armv7 without FPU
./utils/make.sh --arch=arm --cpu=cortex-m7 -t # armv7 with FPU

Test coverage includes:

  • Basic context switching
  • Register preservation
  • Stack integrity
  • FPU register preservation (ARM)
  • Multiple fiber coordination

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

A lightweight, portable fiber library (stackful coroutines) for cooperative multitasking on bare-metal and hosted environments.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published