@@ -5,6 +5,10 @@ resource-constrained environments. Built with stack-based allocation to avoid
55heap usage and designed to fit within a single cache line for optimal
66performance.
77
8+ > [ !CAUTION]
9+ >
10+ > 🚧 This project is still under construction! 🚧
11+
812## Features
913
1014- ** Stack-based coroutine allocation** - No heap allocations; coroutine frames are allocated from a user-provided stack buffer
@@ -22,22 +26,52 @@ performance.
2226## Requirements
2327
2428- C++23 compiler with coroutine support
25- - Tested with Clang 18+
29+ - Tested with Clang 20+
30+ - Usage of C++20 modules
2631
2732## Stack-Based Allocation
2833
2934Unlike typical coroutine implementations that allocate frames on the heap,
3035` async_context ` uses a stack-based allocation scheme. Each context owns a
3136contiguous buffer of memory that grows upward as coroutines are called.
3237
33- ### Memory Layout
34-
35- > [ !NOTE]
36- >
37- > Will add a diagram here later
38-
3938### How Allocation Works
4039
40+ ``` ascii
41+ ┌─────────────────────────────┐ Address 0
42+ │ &context::m_stack_pointer │
43+ ├─────────────────────────────┤
44+ │ Coroutine Frame A │
45+ │ (promise + locals) │
46+ | (96 B) │
47+ ├─────────────────────────────┤
48+ │ &context::m_stack_pointer │
49+ ├─────────────────────────────┤
50+ │ Coroutine Frame B │
51+ | (192 B) │
52+ │ (promise + locals) │
53+ │ │
54+ │ │
55+ │ │
56+ ├─────────────────────────────┤
57+ │ Stack pointer address │
58+ ├─────────────────────────────┤
59+ │ Coroutine Frame C │
60+ | (128 B) │
61+ │ (promise + locals) │
62+ │ │
63+ ├─────────────────────────────┤
64+ │ Unused Memory │ <-- context::m_stack_pointer
65+ │ │
66+ │ │
67+ │ │
68+ │ │
69+ │ │
70+ │ │
71+ │ │
72+ └─────────────────────────────┘ Address N (bytes of stack memory)
73+ ```
74+
41751 . ** Allocation** : When a coroutine is created, the promise's ` operator new `
4276 requests memory from the context. The context:
4377 - Stores the address of ` m_stack_pointer ` at the current position
@@ -48,13 +82,14 @@ contiguous buffer of memory that grows upward as coroutines are called.
4882 - Reads the stored ` &m_stack_pointer ` from just before the frame
4983 - Resets ` m_stack_pointer ` back to that position
5084
51- This creates a strict LIFO ( stack) discipline— coroutines must complete in
52- reverse order of their creation, which naturally matches how ` co_await ` chains
85+ This creates a strict LIFO stack where coroutines must complete in reverse
86+ order of their creation, which naturally matches how ` co_await ` chains
5387work.
5488
5589### Benefits
5690
57- - ** No heap allocation** : Ideal for embedded systems without dynamic memory
91+ - ** No heap allocation on frame creation** : Ideal for embedded systems without
92+ dynamic memory
5893- ** Deterministic** : Memory usage is bounded by the stack buffer size
5994- ** Cache-friendly** : Coroutine frames are contiguous in memory
6095- ** Fast** : Simple pointer arithmetic instead of malloc/free
0 commit comments