Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a CPU yield awaitable. #2

Open
FunMiles opened this issue Jan 30, 2023 · 2 comments
Open

Add a CPU yield awaitable. #2

FunMiles opened this issue Jan 30, 2023 · 2 comments

Comments

@FunMiles
Copy link
Owner

FunMiles commented Jan 30, 2023

A purely coroutine based multi-tasking system needs all tasks to be good citizen of the cooperative multi-tasking system, yielding the CPU to other tasks in a periodic manner, enabling long running compute intensive tasks to run while not stopping other tasks from operating.
A yield awaitable object is a clean way of achieving this goal. It can be awaited periodically in long running loops:

task<> do_some_long_computation(int iterationCount, auto &&operation, priority myPriority)
{
    for (int i = 0; i < iterationCount; ++i) {
         // Perform one iteration's work
         operation(i);
         // Yield the CPU, signaling the queueing system our priority (optional argument)
         co_await cpu::yield(myPriority); 
     }
}

An example of such use is for the SSD1306 code. Filling the OLED screen buffer to print text can take tens of thousands of cycles.
The routine performing this operation should be capable of yielding so that time-critical operations can take place.

@hattesen
Copy link

hattesen commented Nov 5, 2023

Could a "poor man's version" of a yield awaitable be constructed as ...

co_await 0ms;

PS's:

  • I really appreciate your effort to make C++ 20 coroutines approachable, and I believe is a great shame that a similar thing was not baked into C++ 20 itself, rather than delivering the over-designed mess that it presents itself as now.
  • Having a lot of "real world" examples, as this library has, is great for understanding typical use-cases, but I really miss some proper API documentation for the library.
  • Another thing that would assist users of this library – who may know nothing about C++ 20 coroutines – would be to provide top level documentation on how the coroutines work, explaining how/when context switching is performed, how task stacks are managed etc, possibly by copying/referencing existing C++20 documentation, such as ...

    Coroutines (C++20) A coroutine is a function that can suspend execution to be resumed later. Coroutines are stackless: they suspend execution by returning to the caller and the data that is required to resume execution is stored separately from the stack. (from cppreference)

@FunMiles
Copy link
Owner Author

FunMiles commented Nov 5, 2023

Could a "poor man's version" of a yield awaitable be constructed as ...

co_await 0ms;

Yes, that is indeed a poor man's version. The ultimate version would have a sense of priority. Some running tasks could be purely "maintenance" type with no set deadline of execution. I think the question will remain opened/work in progress for a while.

PS's:

  • I really appreciate your effort to make C++ 20 coroutines approachable, and I believe is a great shame that a similar thing was not baked into C++ 20 itself, rather than delivering the over-designed mess that it presents itself as now.
  • Having a lot of "real world" examples, as this library has, is great for understanding typical use-cases, but I really miss some proper API documentation for the library.
  • Another thing that would assist users of this library – who may know nothing about C++ 20 coroutines – would be to provide top level documentation on how the coroutines work, explaining how/when context switching is performed, how task stacks are managed etc, possibly by copying/referencing existing C++20 documentation, such as ...

    Coroutines (C++20) A coroutine is a function that can suspend execution to be resumed later. Coroutines are stackless: they suspend execution by returning to the caller and the data that is required to resume execution is stored separately from the stack. (from cppreference)

I appreciate your comments. And I do agree with them. Unfortunately, I have been busy with many a thing and this library has been on the back burner, but I will get back to it and try to help with the descriptions your last two comments ask for.

Cheers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants