libcommunism

A C++ cooperative threading library

libcommunism is intended to be a really, really fast, portable, and small implementation of cooperative multithreading in userspace. It provides a common C++ interface to clients, similar to the C++ std::thread class. The caller decides when threads are executed by explicitly switching to them function call style.

Like kernel threads, each cooperative thread (cothread) has its own stack. By performing the context switching in user space (i.e. making it explicit by calling the thread’s switchTo() method) the significant cost of a switch into the kernel, and the associated kernel processing time is completely removed.

It is freely available under the terms of the ISC license.

Supported Platforms

The library is supported on most any system with a reasonably standards compliant C library, because it can make use of the standard sigsetjmp() and setcontext() family of functions. This means it is not tied to any particular operating system or compiler.

Unless overridden, the build script will automatically select the best suitable optimized implementation, and if none are suitable, fall back to the best available generic implementation.

Optimized Implementations

In addition to the generic platforms, the following performance optimized platform choices are available:

Adding optimized implementations for new platforms is relatively easy; only a thin shim needs to be developed, which may require a few small assembly routines to switch thread context. Feel free to submit pull requests to add new platforms.

Requirements

There are no external requirements for using the library besides a functioning C++ compiler. The library itself requires C++20 (due to use of std::span<T>) and CMake to build.

Building and Installation

Use your favorite CMake generator to generate the build files for the library and build it; by default, this will result in a static library. You can then easily link against it by its name after installing it to the system.

Alternatively, if you are using CMake, simply include the subdirectory containing this library (use the FetchContent module against the library repository, if possible) in your project’s CMakeLists.txt, and then link against it like so:

target_link_libraries(TARGET_NAME PUBLIC libcommunism)

The main header of libcommunism/Cothread.h is currently the only required header required to use the library.

Configuration

There are not very many tuneables for the library. Please see the build options pages for available options to influence the produced library.

Releases

All releases of the library are available on GitHub. There you can find the associated release notes and source tarballs.

Tests

Tests are provided with the library. They use the Catch2 framework, and are built by the tests target. Do note that these tests only cover the host’s architecture. While simple, they do a reasonable job exercising the most commonly used library methods.

Benchmarks

One of the tests attempts to benchmark the context switching time. Approximate context switching times are:

Documentation

Generate Docs

For documentation on how to use the library, and how its internals are constructed, please see the autogenerated Doxygen documentation pages. These pages always reflect the current state of the main branch of the repository.

Examples

Proper examples will be provided soon. For now, take a look at the following snippet:

#include <libcommunism/Cothread.h>

static libcommunism::Cothread *thread1, *thread2;

thread1 = new libcommunism::Cothread([](void *) {
    do {
        puts("Hello from cothread 1!");
        thread2->switchTo();
    } while(1);
});
thread2 = new libcommunism::Cothread([](void *) {
    do {
        puts("Hello from cothread 2!");
        thread1->switchTo();
    } while(1);
});

thread1->switchTo();

The above code will have two cooperative threads passing control back and forth forever, printing alternating lines of “Hello from cothread 1/2.”