Odpověď na názor

Odpovídáte na názor ke článku Zamyšlení se nad korutinami v C++20.

  • 28. 4. 2025 13:39

    MarSik

    Aha! Tady je ta podobnost a rozdíl v tom jak to dělá C++ a jak to dělá Rust. V Rustu není nic jako ready nebo suspend, ta samotná korutina to dělá v rámci svého kódu. V C++ to jsou oddělené metody.

    V Rustu totiž sice může vypadat jednoduchá async funkce takto, ale ta jen používá jiné async metody.

    async fn read() -> Result<...> {
      serial.await // tedy ekvivalent co_await
    }

    Ale taky se dá naimplementovat pomocí nízkoúrovňové Future struktury (zjednodušuju typy..), když potřebuje implementovat to čekání:

    impl Future for StreamRead {
    
      // poll se zavolá, když někdo zavolá await nebo zaregistruje instanci
      // do executoru - což je cca to samé jako await_resume, ale bez
      // návratové hodnoty, Rust se neumí chovat jako iterátor v rámci jedné
      // instance korutiny, prostě čeká na výsledek a pak vytvoří novou korutinu, když chce další
      fn poll(&mut self, ctx: Context) -> Poll {
    
        if Some(data) = serial.read() { // neblokující čtení..
          return Poll::Ready(data);
        }
    
        // někam se musí zaregistrovat waker, to někde ho zavolá, když
        // nastane vhodná událost a to informuje executor, aby znovu zavolal
        // StreamRead::poll
        // funkci jsem si totálně vymyslel, závisí na runtime
        serial.wake_on_interrupt(ctx.waker());
        return Poll::Pending;
      }
    }

    Takže await_suspend je to samé jako vrácení Poll::Pending v Rustu, ale Rust executory očekávají, že ten Waker už byl někam zaregistrovaný tou samotnou korutinou.

    await_resume je víceméně ekvivalent Future::poll. A await_ready nemáme, protože je to detail executoru a schovaný v tom Wakeru. Executor to může zkoušet pořád dokola, nebo nějak vhodně čekat na to, až někdo zavolá Waker::wake. Což někde v executoru poznačí, že korutina se může vzbudit a může to být propojené s nějakou wake-up instrukcí, které třeba na ARM Cortex-M ukončí WFE (Wait for Event), kvůli šetření energií.

    Ten přístup není zase tak odlišný, jen to API je jinak rozhozené mezi tu korutinu a executor.