diff --git a/README.md b/README.md index 30e5b730..7061ffac 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ English | [ไธญๆ–‡](README_ZH.md) ## ๐Ÿ•Š Roadmap -- [ ] add docs; - [ ] add performance [benchmark](https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview); - [ ] cancel coroutine/task; @@ -194,7 +193,7 @@ fn main() { - [Coroutine Pool Overview](core/docs/en/coroutine-pool.md) - [Hook Overview](hook/docs/en/hook.md) -[ๆˆ‘ๆœ‰ๆ•…ไบ‹,ไฝ ๆœ‰้…’ๅ—?](https://github.com/acl-dev/open-coroutine-docs) +[Old Docs Here](https://github.com/acl-dev/open-coroutine-docs) ## ๐Ÿ‘ Credits diff --git a/README_ZH.md b/README_ZH.md index 324686a7..d842c595 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -28,7 +28,6 @@ ## ๐Ÿ•Š ๆœชๆฅ่ฎกๅˆ’ -- [ ] ๅฎŒๅ–„ๆ–‡ๆกฃ; - [ ] ๅขžๅŠ ๆ€ง่ƒฝ[ๅŸบๅ‡†ๆต‹่ฏ•](https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview); - [ ] ๅ–ๆถˆๅ็จ‹/ไปปๅŠก; @@ -185,7 +184,7 @@ fn main() { - [่ฏž็”Ÿไน‹ๅ› ](docs/cn/background.md) - [่ฏญ่จ€้€‰ๆ‹ฉ](docs/cn/why-rust.md) -[ๆˆ‘ๆœ‰ๆ•…ไบ‹,ไฝ ๆœ‰้…’ๅ—?](https://github.com/acl-dev/open-coroutine-docs) +[ๆ—ง็‰ˆๆ–‡ๆกฃๅœจ่ฟ™](https://github.com/acl-dev/open-coroutine-docs) ## ๐Ÿ‘ ้ธฃ่ฐข diff --git a/core/docs/en/monitor.md b/core/docs/en/monitor.md index 12f3df94..a4636c0b 100644 --- a/core/docs/en/monitor.md +++ b/core/docs/en/monitor.md @@ -21,6 +21,9 @@ The `preemptive` feature currently supports the following targets: โœ… Tested and stable; โš ๏ธ Tested but unstable; โŒ Not supported. +โš ๏ธ If you want to use `preemptive` feature with `open-coroutine-core` not `open-coroutine`, you must learn +[Hook Overview](../../../hook/docs/en/hook.md). + ## Usage ```rust diff --git a/hook/docs/en/hook.md b/hook/docs/en/hook.md index 4d944060..0b4544c6 100644 --- a/hook/docs/en/hook.md +++ b/hook/docs/en/hook.md @@ -1 +1,81 @@ -todo \ No newline at end of file +--- +title: Hook Overview +date: 2025-01-20 10:00:00 +author: loongs-zhang +--- + +# Hook Overview + +## Why hook? + +After a `Coroutine::resume_with`, a coroutine may occupy the scheduling thread for a long time, thereby slowing down +other coroutines scheduled by that scheduling thread. To solve this problem, we introduce hook, which automatically +suspends coroutines entering syscall and allow other coroutines to execute. + +The coroutine occupies scheduling threads for a long time in two scenarios: getting stuck in heavy computing or syscall. +The following only solves the problem of getting stuck in syscall. + +Another problem is that `signals can interrupt the running syscall`, and the `preemptive` feature mechanism sends a +large +number of signals. In addition, most user code does not handle signals, if they directly use `open-routine-core` and +enabling preemptive will lead to `catastrophic consequences`. + +## What is hook? + +Hook can modify or extend the behavior of existing code by inserting custom code at runtime, and even monitor, +intercept, modify, and redirect system calls. Now, let's use an [example](https://github.com/loongs-zhang/link-example) +to visually experience it. + +Assuming we have the following test code: + +```rust +use std::time::{Duration, Instant}; + +#[test] +fn test_hook() { + let start = Instant::now(); + std::thread::sleep(Duration::MAX); + let cost = Instant::now().duration_since(start); + println!("cost: {:?}", cost); +} +``` + +If we don't hook, this test would almost never end due to `std::thread::sleep(Duration::MAX)`, but with hook, we +redirect the `nanosleep` syscall +to [our custom code](https://github.com/loongs-zhang/link-example/blob/master/dep/src/lib.rs) `without change the test +code`, and then the test +will [end soon](https://github.com/loongs-zhang/link-example/actions/runs/12862762378/job/35858206179). + +
+ +
+ +## How it works + +```mermaid +sequenceDiagram + Actor Your Project + participant open-coroutine + participant open-coroutine-hook + participant open-coroutine-core + + Your Project ->> open-coroutine: depends on + open-coroutine ->> open-coroutine-hook: depends on + alt at compile time + open-coroutine ->> open-coroutine: build open-coroutine-hook into dylib + open-coroutine ->> open-coroutine: link open-coroutine-hook's dylib + else runtime + Your Project -->> Operation System: logic execute syscall + alt what actually happened + Your Project ->> open-coroutine-hook: redirect syscall to open-coroutine-hook's syscall mod + open-coroutine-hook ->> open-coroutine-core: call open-coroutine-core's syscall mod + open-coroutine-core ->> Operation System: execute fast syscall actually + Operation System ->> open-coroutine-core: return syscall result and errno + open-coroutine-core -->> Operation System: maybe execute fast syscall many times + open-coroutine-core -->> open-coroutine-core: maybe modify syscall result or errno + open-coroutine-core ->> open-coroutine-hook: return syscall result and errno + open-coroutine-hook ->> Your Project: return syscall result and errno + end + Operation System ->> Your Project: return syscall result and errno + end +``` diff --git a/hook/docs/img/result-on-macos.png b/hook/docs/img/result-on-macos.png new file mode 100644 index 00000000..30aa27bc Binary files /dev/null and b/hook/docs/img/result-on-macos.png differ diff --git a/hook/src/lib.rs b/hook/src/lib.rs index b4866625..7dab9dda 100644 --- a/hook/src/lib.rs +++ b/hook/src/lib.rs @@ -44,6 +44,7 @@ clippy::indexing_slicing, clippy::separated_literal_suffix, // conflicts with clippy::unseparated_literal_suffix clippy::single_char_lifetime_names, // TODO: change lifetime names + clippy::test_attr_in_doctest, )] #![doc = include_str!("../docs/en/hook.md")]