Changeset 86fb8f2 for doc/papers/concurrency
- Timestamp:
- Mar 27, 2019, 11:09:23 AM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- a45fc7b
- Parents:
- 2b10f95 (diff), 1e5d0f0c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- doc/papers/concurrency
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/papers/concurrency/Paper.tex
r2b10f95 r86fb8f2 654 654 \centering 655 655 \newbox\myboxA 656 % \begin{lrbox}{\myboxA} 657 % \begin{cfa}[aboveskip=0pt,belowskip=0pt] 658 % `int fn1, fn2, state = 1;` // single global variables 659 % int fib() { 660 % int fn; 661 % `switch ( state )` { // explicit execution state 662 % case 1: fn = 0; fn1 = fn; state = 2; break; 663 % case 2: fn = 1; fn2 = fn1; fn1 = fn; state = 3; break; 664 % case 3: fn = fn1 + fn2; fn2 = fn1; fn1 = fn; break; 665 % } 666 % return fn; 667 % } 668 % int main() { 669 % 670 % for ( int i = 0; i < 10; i += 1 ) { 671 % printf( "%d\n", fib() ); 672 % } 673 % } 674 % \end{cfa} 675 % \end{lrbox} 656 676 \begin{lrbox}{\myboxA} 657 677 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 658 `int fn1, fn2, state = 1;` // single global variables 659 int fib() { 660 int fn; 661 `switch ( state )` { // explicit execution state 662 case 1: fn = 0; fn1 = fn; state = 2; break; 663 case 2: fn = 1; fn2 = fn1; fn1 = fn; state = 3; break; 664 case 3: fn = fn1 + fn2; fn2 = fn1; fn1 = fn; break; 665 } 666 return fn; 667 } 678 #define FIB_INIT { 0, 1 } 679 typedef struct { int fn1, fn; } Fib; 680 int fib( Fib * f ) { 681 682 int ret = f->fn1; 683 f->fn1 = f->fn; 684 f->fn = ret + f->fn; 685 return ret; 686 } 687 688 689 668 690 int main() { 669 691 Fib f1 = FIB_INIT, f2 = FIB_INIT; 670 692 for ( int i = 0; i < 10; i += 1 ) { 671 printf( "%d\n", fib() ); 693 printf( "%d %d\n", 694 fib( &f1 ), fib( &f2 ) ); 672 695 } 673 696 } … … 678 701 \begin{lrbox}{\myboxB} 679 702 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 680 #define FIB_INIT `{ 0, 1 }` 681 typedef struct { int fn2, fn1; } Fib; 682 int fib( Fib * f ) { 683 684 int ret = f->fn2; 685 int fn = f->fn1 + f->fn2; 686 f->fn2 = f->fn1; f->fn1 = fn; 687 688 return ret; 689 } 690 int main() { 691 Fib f1 = FIB_INIT, f2 = FIB_INIT; 692 for ( int i = 0; i < 10; i += 1 ) { 693 printf( "%d %d\n", fib( &fn1 ), fib( &f2 ) ); 703 `coroutine` Fib { int fn1; }; 704 void main( Fib & fib ) with( fib ) { 705 int fn; 706 [fn1, fn] = [0, 1]; 707 for () { 708 `suspend();` 709 [fn1, fn] = [fn, fn1 + fn]; 694 710 } 695 711 } 696 \end{cfa} 697 \end{lrbox} 698 699 \subfloat[3 states: global variables]{\label{f:GlobalVariables}\usebox\myboxA} 700 \qquad 701 \subfloat[1 state: encapsulated variables]{\label{f:ExternalState}\usebox\myboxB} 702 \caption{C fibonacci fsm} 703 \label{f:C-fibonacci} 704 705 \bigskip 706 707 \newbox\myboxA 708 \begin{lrbox}{\myboxA} 709 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 710 `coroutine` Fib { int fn; }; 711 void main( Fib & fib ) with( fib ) { 712 fn = 0; int fn1 = fn; `suspend()`; 713 fn = 1; int fn2 = fn1; fn1 = fn; `suspend()`; 714 for () { 715 fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `suspend()`; } 716 } 717 int next( Fib & fib ) with( fib ) { `resume( fib );` return fn; } 712 int ?()( Fib & fib ) with( fib ) { 713 `resume( fib );` return fn1; 714 } 718 715 int main() { 719 716 Fib f1, f2; 720 for ( 10 ) 721 sout | next( f1 ) | next( f2 ); 722 } 717 for ( 10 ) { 718 sout | f1() | f2(); 719 } 720 721 723 722 \end{cfa} 724 723 \end{lrbox} 725 \newbox\myboxB 726 \begin{lrbox}{\myboxB} 724 725 \newbox\myboxC 726 \begin{lrbox}{\myboxC} 727 727 \begin{python}[aboveskip=0pt,belowskip=0pt] 728 728 729 def Fibonacci(): 730 fn = 0; fn1 = fn; `yield fn` # suspend 731 fn = 1; fn2 = fn1; fn1 = fn; `yield fn` 732 while True: 733 fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `yield fn` 734 735 736 f1 = Fibonacci() 737 f2 = Fibonacci() 729 def Fib(): 730 731 fn1, fn = 0, 1 732 while True: 733 `yield fn1` 734 fn1, fn = fn, fn1 + fn 735 736 737 // next prewritten 738 739 740 f1 = Fib() 741 f2 = Fib() 738 742 for i in range( 10 ): 739 print( `next( f1 )`, `next( f2 )` ) # resume 743 print( next( f1 ), next( f2 ) ) 744 745 740 746 741 747 \end{python} 742 748 \end{lrbox} 743 \subfloat[\CFA]{\label{f:Coroutine3States}\usebox\myboxA} 744 \qquad 745 \subfloat[Python]{\label{f:Coroutine1State}\usebox\myboxB} 746 \caption{Fibonacci input coroutine, 3 states, internal variables} 747 \label{f:cfa-fibonacci} 749 750 \subfloat[C]{\label{f:GlobalVariables}\usebox\myboxA} 751 \hspace{3pt} 752 \vrule 753 \hspace{3pt} 754 \subfloat[\CFA]{\label{f:ExternalState}\usebox\myboxB} 755 \hspace{3pt} 756 \vrule 757 \hspace{3pt} 758 \subfloat[Python]{\label{f:ExternalState}\usebox\myboxC} 759 \caption{Fibonacci Generator} 760 \label{f:C-fibonacci} 761 762 % \bigskip 763 % 764 % \newbox\myboxA 765 % \begin{lrbox}{\myboxA} 766 % \begin{cfa}[aboveskip=0pt,belowskip=0pt] 767 % `coroutine` Fib { int fn; }; 768 % void main( Fib & fib ) with( fib ) { 769 % fn = 0; int fn1 = fn; `suspend()`; 770 % fn = 1; int fn2 = fn1; fn1 = fn; `suspend()`; 771 % for () { 772 % fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `suspend()`; } 773 % } 774 % int next( Fib & fib ) with( fib ) { `resume( fib );` return fn; } 775 % int main() { 776 % Fib f1, f2; 777 % for ( 10 ) 778 % sout | next( f1 ) | next( f2 ); 779 % } 780 % \end{cfa} 781 % \end{lrbox} 782 % \newbox\myboxB 783 % \begin{lrbox}{\myboxB} 784 % \begin{python}[aboveskip=0pt,belowskip=0pt] 785 % 786 % def Fibonacci(): 787 % fn = 0; fn1 = fn; `yield fn` # suspend 788 % fn = 1; fn2 = fn1; fn1 = fn; `yield fn` 789 % while True: 790 % fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `yield fn` 791 % 792 % 793 % f1 = Fibonacci() 794 % f2 = Fibonacci() 795 % for i in range( 10 ): 796 % print( `next( f1 )`, `next( f2 )` ) # resume 797 % 798 % \end{python} 799 % \end{lrbox} 800 % \subfloat[\CFA]{\label{f:Coroutine3States}\usebox\myboxA} 801 % \qquad 802 % \subfloat[Python]{\label{f:Coroutine1State}\usebox\myboxB} 803 % \caption{Fibonacci input coroutine, 3 states, internal variables} 804 % \label{f:cfa-fibonacci} 748 805 \end{figure} 749 806 -
doc/papers/concurrency/examples/Pingpong.cfa
r2b10f95 r86fb8f2 4 4 coroutine PingPong { 5 5 const char * name; 6 /* const */unsigned int N;7 PingPong *part;6 unsigned int N; 7 PingPong & part; 8 8 }; 9 9 10 10 void ?{}( PingPong & this, const char * name, unsigned int N, PingPong & part ) { 11 (this.__cor){name}; 12 this.name = name; 13 this.N = N; 14 this.part = ∂ 11 this.[name, N] = [name, N]; &this.part = ∂ 15 12 } 16 13 void ?{}( PingPong & this, const char * name, unsigned int N ) { 17 this{ name, N, * (PingPong *)0 };14 this{ name, N, *0p }; // call first constructor 18 15 } 19 16 void cycle( PingPong & pingpong ) { … … 21 18 } 22 19 void partner( PingPong & this, PingPong & part ) { 23 this.part = ∂20 &this.part = ∂ 24 21 resume( this ); 25 22 } 26 void main( PingPong & pingpong ) {// ping's starter ::main, pong's starter ping27 for ( pingpong.N ) {// N ping-pongs28 sout | pingpong.name;29 cycle( *pingpong.part );23 void main( PingPong & pingpong ) with(pingpong) { // ping's starter ::main, pong's starter ping 24 for ( N ) { // N ping-pongs 25 sout | name; 26 cycle( part ); 30 27 } // for 31 28 } 32 29 int main() { 33 enum { N = 20};30 enum { N = 5 }; 34 31 PingPong ping = { "ping", N }, pong = { "pong", N, ping }; 35 32 partner( ping, pong ); … … 38 35 // Local Variables: // 39 36 // tab-width: 4 // 40 // compile-command: "cfa pingpong.cfa" //37 // compile-command: "cfa Pingpong.cfa" // 41 38 // End: // -
doc/papers/concurrency/examples/Pingpong.py
r2b10f95 r86fb8f2 1 def Scheduler 1 def PingPong( name, N ): 2 partner = (yield) # get partner 3 yield # resume scheduler 4 for i in range( N ): 5 print( name ) 6 yield partner # execute next 7 print( "end", name ) 8 9 def Scheduler(): 10 n = (yield) # starting coroutine 11 while True: 12 n = next( n ) # schedule coroutine 13 14 pi = PingPong( "ping", 5 ) 15 po = PingPong( "pong", 5 ) 16 next( pi ) # prime 17 pi.send( po ) # send partner 18 next( po ) # prime 19 po.send( pi ) # send partner 20 21 s = Scheduler(); 22 next( s ) # prime 2 23 try: 3 yield from ping(); 4 yield from pong(); 24 s.send( pi ) # start cycle 5 25 except StopIteration: 6 print( "Scheduler stop" ) 7 8 9 def pong(): 10 print( "pong" ) 11 for i in range( 10 ): 12 13 yield from ping() 14 print( "stop pong" ) 15 16 def ping(): 17 global i 18 print( "ping" ) 19 i += 1 20 if i < 5: 21 yield from pong() 22 print( "stop ping" ) 23 24 p = ping() 25 try: 26 next( p ) 27 except StopIteration: 28 print( "stop" ) 26 print( "scheduler stop" ) 27 print( "stop" ) 29 28 30 29 # Local Variables: # 31 30 # tab-width: 4 # 32 # compile-command: "python3.5 pingpong.py" #31 # compile-command: "python3.5 Pingpong.py" # 33 32 # End: # -
doc/papers/concurrency/examples/ProdCons.cfa
r2b10f95 r86fb8f2 23 23 sout | "prod stops"; 24 24 } 25 int payment( Prod & prod, int m oney) {26 prod.money = money;25 int payment( Prod & prod, int m ) with(prod) { 26 money = m; 27 27 resume( prod ); // main 1st time, then 28 return prod.receipt;// prod in delivery28 return receipt; // prod in delivery 29 29 } 30 30 void start( Prod & prod, int N, Cons &c ) { -
doc/papers/concurrency/examples/ProdCons.cpp
r2b10f95 r86fb8f2 12 12 struct Cons; 13 13 14 struct Prod { 14 struct resumable { 15 virtual resumable * resume() = 0; 16 }; 17 18 struct Prod : public resumable { 15 19 struct local { 16 20 Cons * c; … … 20 24 struct promise_type { 21 25 local _l; 26 resumable * next; 22 27 23 28 Prod get_return_object() { … … 69 74 static Prod main(); 70 75 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); 81 79 82 80 auto start(int N, Cons & c) { … … 84 82 _coroutine.promise()._l.N = N; 85 83 _coroutine.promise()._l.receipt = 0; 84 } 85 86 virtual resumable * resume() override final { 86 87 _coroutine.resume(); 87 } 88 }; 89 90 struct Cons { 88 return _coroutine.promise().next; 89 } 90 }; 91 92 struct Cons : public resumable { 91 93 struct local { 92 94 Prod * p; … … 97 99 struct promise_type { 98 100 local _l; 101 resumable * next; 99 102 100 103 Cons get_return_object() { … … 154 157 struct ret { 155 158 int _status; 159 Cons * c; 156 160 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 } 158 164 int await_resume() { return _status; } 159 165 }; 160 return ret{ _coroutine.promise()._l.status };166 return ret{ _coroutine.promise()._l.status, this }; 161 167 } 162 168 … … 164 170 _coroutine.promise()._l.done = true; 165 171 struct ret { 172 Cons * c; 173 Prod::promise_type * _promise; 166 174 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 } 169 182 }; 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 192 struct 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 202 Prod::payment_return Prod::payment(int money) { 203 _coroutine.promise()._l.money = money; 204 return payment_return{ _coroutine.promise()._l.receipt, this }; 205 } 173 206 174 207 Prod Prod::main() { … … 176 209 for(int i = 0; i < p.N; i++) { 177 210 int p1 = random(100), p2 = random(100); 178 std::cout << p1 << " " << p2 ;211 std::cout << p1 << " " << p2 << std::endl; 179 212 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; 181 214 p.receipt += 1; 182 215 } 183 216 co_await p.c->stop(); 184 std::cout << "prod stops" ;217 std::cout << "prod stops" << std::endl; 185 218 } 186 219 … … 189 222 int money = 1, receipt; 190 223 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; 192 226 c.status += 1; 193 227 receipt = co_await c.p->payment( money ); 194 std::cout << " # " << receipt;228 std::cout << " # " << receipt << std::endl; 195 229 money += 1; 196 230 } 197 std::cout << "const stops"; 231 std::cout << "cons stops" << std::endl; 232 } 233 234 void dispatch(resumable * r) { 235 while((r = r->resume())); 198 236 } 199 237 … … 203 241 srandom( getpid() ); 204 242 prod.start(5, cons); 205 } 243 dispatch(&prod); 244 }
Note:
See TracChangeset
for help on using the changeset viewer.