Skip to content

Commit 7e323be

Browse files
committed
add more docs
1 parent e072a60 commit 7e323be

File tree

9 files changed

+132
-8
lines changed

9 files changed

+132
-8
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ fn main() {
189189
- [Coroutine Overview](core/docs/en/coroutine.md)
190190
- [Scalable Stack Overview](core/docs/en/scalable-stack.md)
191191
- [Monitor Overview](core/docs/en/monitor.md)
192+
- [Work Steal Overview](core/docs/en/work-steal.md)
193+
- [Ordered Work Steal Overview](core/docs/en/ordered-work-steal.md)
194+
- [Coroutine Pool Overview](core/docs/en/coroutine-pool.md)
192195

193196
[我有故事,你有酒吗?](https://github.com/acl-dev/open-coroutine-docs)
194197

core/docs/en/coroutine-pool.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
---
2+
title: Coroutine Pool Overview
3+
date: 2025-01-18 10:00:00
4+
author: loongs-zhang
5+
---
6+
7+
# Coroutine Pool Overview
8+
9+
## Usage
10+
11+
```rust
12+
use open_coroutine_core::co_pool::CoroutinePool;
13+
14+
fn main() -> std::io::Result<()> {
15+
let mut pool = CoroutinePool::default();
16+
assert!(pool.is_empty());
17+
pool.submit_task(
18+
Some(String::from(task_name)),
19+
|_| {
20+
println!("Hello, world!");
21+
Some(2)
22+
},
23+
None,
24+
None,
25+
)?;
26+
assert!(!pool.is_empty());
27+
pool.try_schedule_task()
28+
}
29+
```
30+
31+
## Why coroutine pool?
32+
33+
Pooling the coroutines can bring several significant advantages:
34+
35+
1. Resource management: The coroutine pool can manage the creation, destruction, and reuse of coroutines. By using a
36+
coroutine pool, a certain number of coroutines can be created in advance and stored in the pool for use when needed.
37+
This can avoid frequent creation and destruction of coroutines, reduce unnecessary resource waste, and improve system
38+
performance.
39+
40+
2. Avoid coroutine hunger: When using a coroutine pool, coroutines will be continuously provided with tasks, avoiding
41+
the situation where coroutines are idle after completing tasks.
42+
43+
3. Concurrency control: By setting the parameters of the coroutine pool, the number of concurrent coroutines can be
44+
limited to avoid overloading the system due to too many coroutines.
45+
46+
4. Improve code maintainability: Using coroutine pools can separate task execution from coroutine management, making the
47+
code clearer and more maintainable. The execution logic of a task can be focused on the task itself, while the
48+
creation and management of coroutines are handled by the coroutine pool.
49+
50+
## How it works
51+
52+
In open-coroutine-core, the coroutine pool is lazy, which means if you don't call `try_timeout_schedule_task`, tasks
53+
will not be executed. Please refer to the flowchart below for details:
54+
55+
```mermaid
56+
sequenceDiagram
57+
Actor Schedule Thread
58+
participant CoroutinePool
59+
participant WorkerCoroutine
60+
participant Task
61+
participant CoroutineCreator
62+
63+
Schedule Thread ->>+ CoroutinePool: CoroutinePool::try_timeout_schedule_task
64+
alt the coroutine pool is stopped
65+
CoroutinePool ->>+ Schedule Thread: return error
66+
end
67+
alt the task queue in the coroutine pool is empty
68+
CoroutinePool ->>+ Schedule Thread: return success
69+
end
70+
alt create worker coroutines
71+
CoroutinePool ->>+ WorkerCoroutine: create worker coroutines only if the coroutine pool has not reached its maximum pool size
72+
end
73+
CoroutinePool ->>+ WorkerCoroutine: schedule the worker coroutines
74+
alt run tasks
75+
WorkerCoroutine ->>+ Task: try poll a task
76+
alt poll success
77+
Task ->>+ Task: run the task
78+
alt in execution
79+
Task ->>+ WorkerCoroutine: be preempted or enter syscall
80+
WorkerCoroutine ->>+ WorkerCoroutine: The coroutine state changes to Suspend/Syscall
81+
WorkerCoroutine ->>+ CoroutineCreator: Listener::on_state_changed
82+
CoroutineCreator ->>+ WorkerCoroutine: create worker coroutines only if the coroutine pool has not reached its maximum pool size
83+
end
84+
alt run success
85+
Task ->>+ WorkerCoroutine: Task exited normally
86+
end
87+
alt run fail
88+
Task ->>+ WorkerCoroutine: Task exited abnormally
89+
WorkerCoroutine ->>+ WorkerCoroutine: The coroutine state changes to Error
90+
WorkerCoroutine ->>+ CoroutineCreator: Listener::on_state_changed
91+
CoroutineCreator ->>+ CoroutineCreator: reduce the current coroutine count
92+
CoroutineCreator ->>+ WorkerCoroutine: recreate worker coroutine only if the coroutine pool has not reached its maximum pool size
93+
end
94+
end
95+
alt poll fail
96+
Task ->>+ WorkerCoroutine: increase count and yield to the next coroutine
97+
WorkerCoroutine ->>+ WorkerCoroutine: block for a while if the count has reached the current size of coroutine pool
98+
end
99+
WorkerCoroutine ->>+ WorkerCoroutine: try poll the next task
100+
end
101+
alt recycle coroutines
102+
WorkerCoroutine ->>+ WorkerCoroutine: the schedule has exceeded the timeout time
103+
WorkerCoroutine ->>+ CoroutinePool: has the coroutine pool exceeded the minimum pool size?
104+
CoroutinePool ->>+ WorkerCoroutine: yes
105+
WorkerCoroutine ->>+ WorkerCoroutine: exit
106+
end
107+
WorkerCoroutine ->>+ CoroutinePool: return if timeout or schedule fail
108+
CoroutinePool ->>+ Schedule Thread: This schedule has ended
109+
Schedule Thread ->>+ Schedule Thread: ......
110+
```

core/docs/en/monitor.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ fn main() -> std::io::Result<()> {
3939
}
4040
```
4141

42-
## What is monitor?
43-
44-
The `monitor` mod implements the `preemptive` feature for open-coroutine, which allows the coroutine to be preempted
45-
when it is running for a long time.
46-
4742
## Why preempt?
4843

4944
After a `Coroutine::resume_with`, a coroutine may occupy the scheduling thread for a long time, thereby slowing down
@@ -53,6 +48,11 @@ automatically suspends coroutines that are stuck in long-term execution and allo
5348
The coroutine occupies scheduling threads for a long time in two scenarios: getting stuck in heavy computing or syscall.
5449
The following only solves the problem of getting stuck in heavy computing.
5550

51+
## What is monitor?
52+
53+
The `monitor` mod implements the `preemptive` feature for open-coroutine, which allows the coroutine to be preempted
54+
when it is running for a long time.
55+
5656
## How it works
5757

5858
```mermaid

core/docs/en/ordered-work-steal.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ priority, the earlier it will be popped up.
2222
## What is ordered work steal queue?
2323

2424
An ordered work steal queue consists of a global queue and multiple local queues, the global queue is unbounded, while
25-
the local queue has a bounded SkipList with collections. To ensure high performance, the number of local queues is
26-
usually equal to the number of threads.
25+
the local queue has a bounded `SkipList` with collections. To ensure high performance, the number of local queues is
26+
usually equal to the number of threads. I's worth mentioning that if all threads prioritize local tasks, there will be
27+
an extreme situation where tasks on the shared queue will never have a chance to be scheduled. To avoid this imbalance,
28+
refer to goroutine, every time a thread has scheduled 60 tasks from the local queue, it will be forced to pop the
29+
`highest priority task` from the shared queue.
2730

2831
## How `push` works
2932

core/docs/en/overview.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ replacement for IO thread pools, see [why better](../en/why-better.md).
2626
- [Coroutine Overview](../en/coroutine.md)
2727
- [Scalable Stack Overview](../en/scalable-stack.md)
2828
- [Monitor Overview](../en/monitor.md)
29+
- [Work Steal Overview](../en/work-steal.md)
30+
- [Ordered Work Steal Overview](../en/ordered-work-steal.md)
31+
- [Coroutine Pool Overview](../en/coroutine-pool.md)

core/docs/en/work-steal.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ better to let them help other threads work.
2222

2323
A work steal queue consists of a global queue and multiple local queues, the global queue is unbounded, while the local
2424
queue has a bounded RingBuffer. To ensure high performance, the number of local queues is usually equal to the number of
25-
threads.
25+
threads. I's worth mentioning that if all threads prioritize local tasks, there will be an extreme situation where tasks
26+
on the shared queue will never have a chance to be scheduled. To avoid this imbalance, refer to goroutine, every time a
27+
thread has scheduled 60 tasks from the local queue, it will be forced to pop a task from the shared queue.
2628

2729
## How `push` works
2830

core/src/co_pool/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub struct CoroutinePool<'p> {
3232
//协程池状态
3333
state: Cell<PoolState>,
3434
//任务队列
35+
#[doc = include_str!("../../docs/en/ordered-work-steal.md")]
3536
task_queue: OrderedLocalQueue<'p, Task<'p>>,
3637
//工作协程组
3738
workers: Scheduler<'p>,

core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ mod monitor;
7171
pub mod scheduler;
7272

7373
/// Coroutine pool abstraction and impl.
74+
#[doc = include_str!("../docs/en/coroutine-pool.md")]
7475
pub mod co_pool;
7576

7677
/// net abstraction and impl.

core/src/scheduler.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ pub struct Scheduler<'s> {
8585
name: String,
8686
stack_size: AtomicUsize,
8787
listeners: VecDeque<&'s dyn Listener<(), Option<usize>>>,
88+
#[doc = include_str!("../docs/en/ordered-work-steal.md")]
8889
ready: OrderedLocalQueue<'s, SchedulableCoroutine<'s>>,
8990
suspend: BinaryHeap<SuspendItem<'s>>,
9091
syscall: DashMap<&'s str, SchedulableCoroutine<'s>>,

0 commit comments

Comments
 (0)