Changeset de8a0286
- Timestamp:
- Nov 17, 2025, 8:54:32 PM (4 weeks ago)
- Branches:
- master
- Children:
- 411142c
- Parents:
- f04623f
- File:
-
- 1 edited
-
doc/uC++toCFA/uC++toCFA.tex (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/uC++toCFA/uC++toCFA.tex
rf04623f rde8a0286 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Mon Sep 8 18:10:30202514 %% Update Count : 6 53413 %% Last Modified On : Mon Nov 17 11:14:48 2025 14 %% Update Count : 6677 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 345 345 346 346 \begin{cquote} 347 \setlength{\tabcolsep}{5pt} 347 348 \begin{tabular}{@{}l|ll@{}} 348 349 \begin{uC++} 349 350 350 351 351 void main() {352 void Coroutine::main() { 352 353 try { 353 354 _Enable { … … 357 358 catch( E & ) { ... } 358 359 } 360 void Coroutine::mem() { resume(); } 359 361 \end{uC++} 360 362 & … … 362 364 #define resumePoll( coroutine ) resume( coroutine ); poll() 363 365 #define suspendPoll suspend; poll() 364 void main( ) {366 void main( Coroutine & cor ) { 365 367 try { 366 368 enable_ehm(); … … 370 372 catch( E & ) { ... } 371 373 } 374 void mem( Coroutine & cor ) { resumePoll(); } 372 375 \end{cfa} 373 376 \end{tabular} … … 429 432 \end{tabular} 430 433 \end{cquote} 434 435 436 \section{Time} 437 438 \begin{cquote} 439 \setlength{\tabcolsep}{5pt} 440 \begin{tabular}{@{}l|l@{}} 441 \begin{uC++} 442 443 uTime start = uClock::currTime(); 444 ... 445 cout << "duration " << uClock::currTime() - start 446 << " sec." << endl; 447 \end{uC++} 448 & 449 \begin{cfa} 450 #include <clock.hfa> 451 Time start = timeHiRes(); // time with nanoseconds 452 ... 453 sout | "duration " | timeHiRes() - start | " sec."; 454 455 \end{cfa} 456 \end{tabular} 457 \end{cquote} 458 459 460 \section{Constructor / Destructor} 461 462 A constructor/destructor must have its structure type as the first parameter and be a reference. 463 \begin{cquote} 464 \begin{tabular}{@{}l|l@{}} 465 \begin{uC++} 466 467 struct S { 468 int i, j; 469 @S@() { i = j = 3; } 470 @S@( int i, int j ) { S::i = i; S::j = j; } 471 @S@( const S & s ) { *this = s; } 472 @~S@() {} 473 }; 474 S s0, s1 = { 1, 2 }; 475 476 S * s2 = new S{ 1, 2 }; delete s2; 477 s2 = new S{ 1, 2 }; delete s2; 478 S & s3 = *new S{ 1, 2 }; delete &s3; 479 s3 = *new S{ 1, 2 }; delete &s3; 480 \end{uC++} 481 & 482 \begin{cfa} 483 #include <stdlib.hfa> // new (malloc) 484 struct S { int i, j; }; 485 486 void @?{}@( @S & s@ ) { s.i = s.j = 3; } $\C[3in]{// default}$ 487 void @?{}@( @S & s@, int i, int j ) { s.i = i; s.j = j; } $\C{// initializer}$ 488 void @?{}@( @S & s@, const S rhs ) { ?{}( s, rhs.i, rhs.j ); } $\C{// copy}$ 489 void @^?{}@( @S & s@ ) { s.i = 0; s.j = 0; } $\C{// destructor}\CRT$ 490 491 S s0, s1 = { 1, 2 }; 492 // bug, cannot use 0/1 (zero_t/one_t) with "new" 493 S * s2 = new( 0@n@, 2 ); /* suffix n => (natural int) */ delete( s2 ); 494 s2 = new( 1@n@, 2 ); delete( s2 ); 495 S & s3 = *new( 2, 2 ); delete( &s3 ); 496 &s3 = &*new( 3, 2 ); delete( &s3 ); 497 \end{cfa} 498 \end{tabular} 499 \end{cquote} 500 501 502 \section{\texorpdfstring{Structures (object-oriented \protect\vs routine style)}{Structures (object-oriented vs. routine style)}} 503 504 \CFA is NOT an object-oriented programming-language, so there is no receiver (\lstinline[language=c++]{this}) or nested structure routines. 505 The equivalent of a \emph{member} routine has an explicit structure parameter in any parameter position (often the first). 506 \begin{cquote} 507 \begin{tabular}{@{}l|l@{}} 508 \begin{uC++} 509 struct S { 510 int i = 0; // cheat, implicit default constructor 511 int setter( int j ) { int t = i; i = j; return t; } 512 int getter() { return i; } 513 }; 514 S s; 515 @s.@setter( 3 ); // object calls 516 int k = @s.@getter(); 517 \end{uC++} 518 & 519 \begin{cfa} 520 struct S { int i; }; 521 void ?{}( S & s ) { s.i = 0; } // explicit default constructor 522 int setter( @S & s,@ int j ) @with( s )@ { int t = i; i = j; return t; } 523 int getter( @S & s@ ) @with( s )@ { return i; } 524 525 S s; 526 setter( @s,@ 3 ); // normal calls 527 int k = getter( @s@ ); 528 \end{cfa} 529 \end{tabular} 530 \end{cquote} 531 Aggregate qualification is reduced or eliminated by opening scopes using the @with@ clause. 532 \begin{cfa} 533 struct S { int i; int j; double m; }; // field i has same type in structures S and T 534 struct T { int i; int k; int m; }; 535 void foo( S s, T t ) @with( s, t )@ { // open structure scope s and t in parallel 536 j + k; $\C[1.6in]{// unambiguous, s.j + t.k}$ 537 m = 5.0; $\C{// unambiguous, s.m = 5.0}$ 538 m = 1; $\C{// unambiguous, t.m = 1}$ 539 int a = m; $\C{// unambiguous, a = t.m}$ 540 double b = m; $\C{// unambiguous, b = s.m}$ 541 int c = s.i + t.i; $\C{// unambiguous with qualification}$ 542 (double)m; $\C{// unambiguous with cast s.m}\CRT$ 543 } 544 \end{cfa} 545 \noindent 546 In subsequent code examples, the left example is \CC/\uC and the right example is \CFA. 431 547 432 548 … … 474 590 475 591 592 \enlargethispage{1000pt} 476 593 \section{\texorpdfstring{\lstinline{uArray}}{uArray}} 477 594 … … 525 642 \end{cquote} 526 643 527 528 \section{\texorpdfstring{Structures (object-oriented \protect\vs routine style)}{Structures (object-oriented vs. routine style)}} 529 530 \CFA is NOT an object-oriented programming-language, so there is no receiver (\lstinline[language=c++]{this}) or nested structure routines. 531 The equivalent of a \emph{member} routine has an explicit structure parameter in any parameter position (often the first). 532 \begin{cquote} 533 \begin{tabular}{@{}l|l@{}} 644 \newpage 645 646 647 \section{Doubly-Linked Intrusive List} 648 649 \begin{cquote} 650 \setlength{\tabcolsep}{10pt} 651 \begin{tabular}{@{}l|l@{}} 652 \begin{uC++} 653 #include <iostream> 654 using namespace std; 655 struct Node : @public uSeqable@ { 656 int i; 657 Node( int i ) : i( i ) {} 658 }; 659 660 661 int main() { 662 @uSequence<Node> dlist;@ 663 Node n1{ 1 }, n2{ 2 }, n3{ 3 }; 664 dlist.addTail( &n1 ); 665 dlist.addHead( &n2 ); // out of order 666 dlist.insertAft( &n1, &n3 ); // insertBef 667 for ( Node * it = dlist.head(); it; it = dlist.succ( it ) ) { 668 cout << it->i << endl; 669 } 670 dlist.remove( &n3 ); // shorten list 671 dlist.dropTail(); // dropHead 672 Node * it; 673 for ( uSeqIter<Node> seqit(dlist); // uSeqIterRev 674 seqit >> it; ) { 675 cout << it->i << endl; 676 } 677 } 678 \end{uC++} 679 & 680 \begin{cfa} 681 #include <fstream.hfa> 682 #include <list.hfa> 683 struct Node { 684 @inline dlink( Node );@ 685 int i; 686 }; 687 @P9_EMBEDDED( Node, dlink( Node ) );@ // magic 688 void ?{}( Node & node, int i ) { node.i = i; } 689 int main() { 690 @dlist( Node ) dlist;@ 691 Node n1{ 1 }, n2{ 2 }, n3{ 3 }; 692 insert_last( dlist, n1 ); 693 insert_first( dlist, n2 ); // out of order 694 insert_after( n1, n3 ); // insert_before 695 for ( Node & it = first( dlist ); ⁢ &it = &next( it ) ) { 696 sout | it.i; 697 } 698 remove( n3 ); // shorten list 699 remove_last( dlist ); // remove_first 700 701 FOREACH( dlist, it ) { // FOREACH_REV 702 703 sout | it.i; 704 } 705 } 706 \end{cfa} 707 \end{tabular} 708 \end{cquote} 709 710 711 \section{RAII Dynamic Allocation} 712 713 \begin{cquote} 714 \begin{tabular}{@{}l|ll@{}} 534 715 \begin{uC++} 535 716 struct S { 536 int i = 0; // cheat, implicit default constructor 537 int setter( int j ) { int t = i; i = j; return t; } 538 int getter() { return i; } 539 }; 540 S s; 541 @s.@setter( 3 ); // object calls 542 int k = @s.@getter(); 543 \end{uC++} 544 & 545 \begin{cfa} 546 struct S { int i; }; 547 void ?{}( S & s ) { s.i = 0; } // explicit default constructor 548 int setter( @S & s,@ int j ) @with( s )@ { int t = i; i = j; return t; } 549 int getter( @S & s@ ) @with( s )@ { return i; } 550 551 S s; 552 setter( @s,@ 3 ); // normal calls 553 int k = getter( @s@ ); 554 \end{cfa} 555 \end{tabular} 556 \end{cquote} 557 Aggregate qualification is reduced or eliminated by opening scopes using the @with@ clause. 558 \begin{cfa} 559 struct S { int i; int j; double m; }; // field i has same type in structures S and T 560 struct T { int i; int k; int m; }; 561 void foo( S s, T t ) @with( s, t )@ { // open structure scope s and t in parallel 562 j + k; $\C[1.6in]{// unambiguous, s.j + t.k}$ 563 m = 5.0; $\C{// unambiguous, s.m = 5.0}$ 564 m = 1; $\C{// unambiguous, t.m = 1}$ 565 int a = m; $\C{// unambiguous, a = t.m}$ 566 double b = m; $\C{// unambiguous, b = s.m}$ 567 int c = s.i + t.i; $\C{// unambiguous with qualification}$ 568 (double)m; $\C{// unambiguous with cast s.m}\CRT$ 569 } 570 \end{cfa} 571 \noindent 572 In subsequent code examples, the left example is \CC/\uC and the right example is \CFA. 573 574 575 \section{Constructor / Destructor} 576 577 A constructor/destructor must have its structure type as the first parameter and be a reference. 578 \begin{cquote} 579 \begin{tabular}{@{}l|l@{}} 580 \begin{uC++} 581 582 struct S { 583 int i, j; 584 @S@() { i = j = 3; } 585 @S@( int i, int j ) { S::i = i; S::j = j; } 586 @S@( const S & s ) { *this = s; } 587 @~S@() {} 588 }; 589 S s0; 590 S s1 = { 1, 2 }; 591 592 S * s2 = new S{ 1, 2 }; 593 delete s2; 594 s2 = new S{ 1, 2 }; 595 delete s2; 596 S & s3 = *new S{ 1, 2 }; 597 delete &s3; 598 s3 = *new S{ 1, 2 }; 599 delete &s3; 600 \end{uC++} 601 & 602 \begin{cfa} 603 #include <stdlib.hfa> // new (malloc) 604 struct S { int i, j; }; 605 606 void @?{}@( @S & s@ ) { s.i = s.j = 3; } $\C[3in]{// default}$ 607 void @?{}@( @S & s@, int i, int j ) { s.i = i; s.j = j; } $\C{// initializer}$ 608 void @?{}@( @S & s@, const S rhs ) { ?{}( s, rhs.i, rhs.j ); } $\C{// copy}$ 609 void @^?{}@( @S & s@ ) { s.i = 0; s.j = 0; } $\C{// destructor}\CRT$ 610 611 S s0; 612 S s1 = { 1, 2 }; 613 // bug, cannot use 0/1 (zero_t/one_t) with "new" 614 S * s2 = new( 0@n@, 2 ); // suffix n => (natural int) 615 delete( s2 ); 616 s2 = new( 1@n@, 2 ); 617 delete( s2 ); 618 S & s3 = *new( 2, 2 ); 619 delete( &s3 ); 620 &s3 = &*new( 3, 2 ); 621 delete( &s3 ); 717 ... S() { ... } ~S() { ... } // ctor / dtor 718 }; 719 S * s = new S; delete s; 720 S * sa = new S[10]; delete [] sa; 721 \end{uC++} 722 & 723 \begin{cfa} 724 #include <stdlib.hfa> 725 struct S { ... }; 726 void ?{}( S & ) { ... } void ^?{}( S & ) { ... } // ctor / dtor 727 S * s = new(); delete( s ); 728 S * sa = anew( 10 ); adelete( sa ); 622 729 \end{cfa} 623 730 \end{tabular} … … 660 767 } 661 768 \end{cfa} 662 \\663 \multicolumn{2}{@{}l@{}}{\lstinline{C c;}}664 769 \end{tabular} 665 770 \end{cquote} … … 708 813 709 814 \begin{cquote} 815 \setlength{\tabcolsep}{10pt} 710 816 \begin{tabular}{@{}l|ll@{}} 711 817 \begin{uC++} … … 738 844 } 739 845 \end{cfa} 740 \end{tabular} 741 \begin{tabular}{@{}l|ll@{}} 846 \\ 742 847 \begin{uC++} 743 848 _Actor Hello { ${\color{red}\LstCommentStyle{// : public uActor}}$ … … 829 934 830 935 uOwnerLock m; 831 uCondLock s;936 uCondLock c; 832 937 m.acquire(); 833 if ( ! s.empty() ) s.wait( m );938 if ( ! c.empty() ) c.wait( m ); 834 939 else { 835 940 m.release(); … … 841 946 #include <locks.hfa> 842 947 owner_lock m; 843 cond_lock( owner_lock ) s; // generic type on mutex lock948 cond_lock( owner_lock ) c; // generic type on mutex lock 844 949 lock( m ); 845 if ( ! empty( s ) ) wait( s, m );950 if ( ! empty( c ) ) wait( c, m ); 846 951 else { 847 952 unlock( m ); … … 852 957 \end{cquote} 853 958 959 \begin{cquote} 960 \begin{tabular}{@{}l|ll@{}} 961 \begin{uC++} 962 963 uSemaphore m, c; 964 m.P(); 965 if ( ! c.empty() ) c.P( m ); 966 else { 967 m.V(); 968 } 969 \end{uC++} 970 & 971 \begin{cfa} 972 #include <locks.hfa> 973 semaphore m, c; 974 P( m ); 975 if ( ! empty( c ) ) P( c, m ); 976 else { 977 V( m ); 978 } 979 \end{cfa} 980 \end{tabular} 981 \end{cquote} 982 983 984 \enlargethispage{1000pt} 854 985 855 986 \section{Barrier} … … 888 1019 #include <mutex_stmt.hfa> 889 1020 struct Barrier { 890 @ barrier b;@ // containment1021 @inline barrier;@ 891 1022 int total; 892 1023 893 1024 }; 894 void ?{}( Barrier & B, unsigned int group ) with(B) {895 @ ?{}( b, group );@ // initialize barrier1025 void ?{}( Barrier & b, unsigned int group ) with( b ) { 1026 @(b){ group };@ // initialize barrier 896 1027 total = 0; 897 1028 } 898 unsigned int block( Barrier & B, int subtotal ) with(B) {899 void @last@( ) { sout | total; } // called by Gth arriving thread1029 unsigned int block( Barrier & b, int subtotal ) with( b ) { 1030 void @last@(...) { sout | total; } // called by Gth arriving thread 900 1031 @mutex( b )@ { // use barrier's mutual exclusion 901 1032 total += subtotal; … … 909 1040 \end{cquote} 910 1041 1042 \newpage 911 1043 912 1044 \enlargethispage{1000pt} … … 916 1048 Internal Scheduling 917 1049 \begin{cquote} 1050 \setlength{\tabcolsep}{5pt} 918 1051 \begin{tabular}{@{}l|ll@{}} 919 1052 \begin{uC++} … … 979 1112 \end{cquote} 980 1113 981 \ newpage1114 \bigskip 982 1115 \noindent 983 1116 External Scheduling 984 1117 \begin{cquote} 1118 \setlength{\tabcolsep}{5pt} 985 1119 \begin{tabular}{@{}l|ll@{}} 986 1120 \begin{uC++} … … 1039 1173 1040 1174 1041 \input{uC++toCFA.ind} 1175 \newpage 1176 1177 \section{Futures (reference counting)} 1178 1179 1180 {\lstset{tabsize=3} 1181 \setlength{\tabcolsep}{5pt} 1182 \begin{tabular}{@{}l|ll@{}} 1183 \begin{uC++} 1184 #include <uFuture.h> 1185 @Future_ISM@<int> fi; 1186 @Future_ISM@<double> fd; 1187 struct Msg { int i, j; }; @Future_ISM@<Msg> fm; 1188 struct Stop {}; @Future_ISM@<Stop> fs; 1189 struct Cont {}; @Future_ISM@<Cont> fc; 1190 1191 _Task Worker { 1192 void main() { 1193 1194 for ( ;; ) { 1195 _Select( fi ) { cout << fi() << endl; fi.reset(); } 1196 and _Select( fd ) { cout << fd() << endl; fd.reset(); } 1197 and _Select( fm ) { 1198 cout << fm().i << " " << fm().j << endl; fm.reset(); 1199 } or _Select( fs ) { cout << "stop" << endl; break; } 1200 fc.delivery( (Cont){} ); // synchronize 1201 } 1202 } 1203 1204 }; 1205 int main() { 1206 Worker worker; 1207 for ( int i = 0; i < 10; i += 1 ) { 1208 fi( i ); fd( i + 2.5 ); fm( (Msg){ i, 2 } ); // fulfil 1209 fc(); fc.reset(); // synchronize 1210 } 1211 fs( (Stop){} ); 1212 } // wait for worker to terminate 1213 \end{uC++} 1214 & 1215 \begin{cfa} 1216 #include <future.hfa> 1217 @future_rc@(int) fi; 1218 @future_rc@(double) fd; 1219 struct Msg { int i, j; }; @future_rc@(Msg) fm; 1220 struct Stop {}; @future_rc@(Stop) fs; 1221 struct Cont {}; @future_rc@(Cont) fc; 1222 ExceptionDecl( Break ); 1223 thread Worker {}; 1224 void main( Worker & ) { 1225 try { 1226 for () { 1227 waituntil( fi ) { sout | fi(); reset( fi ); } 1228 and waituntil( fd ) { sout | fd(); reset( fd ); } 1229 and waituntil( fm ) { sout | fm().i | fm().j; reset( fm ); } 1230 or waituntil( fs ) { sout | "stop"; 1231 throw ExceptionInst( Break ); 1232 } 1233 fc( (Cont){} ); // synchronize 1234 } 1235 } catch( Break * ) {} 1236 } 1237 int main() { 1238 Worker worker; 1239 for ( i; 10 ) { 1240 fi( i ); fd( i + 2.5 ); fm( (Msg){ i, 2 } ); // fulfil 1241 fc(); reset( fc ); // synchronize 1242 } 1243 fs( (Stop){} ); 1244 } // wait for worker to terminate 1245 \end{cfa} 1246 \end{tabular} 1247 }% 1248 1249 %\input{uC++toCFA.ind} 1042 1250 1043 1251 % \bibliographystyle{plain}
Note:
See TracChangeset
for help on using the changeset viewer.