open-coroutine-core 0.7.0

The open-coroutine is a simple, efficient and generic coroutine library.
Documentation
---
title: Monitor Overview
date: 2025-01-02 08:35:00
author: loongs-zhang
---

# Monitor Overview

English | [中文]../cn/monitor.md

## Supported Targets

The `preemptive` feature currently supports the following targets:

|               | ELF (Linux, BSD, bare metal, etc) | Darwin (macOS, iOS, etc) | Windows |
|---------------|-----------------------------------|--------------------------|---------|
| `x86_64`      ||||
| `x86`         ||||
| `AArch64`     ||||
| `ARM`         ||||
| `RISC-V`      ||||
| `LoongArch64` ||||

✅ Tested and stable; ⚠️ Tested but unstable; ❌ Not supported.

⚠️ If you want to use `preemptive` feature directly in `open-coroutine-core`, you must learn
[Hook Overview](../../../hook/docs/en/hook.md).

## Usage

```rust
use open_coroutine_core::co;
use open_coroutine_core::common::constants::CoroutineState;
use open_coroutine_core::coroutine::Coroutine;

fn main() -> std::io::Result<()> {
    // Simulate the most extreme dead loop, if the preemptive feature is not enabled,
    // coroutine will remain stuck in a dead loop after resume.
    let mut coroutine: Coroutine<(), (), ()> = co!(|_, ()| { loop {} })?;
    assert_eq!(CoroutineState::Suspend((), 0), coroutine.resume()?);
    // will never reach if the preemptive feature is not enabled
    assert_eq!(CoroutineState::Suspend((), 0), coroutine.state());
    Ok(())
}
```

## Why preempt?

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. The coroutine occupies scheduling threads for a long time in two
scenarios: getting stuck in heavy computing or syscall. To solve the problem of getting stuck in heavy computing, we
introduce preemptive scheduling, which automatically suspends coroutines that are stuck in long-term execution and
allows other coroutines to execute.

## What is monitor?

The `monitor` is a module of open-routine-core that implements the `preemptive` feature, which allows the coroutine to
be preempted when it has been running for a long time.

## How it works

```mermaid
sequenceDiagram
    actor User Thread
    participant Coroutine
    participant MonitorListener
    participant Monitor Thread
    User Thread ->>+ Coroutine: Coroutine::resume_with
    Coroutine ->>+ MonitorListener: Listener::on_state_changed
    MonitorListener ->>+ Monitor Thread: Monitor::submit
    Monitor Thread ->>+ Monitor Thread: libc::sigaction
    alt Preempting has occurred
        Coroutine ->> Coroutine: Resumed and the coroutine state is Running for more than 10ms
        Monitor Thread ->>+ User Thread: libc::pthread_kill
        User Thread ->>+ User Thread: libc::pthread_sigmask
        User Thread ->>+ Coroutine: suspend the coroutine, see sigurg_handler
        Coroutine ->> User Thread: coroutine has been preempted
    else No preempting
        Coroutine ->> Coroutine: The coroutine state changes to Suspend/Syscall/Complete/Error
        Coroutine ->>+ MonitorListener: Listener::on_state_changed
        MonitorListener ->>+ Monitor Thread: Monitor::remove
        Monitor Thread ->>+ MonitorListener: return
        MonitorListener ->>+ Coroutine: return
        Coroutine ->> User Thread: return
    end
```