Changeset ae6b6cf


Ignore:
Timestamp:
Mar 26, 2019, 2:12:57 PM (2 years ago)
Author:
tdelisle <tdelisle@…>
Branches:
arm-eh, cleanup-dtors, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
8dbfb7e
Parents:
1bb2488
Message:

Implemented ProdCons? using C++20 coroutines and a dispatcher pattern, it works but is also a lovecraftian horror

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/papers/concurrency/examples/ProdCons.cpp

    r1bb2488 rae6b6cf  
    1212struct Cons;
    1313
    14 struct Prod {
     14struct resumable {
     15        virtual resumable * resume() = 0;
     16};
     17
     18struct Prod : public resumable {
    1519        struct local {
    1620                Cons * c;
     
    2024        struct promise_type {
    2125                local _l;
     26                resumable * next;
    2227
    2328                Prod get_return_object() {
     
    6974        static Prod main();
    7075
    71         auto payment(int money) {
    72                 _coroutine.promise()._l.money = money;
    73                 struct ret {
    74                         int _receipt;
    75                         bool await_ready() { return false; }
    76                         void await_suspend(std::experimental::coroutine_handle<>) {}
    77                         int await_resume() { return _receipt; }
    78                 };
    79                 return ret{ _coroutine.promise()._l.receipt };
    80         }
     76        struct payment_return;
     77
     78        payment_return payment(int money);
    8179
    8280        auto start(int N, Cons & c) {
     
    8482                _coroutine.promise()._l.N = N;
    8583                _coroutine.promise()._l.receipt = 0;
     84        }
     85
     86        virtual resumable * resume() override final {
    8687                _coroutine.resume();
    87         }
    88 };
    89 
    90 struct Cons {
     88                return _coroutine.promise().next;
     89        }
     90};
     91
     92struct Cons : public resumable {
    9193        struct local {
    9294                Prod * p;
     
    9799        struct promise_type {
    98100                local _l;
     101                resumable * next;
    99102
    100103                Cons get_return_object() {
     
    154157                struct ret {
    155158                        int _status;
     159                        Cons * c;
    156160                        bool await_ready() { return false; }
    157                         void await_suspend(std::experimental::coroutine_handle<>) {}
     161                        void await_suspend(std::experimental::coroutine_handle<Prod::promise_type> _coroutine) {
     162                                _coroutine.promise().next = c;
     163                        }
    158164                        int await_resume() { return _status; }
    159165                };
    160                 return ret{ _coroutine.promise()._l.status };
     166                return ret{ _coroutine.promise()._l.status, this };
    161167        }
    162168
     
    164170                _coroutine.promise()._l.done = true;
    165171                struct ret {
     172                        Cons * c;
     173                        Prod::promise_type * _promise;
    166174                        bool await_ready() { return false; }
    167                         void await_suspend(std::experimental::coroutine_handle<>) {}
    168                         void await_resume() {}
     175                        void await_suspend(std::experimental::coroutine_handle<Prod::promise_type> _coroutine) {
     176                                _promise = &_coroutine.promise();
     177                                _promise->next = c;
     178                        }
     179                        void await_resume() {
     180                                _promise->next = nullptr;
     181                        }
    169182                };
    170                 return ret{};
    171         }
    172 };
     183                return ret{this, nullptr};
     184        }
     185
     186        virtual resumable * resume() override final {
     187                _coroutine.resume();
     188                return _coroutine.promise().next;
     189        }
     190};
     191
     192struct Prod::payment_return {
     193        int _receipt;
     194        Prod * p;
     195        bool await_ready() { return false; }
     196        void await_suspend(std::experimental::coroutine_handle<Cons::promise_type> _coroutine) {
     197                _coroutine.promise().next = p;
     198        }
     199        int await_resume() { return _receipt; }
     200};
     201
     202Prod::payment_return Prod::payment(int money)  {
     203        _coroutine.promise()._l.money = money;
     204        return payment_return{ _coroutine.promise()._l.receipt, this };
     205}
    173206
    174207Prod Prod::main() {
     
    176209        for(int i = 0; i < p.N; i++) {
    177210                int p1 = random(100), p2 = random(100);
    178                 std::cout << p1 << " " << p2;
     211                std::cout << p1 << " " << p2 << std::endl;
    179212                int status = co_await p.c->deliver(p1, p2);
    180                 std::cout << " $" << p.money << std::endl << status;
     213                std::cout << " $" << p.money << std::endl << status << std::endl;
    181214                p.receipt += 1;
    182215        }
    183216        co_await p.c->stop();
    184         std::cout << "prod stops";
     217        std::cout << "prod stops" << std::endl;
    185218}
    186219
     
    189222        int money = 1, receipt;
    190223        for(;!c.done ;) {
    191                 std::cout << c.p1 << " " << c.p2 << std::endl << " $" << money;
     224                std::cout << c.p1 << " " << c.p2 << std::endl;
     225                std::cout << " $ " << money << std::endl;
    192226                c.status += 1;
    193227                receipt = co_await c.p->payment( money );
    194                 std::cout << " #" << receipt;
     228                std::cout << " # " << receipt << std::endl;
    195229                money += 1;
    196230        }
    197         std::cout << "const stops";
     231        std::cout << "cons stops" << std::endl;
     232}
     233
     234void dispatch(resumable * r) {
     235        while((r = r->resume()));
    198236}
    199237
     
    203241        srandom( getpid() );
    204242        prod.start(5, cons);
    205 }
     243        dispatch(&prod);
     244}
Note: See TracChangeset for help on using the changeset viewer.