Skip to content

Commit 7e24ee0

Browse files
committed
feat: implement lazy single-consumer Task
1 parent 48df7d9 commit 7e24ee0

14 files changed

Lines changed: 1238 additions & 99 deletions

File tree

.idea/.gitignore

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/cmp.iml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/editor.xml

Lines changed: 350 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
[![ci-windows](https://github.com/mcpplibs/cmp/actions/workflows/ci-windows.yml/badge.svg?branch=main)](https://github.com/mcpplibs/cmp/actions/workflows/ci-windows.yml)
1717

1818
> [!IMPORTANT]
19-
> CMP is currently in its **bootstrap stage**. The package exports the root module
20-
> `mcpplibs.cmp`, but it does not provide coroutine runtime APIs yet.
19+
> CMP now provides its first coroutine primitive: a lazy, single-consumer `Task<T>` / `Task<void>`.
20+
> Scheduling, cancellation, timers, asynchronous I/O, and a public root runner are not implemented.
2121
2222
CMP is being built as a modern coroutine runtime and library on standard stackless C++
2323
coroutines. The intended direction is an explicit `co_await` model that can grow, in small
@@ -71,21 +71,43 @@ cd examples/basic
7171
mcpp run
7272
```
7373

74-
The example exits successfully without output. Its purpose is to prove that an independent mcpp
75-
package can resolve the path dependency and import `mcpplibs.cmp`.
74+
The example prints `Coroutine result: 42` from inside a `Task<void>` coroutine and exits
75+
successfully. It proves that an independent mcpp package can resolve the path dependency, import
76+
`mcpplibs.cmp`, compose Tasks, and execute the synchronous chain.
7677

77-
## Current Module
78+
## Current Task API
7879

7980
```cpp
81+
import std;
8082
import mcpplibs.cmp;
8183

82-
int main() {
83-
return 0;
84+
using mcpplibs::cmp::Task;
85+
86+
Task<int> answer() {
87+
co_return 42;
88+
}
89+
90+
Task<void> print_answer() {
91+
auto value = co_await answer();
92+
std::println("Coroutine result: {}", value);
93+
co_return;
8494
}
8595
```
8696

87-
The module deliberately has no public declarations during bootstrap. Future public APIs will use
88-
the namespace `mcpplibs::cmp`.
97+
`Task` is lazy: calling `answer()` creates a suspended coroutine. It starts when consumed by
98+
`co_await`. A Task is move-only, has one consumer, and can only be awaited as an rvalue. It stores
99+
either a value or an exception, transfers directly between child and continuation, and destroys
100+
an unconsumed frame through RAII. `Task<T&>`, copying, move assignment, and detached execution are
101+
deliberately unsupported.
102+
103+
A translation unit that defines a coroutine must import `std` so the compiler can see the standard
104+
coroutine protocol types. CMP imports `std` privately and does not re-export the whole standard
105+
library.
106+
107+
CMP does not yet provide `sync_wait` or a scheduler, so the current API is a composition primitive
108+
rather than a complete application entry point. The standalone example therefore defines a small,
109+
private root coroutine that is suitable only for its synchronously completing chain. A moved-from
110+
Task must not be awaited.
89111

90112
## Repository Layout
91113

@@ -94,7 +116,7 @@ the namespace `mcpplibs::cmp`.
94116
├── .xlings.json # pinned project tool environment
95117
├── mcpp.toml # package identity and test dependency
96118
├── src/cmp.cppm # root module interface
97-
├── tests/cmp_test.cpp # import smoke test
119+
├── tests/cmp_test.cpp # Task contract and lifetime tests
98120
├── examples/basic/ # standalone path-dependency consumer
99121
├── docs/architecture.md # current structure, boundaries, and evolution
100122
└── .github/workflows/ # Linux, macOS, and Windows CI
@@ -122,17 +144,16 @@ belong in `[dependencies]`; test-only dependencies belong in `[dev-dependencies]
122144

123145
## Roadmap
124146

125-
Runtime work will be split into independently reviewable phases:
147+
Runtime work is split into independently reviewable phases:
126148

127-
1. package identity and importable-module bootstrap;
128-
2. coroutine task and lifetime semantics;
149+
1. package identity and importable-module bootstrap — implemented;
150+
2. coroutine task and lifetime semantics — initial `Task` implemented;
129151
3. a minimal single-thread scheduler;
130152
4. timers, cancellation, and structured wake-up paths;
131153
5. multi-worker scheduling and work stealing;
132154
6. asynchronous I/O integration and a blocking pool.
133155

134-
The order after the bootstrap is directional, not a promise that any listed feature is already
135-
implemented.
156+
The remaining order is directional, not a promise that a listed feature is already implemented.
136157

137158
## Contributing
138159

README.zh.hant.md

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
[![ci-windows](https://github.com/mcpplibs/cmp/actions/workflows/ci-windows.yml/badge.svg?branch=main)](https://github.com/mcpplibs/cmp/actions/workflows/ci-windows.yml)
1717

1818
> [!IMPORTANT]
19-
> CMP 目前處於 **bootstrap 階段**。套件已經匯出根模組 `mcpplibs.cmp`,但尚未提供協程執行期 API。
19+
> CMP 已提供第一個協程基礎型別:延遲啟動、單一消費者的 `Task<T>` / `Task<void>`
20+
> 排程、取消、計時器、非同步 I/O 和公開根任務驅動器尚未實作。
2021
2122
CMP 計畫以標準無堆疊 C++ 協程建構現代協程執行期與函式庫。專案將以明確的 `co_await`
2223
為主線,透過經過驗證的小步驟逐步探索排程、計時器、非同步 I/O、取消,以及阻塞工作的安全隔離。
@@ -66,20 +67,39 @@ cd examples/basic
6667
mcpp run
6768
```
6869

69-
範例會以成功狀態結束且不產生輸出。它只負責證明獨立 mcpp 套件能夠解析路徑相依並匯入
70-
`mcpplibs.cmp`
70+
範例會從 `Task<void>` 協程內部印出 `Coroutine result: 42`,然後以成功狀態結束。它負責
71+
證明獨立 mcpp 套件能夠解析路徑相依、匯入 `mcpplibs.cmp`、組合 Task 並執行同步協程鏈
7172

72-
## 目前模組
73+
## 目前 Task API
7374

7475
```cpp
76+
import std;
7577
import mcpplibs.cmp;
7678

77-
int main() {
78-
return 0;
79+
using mcpplibs::cmp::Task;
80+
81+
Task<int> answer() {
82+
co_return 42;
83+
}
84+
85+
Task<void> print_answer() {
86+
auto value = co_await answer();
87+
std::println("Coroutine result: {}", value);
88+
co_return;
7989
}
8090
```
8191

82-
bootstrap 階段的模組刻意不包含公開宣告。未來公共 API 將使用 `mcpplibs::cmp` 命名空間。
92+
`Task` 採延遲啟動:呼叫 `answer()` 只建立處於暫停狀態的協程,在被 `co_await` 消費時才
93+
開始執行。Task 只能移動、只有一個消費者且只能作為右值等待;它保存值或例外,在子協程與
94+
continuation 之間直接轉移,並透過 RAII 銷毀未消費的協程框架。目前刻意不支援 `Task<T&>`
95+
複製、移動賦值和 detached 執行。
96+
97+
定義協程的轉譯單元必須匯入 `std`,使編譯器能夠看到標準協程協定型別。CMP 私下匯入
98+
`std`,不會向使用端重新匯出整個標準函式庫。
99+
100+
CMP 尚未提供 `sync_wait` 或排程器,因此目前 API 是協程組合基礎,而不是完整的應用程式入口。
101+
獨立範例因此定義了一個很小的私有根協程,只適用於其中同步完成的協程鏈。已經被移動的
102+
Task 不得再次等待。
83103

84104
## 儲存庫結構
85105

@@ -88,7 +108,7 @@ bootstrap 階段的模組刻意不包含公開宣告。未來公共 API 將使
88108
├── .xlings.json # 固定的專案工具環境
89109
├── mcpp.toml # 套件識別與測試相依
90110
├── src/cmp.cppm # 根模組介面
91-
├── tests/cmp_test.cpp # 匯入 smoke 測試
111+
├── tests/cmp_test.cpp # Task 契約和生命週期測試
92112
├── examples/basic/ # 獨立的路徑相依 consumer
93113
├── docs/architecture.zh.hant.md # 目前結構、邊界與演進方向
94114
└── .github/workflows/ # Linux、macOS 和 Windows CI
@@ -114,16 +134,16 @@ CMP 目前不追蹤 `mcpp.lock`,`.gitignore` 明確執行這項儲存庫約定
114134

115135
## 路線圖
116136

117-
執行期工作將拆分為可以獨立審查的階段
137+
執行期工作拆分為可以獨立審查的階段
118138

119-
1. 套件識別與可匯入模組 bootstrap;
120-
2. 協程 task 與生命週期語意;
139+
1. 套件識別與可匯入模組 bootstrap——已完成
140+
2. 協程 task 與生命週期語意——已實作初始 `Task`
121141
3. 最小單執行緒排程器;
122142
4. 計時器、取消和結構化喚醒路徑;
123143
5. 多 worker 排程與 work stealing;
124144
6. 非同步 I/O 整合和 blocking pool。
125145

126-
bootstrap 之後的順序只是方向,不代表這些能力已經實作
146+
剩餘順序只是方向,不代表列出的能力已經實作
127147

128148
## 參與貢獻
129149

README.zh.md

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
[![ci-windows](https://github.com/mcpplibs/cmp/actions/workflows/ci-windows.yml/badge.svg?branch=main)](https://github.com/mcpplibs/cmp/actions/workflows/ci-windows.yml)
1717

1818
> [!IMPORTANT]
19-
> CMP 当前处于 **bootstrap 阶段**。包已经导出根模块 `mcpplibs.cmp`,但尚未提供协程运行时 API。
19+
> CMP 已经提供第一个协程基础类型:懒启动、单消费者的 `Task<T>` / `Task<void>`
20+
> 调度、取消、定时器、异步 I/O 和公共根任务驱动器尚未实现。
2021
2122
CMP 计划基于标准无栈 C++ 协程构建现代协程运行时和库。项目将以显式 `co_await` 为主线,
2223
通过经过验证的小步骤逐步探索调度、定时器、异步 I/O、取消以及阻塞工作的安全隔离。
@@ -66,20 +67,39 @@ cd examples/basic
6667
mcpp run
6768
```
6869

69-
示例会以成功状态退出且不产生输出。它只负责证明独立 mcpp 包能够解析路径依赖并导入
70-
`mcpplibs.cmp`
70+
示例会从 `Task<void>` 协程内部打印 `Coroutine result: 42`,然后以成功状态退出。它负责
71+
证明独立 mcpp 包能够解析路径依赖、导入 `mcpplibs.cmp`、组合 Task 并执行同步协程链
7172

72-
## 当前模块
73+
## 当前 Task API
7374

7475
```cpp
76+
import std;
7577
import mcpplibs.cmp;
7678

77-
int main() {
78-
return 0;
79+
using mcpplibs::cmp::Task;
80+
81+
Task<int> answer() {
82+
co_return 42;
83+
}
84+
85+
Task<void> print_answer() {
86+
auto value = co_await answer();
87+
std::println("Coroutine result: {}", value);
88+
co_return;
7989
}
8090
```
8191

82-
bootstrap 阶段的模块刻意不包含公开声明。未来公共 API 将使用 `mcpplibs::cmp` 命名空间。
92+
`Task` 采用懒启动:调用 `answer()` 只创建处于挂起状态的协程,在被 `co_await` 消费时才
93+
开始执行。Task 只能移动、只有一个消费者且只能作为右值等待;它保存值或异常,在子协程与
94+
continuation 之间直接转移,并通过 RAII 销毁未消费的协程帧。当前刻意不支持 `Task<T&>`
95+
复制、移动赋值和 detached 执行。
96+
97+
定义协程的翻译单元必须导入 `std`,使编译器能够看到标准协程协议类型。CMP 私有导入
98+
`std`,不会向使用方重新导出整个标准库。
99+
100+
CMP 尚未提供 `sync_wait` 或调度器,因此当前 API 是协程组合基础,而不是完整的应用入口。
101+
独立示例因此定义了一个很小的私有根协程,只适用于其中同步完成的协程链。已经被移动的
102+
Task 不得再次等待。
83103

84104
## 仓库结构
85105

@@ -88,7 +108,7 @@ bootstrap 阶段的模块刻意不包含公开声明。未来公共 API 将使
88108
├── .xlings.json # 固定的项目工具环境
89109
├── mcpp.toml # 包身份和测试依赖
90110
├── src/cmp.cppm # 根模块接口
91-
├── tests/cmp_test.cpp # 导入 smoke 测试
111+
├── tests/cmp_test.cpp # Task 契约和生命周期测试
92112
├── examples/basic/ # 独立的路径依赖 consumer
93113
├── docs/architecture.zh.md # 当前结构、边界和演进方向
94114
└── .github/workflows/ # Linux、macOS 和 Windows CI
@@ -114,16 +134,16 @@ CMP 当前不跟踪 `mcpp.lock`,`.gitignore` 明确执行这一仓库约定。
114134

115135
## 路线图
116136

117-
运行时工作将拆分为可以独立审查的阶段
137+
运行时工作拆分为可以独立审查的阶段
118138

119-
1. 包身份和可导入模块 bootstrap;
120-
2. 协程 task 与生命周期语义;
139+
1. 包身份和可导入模块 bootstrap——已完成
140+
2. 协程 task 与生命周期语义——已实现初始 `Task`
121141
3. 最小单线程调度器;
122142
4. 定时器、取消和结构化唤醒路径;
123143
5. 多 worker 调度与 work stealing;
124144
6. 异步 I/O 集成和 blocking pool。
125145

126-
bootstrap 之后的顺序只是方向,不代表这些能力已经实现
146+
剩余顺序只是方向,不代表列出的能力已经实现
127147

128148
## 参与贡献
129149

0 commit comments

Comments
 (0)