examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

coro-round-robin.cpp (2011B)


      1 #include "coroutine_owner.hpp"
      2 
      3 #include <iostream>
      4 #include <deque>
      5 
      6 struct round_robin_scheduler : std::suspend_always
      7 {
      8 	std::deque<coroutine_owner<>> tasks;
      9 
     10 	bool await_ready(void) const noexcept
     11 	{
     12 		return tasks.empty();
     13 	}
     14 
     15 	void schedule(std::coroutine_handle<> h)
     16 	{
     17 		tasks.push_back(coroutine_owner<>{h});
     18 	}
     19 
     20 	std::coroutine_handle<> next(void) noexcept
     21 	{
     22 		auto h = tasks.front().release();
     23 		tasks.pop_front();
     24 		return h;
     25 	}
     26 
     27 	std::coroutine_handle<> await_suspend(std::coroutine_handle<> h)
     28 	{
     29 		schedule(h);
     30 		return next();
     31 	}
     32 
     33 	round_robin_scheduler(void) = default;
     34 
     35 	void destroy(void)
     36 	{
     37 		if (not tasks.empty())
     38 			std::cout << "Finishing early, cleaning up state of suspended tasks..." << std::endl;
     39 	}
     40 
     41 	~round_robin_scheduler()
     42 	{
     43 		destroy();
     44 	}
     45 
     46 	round_robin_scheduler(round_robin_scheduler&& old)
     47 	:   tasks(std::move(old.tasks))
     48 	{}
     49 
     50 	round_robin_scheduler& operator =(round_robin_scheduler&& old)
     51 	{
     52 		destroy();
     53 		tasks = std::move(old.tasks);
     54 		return *this;
     55 	}
     56 
     57 	bool operator ()(void) noexcept
     58 	{
     59 		if (tasks.empty())
     60 		    return false;
     61 
     62 		next()();
     63 		return true;
     64 	}
     65 } round_robin;
     66 
     67 struct fire_forget_coroutine
     68 {
     69 	struct promise_type
     70 	{
     71 		~promise_type() {}
     72 		void get_return_object(void) {}
     73 		std::suspend_always initial_suspend(void)
     74 		{
     75 			round_robin.schedule(std::coroutine_handle<promise_type>::from_promise(*this));
     76 			return {};
     77 		}
     78 		void return_void(void) {}
     79 		std::suspend_never final_suspend(void) noexcept
     80 		{
     81 			round_robin();
     82 			return {};
     83 		}
     84 		void unhandled_exception(void) { std::terminate(); }
     85 	};
     86 };
     87 
     88 struct state
     89 {
     90 	~state()
     91 	{
     92 		std::cout << "  ~state()" << std::endl;
     93 	}
     94 };
     95 
     96 fire_forget_coroutine counter(int from, int to)
     97 {
     98 	state s;
     99 
    100 	for (int i = from;; ++i)
    101 	{
    102 		std::cout << "counter [" << from << ',' << to << "): " << i;
    103 		if (i >= to)
    104 			break;
    105 		std::cout << std::endl;
    106 		co_await round_robin;
    107 	}
    108 	std::cout << " DONE"  << std::endl;
    109 	co_return;
    110 }
    111 
    112 int main()
    113 {
    114 	counter(1,3);
    115 	counter(4,5);
    116 	counter(0,7);
    117 
    118 	round_robin();
    119 
    120 	return 0;
    121 }