Skip to content

Commit

Permalink
enhance README.md (#347)
Browse files Browse the repository at this point in the history
  • Loading branch information
loongs-zhang authored Dec 21, 2024
2 parents bc15b2b + 9fee264 commit 855619e
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 243 deletions.
82 changes: 82 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
### 0.6.x

- [x] support custom task and coroutine priority.
- [x] support scalable stack

### 0.5.x

- [x] refactor syscall state, distinguish between state and innerState

### 0.4.x

- [x] Supports and is compatible with io_uring in terms of local file IO
- [x] elegant shutdown
- [x] use log instead of println
- [x] enhance `#[open_coroutine::main]` macro
- [x] refactor hook impl, no need to publish dylibs now
- [x] `Monitor` follow the `thread-per-core` guideline
- [x] `EventLoop` follow the `thread-per-core` guideline

### 0.3.x

- [x] ~~support `genawaiter` as low_level stackless coroutine (can't support it due to hook)~~
- [x] use `corosensei` as low_level coroutine
- [x] support backtrace
- [x] support `#[open_coroutine::co]` macro
- [x] refactor `WorkStealQueue`

### 0.2.x

- [x] use correct `epoll_event` struct
- [x] use `rayon` for parallel computing
- [x] support `#[open_coroutine::main]` macro
- [x] hook almost all `read` syscall
<details>
<summary>read syscalls</summary>

- [x] recv
- [x] readv
- [x] pread
- [x] preadv
- [x] recvfrom
- [x] recvmsg

</details>

- [x] hook almost all `write` syscall
<details>
<summary>write syscalls</summary>

- [x] send
- [x] writev
- [x] sendto
- [x] sendmsg
- [x] pwrite
- [x] pwritev

</details>

- [x] hook other syscall
<details>
<summary>other syscalls</summary>

- [x] sleep
- [x] usleep
- [x] nanosleep
- [x] connect
- [x] listen
- [x] accept
- [x] shutdown
- [x] poll
- [x] select

</details>

### 0.1.x

- [x] basic suspend/resume supported
- [x] use jemalloc as memory pool
- [x] higher level coroutine abstraction supported
- [x] preemptive scheduling supported
- [x] work stealing supported
- [x] sleep system call hooks supported
281 changes: 38 additions & 243 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,24 @@

The `open-coroutine` is a simple, efficient and generic stackful-coroutine library.

<div style="text-align: center;">
<img src="https://github.com/acl-dev/open-coroutine-docs/blob/master/img/architecture.png" width="100%">
</div>
## 🚀 Features

[我有故事,你有酒吗?](https://github.com/acl-dev/open-coroutine-docs)
- [x] Preemptive(`not supported in windows`): even if the coroutine enters a dead loop, it can still be seized, see [example](https://github.com/loongs-zhang/open-coroutine/blob/master/open-coroutine/examples/preemptive.rs);
- [x] Hook: you are free to use most of the slow system calls in coroutine;
- [x] Scalable: the size of the coroutine stack supports unlimited expansion, and immediately shrinks to the original size after use, see [example](https://github.com/loongs-zhang/open-coroutine/blob/master/open-coroutine/examples/scalable_stack.rs);
- [x] io_uring(`only in linux`): supports and is compatible with io_uring in terms of local file IO and network IO. If it's not supported on your system, it will fall back to non-blocking IO;
- [x] Priority: support custom task and coroutine priority;
- [x] Work Stealing: internally using a lock free work steel queue;
- [x] Compatibility: the implementation of open-coroutine is no async, but it is compatible with async, which means you can use this crate in tokeno/sync-std/smol/...;
- [x] Platforms: running on Linux, MacOS and Windows;

## Status
## 🕊 Roadmap

Still under development, please `do not` use this library in the `production` environment !
- [ ] support `#[open_coroutine::all_join]` and `#[open_coroutine::any_join]` macro to wait coroutines;
- [ ] add synchronization toolkit;
- [ ] support and compatibility for AF_XDP socket;

## How to use this library ?
## 📖 Quick Start

### step1: add dependency to your Cargo.toml

Expand All @@ -39,253 +46,41 @@ fn main() {
}
```

### step3: enjoy the performance improvement brought by open-coroutine !

## Examples

### Amazing preemptive schedule

Note: not supported for windows
### step3: create a task

```rust
#[open_coroutine::main]
fn main() -> std::io::Result<()> {
cfg_if::cfg_if! {
if #[cfg(all(unix, feature = "preemptive-schedule"))] {
use open_coroutine_core::scheduler::Scheduler;
use std::sync::{Arc, Condvar, Mutex};
use std::time::Duration;

static mut TEST_FLAG1: bool = true;
static mut TEST_FLAG2: bool = true;
let pair = Arc::new((Mutex::new(true), Condvar::new()));
let pair2 = Arc::clone(&pair);
let handler = std::thread::Builder::new()
.name("preemptive".to_string())
.spawn(move || {
let scheduler = Scheduler::new();
_ = scheduler.submit(
|_, _| {
println!("coroutine1 launched");
while unsafe { TEST_FLAG1 } {
println!("loop1");
_ = unsafe { libc::usleep(10_000) };
}
println!("loop1 end");
1
},
None,
);
_ = scheduler.submit(
|_, _| {
println!("coroutine2 launched");
while unsafe { TEST_FLAG2 } {
println!("loop2");
_ = unsafe { libc::usleep(10_000) };
}
println!("loop2 end");
unsafe { TEST_FLAG1 = false };
2
},
None,
);
_ = scheduler.submit(
|_, _| {
println!("coroutine3 launched");
unsafe { TEST_FLAG2 = false };
3
},
None,
);
scheduler.try_schedule();

let (lock, cvar) = &*pair2;
let mut pending = lock.lock().unwrap();
*pending = false;
// notify the condvar that the value has changed.
cvar.notify_one();
})
.expect("failed to spawn thread");

// wait for the thread to start up
let (lock, cvar) = &*pair;
let result = cvar
.wait_timeout_while(
lock.lock().unwrap(),
Duration::from_millis(3000),
|&mut pending| pending,
)
.unwrap();
if result.1.timed_out() {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"preemptive schedule failed",
))
} else {
unsafe {
handler.join().unwrap();
assert!(!TEST_FLAG1);
}
Ok(())
}
} else {
println!("please enable preemptive-schedule feature");
Ok(())
}
}
fn main() {
let task = open_coroutine::task!(|param| {
assert_eq!(param, 1);
}, 1);
task.timeout_join(std::time::Duration::from_secs(1)).expect("timeout");
}
```

outputs

```text
coroutine1 launched
loop1
coroutine2 launched
loop2
coroutine3 launched
loop1
loop2 end
loop1 end
```

### Arbitrary use of blocking syscalls
### step4: scalable stack(optional)

```rust
#[open_coroutine::main]
fn main() {
std::thread::sleep(std::time::Duration::from_secs(1));
_ = open_coroutine::task!(|_| {
fn recurse(i: u32, p: &mut [u8; 10240]) {
open_coroutine::maybe_grow!(|| {
// Ensure the stack allocation isn't optimized away.
unsafe { _ = std::ptr::read_volatile(&p) };
if i > 0 {
recurse(i - 1, &mut [0; 10240]);
}
})
.expect("allocate stack failed")
}
println!("[coroutine] launched");
// Use ~500KB of stack.
recurse(50, &mut [0; 10240]);
}, ());
}
```

outputs

```text
nanosleep hooked
```

## Features

### todo

- [ ] support and compatibility for AF_XDP socket
- [ ] hook other syscall maybe interrupt by signal
<details>
<summary>syscalls</summary>

- [ ] open
- [ ] chdir
- [ ] chroot
- [ ] readlink
- [ ] stat
- [ ] dup
- [ ] dup2
- [ ] umask
- [ ] mount
- [ ] umount
- [ ] mknod
- [ ] fcntl
- [ ] truncate
- [ ] ftruncate
- [ ] setjmp
- [ ] longjmp
- [ ] chown
- [ ] lchown
- [ ] fchown
- [ ] chmod
- [ ] fchmod
- [ ] fchmodat
- [ ] semop
- [ ] ppoll
- [ ] pselect
- [ ] io_getevents
- [ ] semop
- [ ] semtimedop
- [ ] msgrcv
- [ ] msgsnd
## ⚓ Learn

</details>
- [ ] support `#[open_coroutine::join]` macro to wait coroutines

### 0.6.x

- [x] support custom task and coroutine priority.
- [x] support scalable stack

### 0.5.x

- [x] refactor syscall state, distinguish between state and innerState

### 0.4.x

- [x] Supports and is compatible with io_uring in terms of local file IO
- [x] elegant shutdown
- [x] use log instead of println
- [x] enhance `#[open_coroutine::main]` macro
- [x] refactor hook impl, no need to publish dylibs now
- [x] `Monitor` follow the `thread-per-core` guideline
- [x] `EventLoop` follow the `thread-per-core` guideline

### 0.3.x

- [x] ~~support `genawaiter` as low_level stackless coroutine (can't support it due to hook)~~
- [x] use `corosensei` as low_level coroutine
- [x] support backtrace
- [x] support `#[open_coroutine::co]` macro
- [x] refactor `WorkStealQueue`

### 0.2.x

- [x] use correct `epoll_event` struct
- [x] use `rayon` for parallel computing
- [x] support `#[open_coroutine::main]` macro
- [x] hook almost all `read` syscall
<details>
<summary>read syscalls</summary>

- [x] recv
- [x] readv
- [x] pread
- [x] preadv
- [x] recvfrom
- [x] recvmsg

</details>

- [x] hook almost all `write` syscall
<details>
<summary>write syscalls</summary>

- [x] send
- [x] writev
- [x] sendto
- [x] sendmsg
- [x] pwrite
- [x] pwritev

</details>

- [x] hook other syscall
<details>
<summary>other syscalls</summary>

- [x] sleep
- [x] usleep
- [x] nanosleep
- [x] connect
- [x] listen
- [x] accept
- [x] shutdown
- [x] poll
- [x] select

</details>

### 0.1.x

- [x] basic suspend/resume supported
- [x] use jemalloc as memory pool
- [x] higher level coroutine abstraction supported
- [x] preemptive scheduling supported
- [x] work stealing supported
- [x] sleep system call hooks supported
[我有故事,你有酒吗?](https://github.com/acl-dev/open-coroutine-docs)
Loading

0 comments on commit 855619e

Please sign in to comment.