CMP (Coroutine Machine Process) is a C++23 Modules coroutine runtime with tasks, structured concurrency, explicit scheduling, synchronization primitives, and native async TCP.
Install xlings, then run from the repository root:
xlings install
mcpp --version
mcpp build
mcpp test.xlings.json pins mcpp. The root library uses LLVM 22.1.8; standalone examples use GCC 16.1.0 on Linux and LLVM 22.1.8 on macOS/Windows.
Run the complete example covering the main APIs:
cd examples/basic
mcpp runCreate demo/ beside cmp/ and copy the repository's .xlings.json into it. Create demo/mcpp.toml, adjusting the dependency path if your checkout has a different name:
[package]
name = "cmp-demo"
version = "0.1.0"
standard = "c++23"
[dependencies.mcpplibs]
cmp = { path = "../cmp" }
[toolchain]
default = "llvm@22.1.8"
linux = "gcc@16.1.0"Create demo/src/main.cpp:
import std;
import mcpplibs.cmp;
namespace cmp = mcpplibs::cmp;
cmp::Task<int> answer(cmp::RunLoop::Scheduler scheduler) {
co_await scheduler.schedule();
co_return 42;
}
int main() {
cmp::RunLoop loop {};
std::println("{}", loop.run(answer(loop.get_scheduler())));
}Run from demo/:
xlings install
mcpp runThe program prints 42. A Task starts lazily; run() drives the root task, and schedule() queues the coroutine on that RunLoop. Coroutine source files must import both std and mcpplibs.cmp.
| Purpose | API |
|---|---|
| Tasks and results | Task<T>, Task<void> |
| Structured concurrency | when_all(), TaskGroup |
| Scheduling and timers | RunLoop, ThreadPool, schedule(), schedule_after(), schedule_at(); only RunLoop provides timers |
| Events and mutual exclusion | OneShotEvent, AsyncManualResetEvent, AsyncMutex |
| Blocking work isolation | run_blocking() with a separate ThreadPool instance |
| TCP clients and servers | IoContext, TcpStream, TcpListener |
| Cooperative cancellation | Pass std::stop_token explicitly; a winning cancellation throws OperationCancelled |
- Tasks are move-only and single-consumer. Pass a named Task to
co_awaitor a combinator withstd::move(). - A used TaskGroup must finish
join()before leaving scope, including on exception paths. - Cancellation and thread switches are explicit. Blocking functions block their current thread; cancellation cannot interrupt a synchronous call that has started.
- Events, mutexes, executors, and borrowed TCP buffers must outlive their use. See Architecture for lifetime and error contracts.
Detached execution, work stealing, DNS, TLS, native async file I/O, channels, and general timeout/race combinators are not provided.
- Architecture and minimal usage: execution, cancellation, TCP contracts, and strict validation commands
- Comparison with Go GMP (Chinese): implementation status, technical limits, and follow-up tasks
- Tests and the complete example: executable API usage
- Readiness benchmark and thread-pool benchmark: local workloads and performance measurements
- Implementation and validation record (Chinese): verified results, platform gaps, and future work
- mcpp · Issues
License: Apache License 2.0.