The open-coroutine
is a simple, efficient and generic stackful-coroutine library.
Still under development, please do not
use this library in the production
environment !
-
hook other syscall maybe interrupt by signal
syscalls
- open
- chdir
- chroot
- mkdir
- rmdir
- link
- unlink
- 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
-
support muti low_level coroutine create (just support boost.context for now)
-
support
genawaiter
as low_level stackless coroutine (click to see what impl have been tried) -
support
corosensei
as low_level coroutine -
support back trace
-
support
#[open_coroutine::join]
macro to wait coroutines -
support
#[open_coroutine::co]
macro -
refactor
WorkStealQueue
-
optimize
Stack
andOpenCoroutine
to makecache miss
happen less -
Monitor
follow thethread-per-core
guideline -
EventLoop
follow thethread-per-core
guideline, don't forget to consider theMonitor
thread
-
use correct
epoll_event
struct -
use
rayon
for parallel computing -
support
#[open_coroutine::main]
macro -
hook almost all
read
syscallread syscalls
- recv
- readv
- pread
- preadv
- recvfrom
- recvmsg
-
hook almost all
write
syscallwrite syscalls
- send
- write
- writev
- sendto
- sendmsg
- pwrite
- pwritev
-
hook other syscall
other syscalls
- sleep
- usleep
- nanosleep
- connect
- listen
- accept
- shutdown
- poll
- select
- basic suspend/resume supported
- use jemalloc as memory pool
- higher level coroutine abstraction supported
- preemptive scheduling supported
- work stealing supported
- sleep system call hooks supported
add dependency to your Cargo.toml
[dependencies]
# check https://crates.io/crates/open-coroutine
open-coroutine = "x.y.z"
enable hooks
//step2 enable hooks
#[open_coroutine::main]
fn main() {
//......
}
enjoy the performance improvement brought by open-coroutine
!
run hello example
cargo run --example hello
Click to see code
use open_coroutine::co;
use std::os::raw::c_void;
use std::time::Duration;
#[open_coroutine::main]
fn main() {
co(
|_yielder, input: Option<&'static mut c_void>| {
println!("[coroutine1] launched");
input
},
None,
4096,
);
co(
|_yielder, input: Option<&'static mut c_void>| {
println!("[coroutine2] launched");
input
},
None,
4096,
);
std::thread::sleep(Duration::from_millis(50));
println!("scheduler finished successfully!");
}
Note: not supported for windows
run preemptive example
cargo run --example preemptive
Click to see code
use open_coroutine::co;
use std::os::raw::c_void;
use std::time::Duration;
#[open_coroutine::main]
fn main() {
static mut EXAMPLE_FLAG: bool = true;
let handle = co(
|_yielder, input: Option<&'static mut i32>| {
println!("[coroutine1] launched");
unsafe {
while EXAMPLE_FLAG {
println!("loop");
std::thread::sleep(Duration::from_millis(10));
}
}
input
},
Some(Box::leak(Box::new(1))),
4096,
);
co(
|_yielder, input: Option<&'static mut c_void>| {
println!("[coroutine2] launched");
unsafe {
EXAMPLE_FLAG = false;
}
input
},
None,
4096,
);
let result = handle.join();
unsafe {
assert_eq!(std::ptr::read_unaligned(result.unwrap() as *mut i32), 1);
assert!(!EXAMPLE_FLAG);
}
unsafe { assert!(!EXAMPLE_FLAG) };
println!("preemptive schedule finished successfully!");
}