Changeset f522618


Ignore:
Timestamp:
Jun 16, 2017, 3:22:56 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
d33bc7c
Parents:
4eb31f2 (diff), 1a42132 (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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
doc
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • doc/user/user.tex

    r4eb31f2 rf522618  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Tue Jun 13 11:50:27 2017
    14 %% Update Count     : 2403
     13%% Last Modified On : Fri Jun 16 12:00:01 2017
     14%% Update Count     : 2433
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    4343\usepackage[pagewise]{lineno}
    4444\renewcommand{\linenumberfont}{\scriptsize\sffamily}
    45 \input{common}                                          % bespoke macros used in the document
     45\input{common}                                          % common CFA document macros
    4646\usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}
    4747\usepackage{breakurl}
     
    110110\renewcommand{\subsectionmark}[1]{\markboth{\thesubsection\quad #1}{\thesubsection\quad #1}}
    111111\pagenumbering{roman}
    112 \linenumbers                                            % comment out to turn off line numbering
     112%\linenumbers                                            % comment out to turn off line numbering
    113113
    114114\maketitle
     
    881881
    882882
     883\subsection{Initialization}
     884
     885\Index{Initialization} is different than \Index{assignment} because initialization occurs on the empty (uninitialized) storage on an object, while assignment occurs on possibly initialized storage of an object.
     886There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, return/temporary binding.
     887Because the object being initialized has no value, there is only one meaningful semantics with respect to address duality: it must mean address as there is no pointed-to value.
     888In contrast, the left-hand side of assignment has an address that has a duality.
     889Therefore, for pointer/reference initialization, the initializing value must be an address not a value.
     890\begin{cfa}
     891int * p = &x;                                           §\C{// assign address of x}§
     892®int * p = x;®                                          §\C{// assign value of x}§
     893int & r = x;                                            §\C{// must have address of x}§
     894\end{cfa}
     895Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given).
     896Therefore, for safety, this context requires an address, so it is superfluous to require explicitly taking the address of the initialization object, even though the type is incorrect.
     897Note, this is strictly a convenience and safety feature for a programmer.
     898Hence, \CFA allows ©r© to be assigned ©x© because it infers a reference for ©x©, by implicitly inserting a address-of operator, ©&©, and it is an error to put an ©&© because the types no longer match due to the implicit dereference.
     899Unfortunately, C allows ©p© to be assigned with ©&x© (address) or ©x© (value), but most compilers warn about the latter assignment as being potentially incorrect.
     900Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason.
     901\begin{cfa}
     902int & f( int & r );                                     §\C{// reference parameter and return}§
     903z = f( x ) + f( y );                            §\C{// reference operator added, temporaries needed for call results}§
     904\end{cfa}
     905Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©.
     906Since operator routine ©?+?© takes its arguments by value, the references returned from ©f© are used to initialize compiler generated temporaries with value semantics that copy from the references.
     907\begin{cfa}
     908int temp1 = f( x ), temp2 = f( y );
     909z = temp1 + temp2;
     910\end{cfa}
     911This \Index{implicit referencing} is crucial for reducing the syntactic burden for programmers when using references;
     912otherwise references have the same syntactic  burden as pointers in these contexts.
     913
     914When a pointer/reference parameter has a ©const© value (immutable), it is possible to pass literals and expressions.
     915\begin{cfa}
     916void f( ®const® int & cr );
     917void g( ®const® int * cp );
     918f( 3 );                   g( ®&®3 );
     919f( x + y );             g( ®&®(x + y) );
     920\end{cfa}
     921Here, the compiler passes the address to the literal 3 or the temporary for the expression ©x + y©, knowing the argument cannot be changed through the parameter.
     922The ©&© before the constant/expression for the pointer-type parameter (©g©) is a \CFA extension necessary to type match and is a common requirement before a variable in C (\eg ©scanf©).
     923Importantly, ©&3© may not be equal to ©&3©, where the references occur across calls because the temporaries maybe different on each call.
     924
     925\CFA \emph{extends} this semantics to a mutable pointer/reference parameter, and the compiler implicitly creates the necessary temporary (copying the argument), which is subsequently pointed-to by the reference parameter and can be changed.\footnote{
     926If whole program analysis is possible, and shows the parameter is not assigned, \ie it is ©const©, the temporary is unnecessary.}
     927\begin{cfa}
     928void f( int & r );
     929void g( int * p );
     930f( 3 );                   g( ®&®3 );            §\C{// compiler implicit generates temporaries}§
     931f( x + y );             g( ®&®(x + y) );        §\C{// compiler implicit generates temporaries}§
     932\end{cfa}
     933Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{
     934This conversion attempts to address the \newterm{const hell} problem, when the innocent addition of a ©const© qualifier causes a cascade of type failures, requiring an unknown number of additional ©const© qualifiers, until it is discovered a ©const© qualifier cannot be added and all the ©const© qualifiers must be removed.}
     935The implicit conversion allows seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
     936
     937%\CFA attempts to handle pointers and references in a uniform, symmetric manner.
     938Finally, C handles \Index{routine object}s in an inconsistent way.
     939A routine object is both a pointer and a reference (\Index{particle and wave}).
     940\begin{cfa}
     941void f( int i );
     942void (*fp)( int );                                      §\C{// routine pointer}§
     943fp = f;                                                         §\C{// reference initialization}§
     944fp = &f;                                                        §\C{// pointer initialization}§
     945fp = *f;                                                        §\C{// reference initialization}§
     946fp(3);                                                          §\C{// reference invocation}§
     947(*fp)(3);                                                       §\C{// pointer invocation}§
     948\end{cfa}
     949While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type.
     950Instead, a routine object should be referenced by a ©const© reference:
     951\begin{cfa}
     952®const® void (®&® fr)( int ) = f;       §\C{// routine reference}§
     953fr = ...                                                        §\C{// error, cannot change code}§
     954&fr = ...;                                                      §\C{// changing routine reference}§
     955fr( 3 );                                                        §\C{// reference call to f}§
     956(*fr)(3);                                                       §\C{// error, incorrect type}§
     957\end{cfa}
     958because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{
     959Dynamic code rewriting is possible but only in special circumstances.}
     960\CFA allows this additional use of references for routine objects in an attempt to give a more consistent meaning for them.
     961
     962
    883963\subsection{Address-of Semantics}
    884964
     
    9581038
    9591039
    960 \subsection{Initialization}
    961 
    962 \Index{Initialization} is different than \Index{assignment} because initialization occurs on the empty (uninitialized) storage on an object, while assignment occurs on possibly initialized storage of an object.
    963 There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, return/temporary binding.
    964 Because the object being initialized has no value, there is only one meaningful semantics with respect to address duality: it must mean address as there is no pointed-to value.
    965 In contrast, the left-hand side of assignment has an address that has a duality.
    966 Therefore, for pointer/reference initialization, the initializing value must be an address not a value.
    967 \begin{cfa}
    968 int * p = &x;                                           §\C{// assign address of x}§
    969 ®int * p = x;®                                          §\C{// assign value of x}§
    970 int & r = x;                                            §\C{// must have address of x}§
    971 \end{cfa}
    972 Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given).
    973 Therefore, for safety, this context requires an address, so it is superfluous to require explicitly taking the address of the initialization object, even though the type is incorrect.
    974 Note, this is strictly a convenience and safety feature for a programmer.
    975 Hence, \CFA allows ©r© to be assigned ©x© because it infers a reference for ©x©, by implicitly inserting a address-of operator, ©&©, and it is an error to put an ©&© because the types no longer match due to the implicit dereference.
    976 Unfortunately, C allows ©p© to be assigned with ©&x© (address) or ©x© (value), but most compilers warn about the latter assignment as being potentially incorrect.
    977 Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason.
    978 \begin{cfa}
    979 int & f( int & r );                                     §\C{// reference parameter and return}§
    980 z = f( x ) + f( y );                            §\C{// reference operator added, temporaries needed for call results}§
    981 \end{cfa}
    982 Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©.
    983 Since operator routine ©?+?© takes its arguments by value, the references returned from ©f© are used to initialize compiler generated temporaries with value semantics that copy from the references.
    984 \begin{cfa}
    985 int temp1 = f( x ), temp2 = f( y );
    986 z = temp1 + temp2;
    987 \end{cfa}
    988 This \Index{implicit referencing} is crucial for reducing the syntactic burden for programmers when using references;
    989 otherwise references have the same syntactic  burden as pointers in these contexts.
    990 
    991 When a pointer/reference parameter has a ©const© value (immutable), it is possible to pass literals and expressions.
    992 \begin{cfa}
    993 void f( ®const® int & cr );
    994 void g( ®const® int * cp );
    995 f( 3 );                   g( ®&®3 );
    996 f( x + y );             g( ®&®(x + y) );
    997 \end{cfa}
    998 Here, the compiler passes the address to the literal 3 or the temporary for the expression ©x + y©, knowing the argument cannot be changed through the parameter.
    999 The ©&© before the constant/expression for the pointer-type parameter (©g©) is a \CFA extension necessary to type match and is a common requirement before a variable in C (\eg ©scanf©).
    1000 Importantly, ©&3© may not be equal to ©&3©, where the references occur across calls because the temporaries maybe different on each call.
    1001 
    1002 \CFA \emph{extends} this semantics to a mutable pointer/reference parameter, and the compiler implicitly creates the necessary temporary (copying the argument), which is subsequently pointed-to by the reference parameter and can be changed.\footnote{
    1003 If whole program analysis is possible, and shows the parameter is not assigned, \ie it is ©const©, the temporary is unnecessary.}
    1004 \begin{cfa}
    1005 void f( int & r );
    1006 void g( int * p );
    1007 f( 3 );                   g( ®&®3 );            §\C{// compiler implicit generates temporaries}§
    1008 f( x + y );             g( ®&®(x + y) );        §\C{// compiler implicit generates temporaries}§
    1009 \end{cfa}
    1010 Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{
    1011 This conversion attempts to address the \newterm{const hell} problem, when the innocent addition of a ©const© qualifier causes a cascade of type failures, requiring an unknown number of additional ©const© qualifiers, until it is discovered a ©const© qualifier cannot be added and all the ©const© qualifiers must be removed.}
    1012 The implicit conversion allows seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
    1013 
    1014 %\CFA attempts to handle pointers and references in a uniform, symmetric manner.
    1015 Finally, C handles \Index{routine object}s in an inconsistent way.
    1016 A routine object is both a pointer and a reference (\Index{particle and wave}).
    1017 \begin{cfa}
    1018 void f( int i );
    1019 void (*fp)( int );                                      §\C{// routine pointer}§
    1020 fp = f;                                                         §\C{// reference initialization}§
    1021 fp = &f;                                                        §\C{// pointer initialization}§
    1022 fp = *f;                                                        §\C{// reference initialization}§
    1023 fp(3);                                                          §\C{// reference invocation}§
    1024 (*fp)(3);                                                       §\C{// pointer invocation}§
    1025 \end{cfa}
    1026 While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type.
    1027 Instead, a routine object should be referenced by a ©const© reference:
    1028 \begin{cfa}
    1029 ®const® void (®&® fr)( int ) = f;       §\C{// routine reference}§
    1030 fr = ...                                                        §\C{// error, cannot change code}§
    1031 &fr = ...;                                                      §\C{// changing routine reference}§
    1032 fr( 3 );                                                        §\C{// reference call to f}§
    1033 (*fr)(3);                                                       §\C{// error, incorrect type}§
    1034 \end{cfa}
    1035 because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{
    1036 Dynamic code rewriting is possible but only in special circumstances.}
    1037 \CFA allows this additional use of references for routine objects in an attempt to give a more consistent meaning for them.
    1038 
    1039 
    1040 
    10411040\begin{comment}
    1042 \section{References}
    1043 
    1044 By introducing references in parameter types, users are given an easy way to pass a value by reference, without the need for NULL pointer checks.
    1045 In structures, a reference can replace a pointer to an object that should always have a valid value.
    1046 When a structure contains a reference, all of its constructors must initialize the reference and all instances of this structure must initialize it upon definition.
    1047 
    1048 The syntax for using references in \CFA is the same as \CC with the exception of reference initialization.
    1049 Use ©&© to specify a reference, and access references just like regular objects, not like pointers (use dot notation to access fields).
    1050 When initializing a reference, \CFA uses a different syntax which differentiates reference initialization from assignment to a reference.
    1051 The ©&© is used on both sides of the expression to clarify that the address of the reference is being set to the address of the variable to which it refers.
    1052 
    1053 
    10541041From: Richard Bilson <rcbilson@gmail.com>
    10551042Date: Wed, 13 Jul 2016 01:58:58 +0000
     
    12131200\section{Routine Definition}
    12141201
    1215 \CFA also supports a new syntax for routine definition, as well as ISO C and K\&R routine syntax.
     1202\CFA also supports a new syntax for routine definition, as well as \Celeven and K\&R routine syntax.
    12161203The point of the new syntax is to allow returning multiple values from a routine~\cite{Galletly96,CLU}, \eg:
    12171204\begin{cfa}
     
    12331220in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in:
    12341221\begin{cfa}
    1235 [§\,§] g();                                             §\C{// no input or output parameters}§
    1236 [ void ] g( void );                             §\C{// no input or output parameters}§
     1222[§\,§] g();                                                     §\C{// no input or output parameters}§
     1223[ void ] g( void );                                     §\C{// no input or output parameters}§
    12371224\end{cfa}
    12381225
     
    12521239\begin{cfa}
    12531240typedef int foo;
    1254 int f( int (* foo) );                   §\C{// foo is redefined as a parameter name}§
     1241int f( int (* foo) );                           §\C{// foo is redefined as a parameter name}§
    12551242\end{cfa}
    12561243The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo.
     
    12601247C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg:
    12611248\begin{cfa}
    1262 [ int ] f( * int, int * );              §\C{// returns an integer, accepts 2 pointers to integers}§
    1263 [ * int, int * ] f( int );              §\C{// returns 2 pointers to integers, accepts an integer}§
     1249[ int ] f( * int, int * );                      §\C{// returns an integer, accepts 2 pointers to integers}§
     1250[ * int, int * ] f( int );                      §\C{// returns 2 pointers to integers, accepts an integer}§
    12641251\end{cfa}
    12651252The reason for allowing both declaration styles in the new context is for backwards compatibility with existing preprocessor macros that generate C-style declaration-syntax, as in:
    12661253\begin{cfa}
    12671254#define ptoa( n, d ) int (*n)[ d ]
    1268 int f( ptoa( p, 5 ) ) ...               §\C{// expands to int f( int (*p)[ 5 ] )}§
    1269 [ int ] f( ptoa( p, 5 ) ) ...   §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
     1255int f( ptoa( p, 5 ) ) ...                       §\C{// expands to int f( int (*p)[ 5 ] )}§
     1256[ int ] f( ptoa( p, 5 ) ) ...           §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
    12701257\end{cfa}
    12711258Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms.
     
    12891276        int z;
    12901277        ... x = 0; ... y = z; ...
    1291         ®return;® §\C{// implicitly return x, y}§
     1278        ®return;®                                                       §\C{// implicitly return x, y}§
    12921279}
    12931280\end{cfa}
     
    12991286[ int x, int y ] f() {
    13001287        ...
    1301 } §\C{// implicitly return x, y}§
     1288}                                                                               §\C{// implicitly return x, y}§
    13021289\end{cfa}
    13031290In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered.
     1291
     1292Named return values may be used in conjunction with named parameter values;
     1293specifically, a return and parameter can have the same name.
     1294\begin{cfa}
     1295[ int x, int y ] f( int, x, int y ) {
     1296        ...
     1297}                                                                               §\C{// implicitly return x, y}§
     1298\end{cfa}
     1299This notation allows the compiler to eliminate temporary variables in nested routine calls.
     1300\begin{cfa}
     1301[ int x, int y ] f( int, x, int y );    §\C{// prototype declaration}§
     1302int a, b;
     1303[a, b] = f( f( f( a, b ) ) );
     1304\end{cfa}
     1305While the compiler normally ignores parameters names in prototype declarations, here they are used to eliminate temporary return-values by inferring that the results of each call are the inputs of the next call, and ultimately, the left-hand side of the assignment.
     1306Hence, even without the body of routine ©f© (separate compilation), it is possible to perform a global optimization across routine calls.
     1307The compiler warns about naming inconsistencies between routine prototype and definition in this case, and behaviour is \Index{undefined} if the programmer is inconsistent.
    13041308
    13051309
     
    13091313as well, parameter names are optional, \eg:
    13101314\begin{cfa}
    1311 [ int x ] f ();                                 §\C{// returning int with no parameters}§
    1312 [ * int ] g (int y);                    §\C{// returning pointer to int with int parameter}§
    1313 [ ] h (int,char);                               §\C{// returning no result with int and char parameters}§
    1314 [ * int,int ] j (int);                  §\C{// returning pointer to int and int, with int parameter}§
     1315[ int x ] f ();                                                 §\C{// returning int with no parameters}§
     1316[ * int ] g (int y);                                    §\C{// returning pointer to int with int parameter}§
     1317[ ] h ( int, char );                                    §\C{// returning no result with int and char parameters}§
     1318[ * int, int ] j ( int );                               §\C{// returning pointer to int and int, with int parameter}§
    13151319\end{cfa}
    13161320This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
     
    13201324\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    13211325\begin{cfa}
    1322 [ int ] f(int), g;
     1326[ int ] f( int ), g;
    13231327\end{cfa}
    13241328&
    13251329\begin{cfa}
    1326 int f(int), g(int);
     1330int f( int ), g( int );
    13271331\end{cfa}
    13281332\end{tabular}
     
    13301334Declaration qualifiers can only appear at the start of a \CFA routine declaration,\footref{StorageClassSpecifier} \eg:
    13311335\begin{cfa}
    1332 extern [ int ] f (int);
    1333 static [ int ] g (int);
     1336extern [ int ] f ( int );
     1337static [ int ] g ( int );
    13341338\end{cfa}
    13351339
     
    13391343The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
    13401344\begin{cfa}
    1341 * [ int x ] () fp;                      §\C{// pointer to routine returning int with no parameters}§
    1342 * [ * int ] (int y) gp;         §\C{// pointer to routine returning pointer to int with int parameter}§
    1343 * [ ] (int,char) hp;            §\C{// pointer to routine returning no result with int and char parameters}§
    1344 * [ * int,int ] (int) jp;       §\C{// pointer to routine returning pointer to int and int, with int parameter}§
     1345* [ int x ] () fp;                                              §\C{// pointer to routine returning int with no parameters}§
     1346* [ * int ] (int y) gp;                                 §\C{// pointer to routine returning pointer to int with int parameter}§
     1347* [ ] (int,char) hp;                                    §\C{// pointer to routine returning no result with int and char parameters}§
     1348* [ * int,int ] ( int ) jp;                             §\C{// pointer to routine returning pointer to int and int, with int parameter}§
    13451349\end{cfa}
    13461350While parameter names are optional, \emph{a routine name cannot be specified};
    13471351for example, the following is incorrect:
    13481352\begin{cfa}
    1349 * [ int x ] f () fp;            §\C{// routine name "f" is not allowed}§
     1353* [ int x ] f () fp;                                    §\C{// routine name "f" is not allowed}§
    13501354\end{cfa}
    13511355
     
    15341538        int ;                                   §\C{// disallowed, unnamed field}§
    15351539        int *;                                  §\C{// disallowed, unnamed field}§
    1536         int (*)(int);                   §\C{// disallowed, unnamed field}§
     1540        int (*)( int );                 §\C{// disallowed, unnamed field}§
    15371541};
    15381542\end{cfa}
     
    16571661}
    16581662int main() {
    1659         * [int](int) fp = foo();        §\C{// int (*fp)(int)}§
     1663        * [int]( int ) fp = foo();      §\C{// int (*fp)( int )}§
    16601664        sout | fp( 3 ) | endl;
    16611665}
     
    27782782
    27792783
    2780 \subsection{Constructors and Destructors}
     2784\section{Constructors and Destructors}
    27812785
    27822786\CFA supports C initialization of structures, but it also adds constructors for more advanced initialization.
     
    31093113
    31103114
     3115\begin{comment}
    31113116\section{Generics}
    31123117
     
    33153320        }
    33163321\end{cfa}
     3322\end{comment}
    33173323
    33183324
     
    33743380        Complex *p3 = new(0.5, 1.0); // allocate + 2 param constructor
    33753381}
    3376 
    33773382\end{cfa}
    33783383
     
    33863391
    33873392
     3393\begin{comment}
    33883394\subsection{Unsafe C Constructs}
    33893395
     
    33963402The exact set of unsafe C constructs that will be disallowed in \CFA has not yet been decided, but is sure to include pointer arithmetic, pointer casting, etc.
    33973403Once the full set is decided, the rules will be listed here.
     3404\end{comment}
    33983405
    33993406
    34003407\section{Concurrency}
    3401 
    3402 Today's processors for nearly all use cases, ranging from embedded systems to large cloud computing servers, are composed of multiple cores, often heterogeneous.
    3403 As machines grow in complexity, it becomes more difficult for a program to make the most use of the hardware available.
    3404 \CFA includes built-in concurrency features to enable high performance and improve programmer productivity on these multi-/many-core machines.
    34053408
    34063409Concurrency support in \CFA is implemented on top of a highly efficient runtime system of light-weight, M:N, user level threads.
     
    34093412This enables a very familiar interface to all programmers, even those with no parallel programming experience.
    34103413It also allows the compiler to do static type checking of all communication, a very important safety feature.
    3411 This controlled communication with type safety has some similarities with channels in \Index*{Go}, and can actually implement
    3412 channels exactly, as well as create additional communication patterns that channels cannot.
     3414This controlled communication with type safety has some similarities with channels in \Index*{Go}, and can actually implement channels exactly, as well as create additional communication patterns that channels cannot.
    34133415Mutex objects, monitors, are used to contain mutual exclusion within an object and synchronization across concurrent threads.
    34143416
    3415 Three new keywords are added to support these features:
    3416 
    3417 monitor creates a structure with implicit locking when accessing fields
    3418 
    3419 mutex implies use of a monitor requiring the implicit locking
    3420 
    3421 task creates a type with implicit locking, separate stack, and a thread
     3417\begin{figure}
     3418\begin{cfa}
     3419#include <fstream>
     3420#include <coroutine>
     3421
     3422coroutine Fibonacci {
     3423        int fn;                                                         §\C{// used for communication}§
     3424};
     3425void ?{}( Fibonacci * this ) {
     3426        this->fn = 0;
     3427}
     3428void main( Fibonacci * this ) {
     3429        int fn1, fn2;                                           §\C{// retained between resumes}§
     3430        this->fn = 0;                                           §\C{// case 0}§
     3431        fn1 = this->fn;
     3432        suspend();                                                      §\C{// return to last resume}§
     3433
     3434        this->fn = 1;                                           §\C{// case 1}§
     3435        fn2 = fn1;
     3436        fn1 = this->fn;
     3437        suspend();                                                      §\C{// return to last resume}§
     3438
     3439        for ( ;; ) {                                            §\C{// general case}§
     3440                this->fn = fn1 + fn2;
     3441                fn2 = fn1;
     3442                fn1 = this->fn;
     3443                suspend();                                              §\C{// return to last resume}§
     3444        } // for
     3445}
     3446int next( Fibonacci * this ) {
     3447        resume( this );                                         §\C{// transfer to last suspend}§
     3448        return this->fn;
     3449}
     3450int main() {
     3451        Fibonacci f1, f2;
     3452        for ( int i = 1; i <= 10; i += 1 ) {
     3453                sout | next( &f1 ) | ' ' | next( &f2 ) | endl;
     3454        } // for
     3455}
     3456\end{cfa}
     3457\caption{Fibonacci Coroutine}
     3458\label{f:FibonacciCoroutine}
     3459\end{figure}
     3460
     3461
     3462\subsection{Coroutine}
     3463
     3464\Index{Coroutines} are the precursor to tasks.
     3465\VRef[Figure]{f:FibonacciCoroutine} shows a coroutine that computes the \Index*{Fibonacci} numbers.
    34223466
    34233467
     
    34343478\end{cfa}
    34353479
     3480\begin{figure}
     3481\begin{cfa}
     3482#include <fstream>
     3483#include <kernel>
     3484#include <monitor>
     3485#include <thread>
     3486
     3487monitor global_t {
     3488        int value;
     3489};
     3490
     3491void ?{}(global_t * this) {
     3492        this->value = 0;
     3493}
     3494
     3495static global_t global;
     3496
     3497void increment3( global_t * mutex this ) {
     3498        this->value += 1;
     3499}
     3500void increment2( global_t * mutex this ) {
     3501        increment3( this );
     3502}
     3503void increment( global_t * mutex this ) {
     3504        increment2( this );
     3505}
     3506
     3507thread MyThread {};
     3508
     3509void main( MyThread* this ) {
     3510        for(int i = 0; i < 1_000_000; i++) {
     3511                increment( &global );
     3512        }
     3513}
     3514int main(int argc, char* argv[]) {
     3515        processor p;
     3516        {
     3517                MyThread f[4];
     3518        }
     3519        sout | global.value | endl;
     3520}
     3521\end{cfa}
     3522\caption{Atomic-Counter Monitor}
     3523\caption{f:AtomicCounterMonitor}
     3524\end{figure}
     3525
     3526\begin{comment}
    34363527Since a monitor structure includes an implicit locking mechanism, it does not make sense to copy a monitor;
    34373528it is always passed by reference.
     
    34803571}
    34813572\end{cfa}
     3573\end{comment}
    34823574
    34833575
     
    34873579A task provides mutual exclusion like a monitor, and also has its own execution state and a thread of control.
    34883580Similar to a monitor, a task is defined like a structure:
     3581
     3582\begin{figure}
     3583\begin{cfa}
     3584#include <fstream>
     3585#include <kernel>
     3586#include <stdlib>
     3587#include <thread>
     3588
     3589thread First  { signal_once * lock; };
     3590thread Second { signal_once * lock; };
     3591
     3592void ?{}( First * this, signal_once* lock ) { this->lock = lock; }
     3593void ?{}( Second * this, signal_once* lock ) { this->lock = lock; }
     3594
     3595void main( First * this ) {
     3596        for ( int i = 0; i < 10; i += 1 ) {
     3597                sout | "First : Suspend No." | i + 1 | endl;
     3598                yield();
     3599        }
     3600        signal( this->lock );
     3601}
     3602
     3603void main( Second * this ) {
     3604        wait( this->lock );
     3605        for ( int i = 0; i < 10; i += 1 ) {
     3606                sout | "Second : Suspend No." | i + 1 | endl;
     3607                yield();
     3608        }
     3609}
     3610
     3611int main( void ) {
     3612        signal_once lock;
     3613        sout | "User main begin" | endl;
     3614        {
     3615                processor p;
     3616                {
     3617                        First  f = { &lock };
     3618                        Second s = { &lock };
     3619                }
     3620        }
     3621        sout | "User main end" | endl;
     3622}
     3623\end{cfa}
     3624\caption{Simple Tasks}
     3625\label{f:SimpleTasks}
     3626\end{figure}
     3627
     3628
     3629\begin{comment}
    34893630\begin{cfa}
    34903631type Adder = task {
     
    35403681\end{cfa}
    35413682
    3542 
    35433683\subsection{Cooperative Scheduling}
    35443684
     
    36533793}
    36543794\end{cfa}
    3655 
    3656 
     3795\end{comment}
     3796
     3797
     3798\begin{comment}
    36573799\section{Modules and Packages }
    36583800
    3659 \begin{comment}
    36603801High-level encapsulation is useful for organizing code into reusable units, and accelerating compilation speed.
    36613802\CFA provides a convenient mechanism for creating, building and sharing groups of functionality that enhances productivity and improves compile time.
     
    43214462
    43224463
     4464\begin{comment}
    43234465\subsection[Comparing Key Features of CFA]{Comparing Key Features of \CFA}
    43244466
     
    46984840
    46994841
    4700 \begin{comment}
    47014842\subsubsection{Modules / Packages}
    47024843
     
    47784919}
    47794920\end{cfa}
    4780 \end{comment}
    47814921
    47824922
     
    49395079
    49405080\subsection{Summary of Language Comparison}
    4941 
    4942 
    4943 \subsubsection[C++]{\CC}
     5081\end{comment}
     5082
     5083
     5084\subsection[C++]{\CC}
    49445085
    49455086\Index*[C++]{\CC{}} is a general-purpose programming language.
     
    49625103
    49635104
    4964 \subsubsection{Go}
     5105\subsection{Go}
    49655106
    49665107\Index*{Go}, also commonly referred to as golang, is a programming language developed at Google in 2007 [.].
     
    49785119
    49795120
    4980 \subsubsection{Rust}
     5121\subsection{Rust}
    49815122
    49825123\Index*{Rust} is a general-purpose, multi-paradigm, compiled programming language developed by Mozilla Research.
     
    49925133
    49935134
    4994 \subsubsection{D}
     5135\subsection{D}
    49955136
    49965137The \Index*{D} programming language is an object-oriented, imperative, multi-paradigm system programming
     
    51045245\item[Rationale:] keywords added to implement new semantics of \CFA.
    51055246\item[Effect on original feature:] change to semantics of well-defined feature. \\
    5106 Any ISO C programs using these keywords as identifiers are invalid \CFA programs.
     5247Any \Celeven programs using these keywords as identifiers are invalid \CFA programs.
    51075248\item[Difficulty of converting:] keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism (see~\VRef{s:BackquoteIdentifiers}).
    51085249\item[How widely used:] clashes among new \CFA keywords and existing identifiers are rare.
  • doc/working/exception/impl/exception.c

    r4eb31f2 rf522618  
    7373}
    7474
    75 // Example throw routine
    7675void __throw_terminate( int val ) {
    7776        // Store the current exception
     
    107106        printf("UNWIND ERROR %d after raise exception\n", ret);
    108107        abort();
     108}
     109
     110// Nesting this the other way would probably be faster.
     111void __rethrow_terminate(void) {
     112        // DEBUG
     113        printf("Rethrowing termination exception\n");
     114
     115        __throw_terminate(shared_stack.current_exception);
    109116}
    110117
  • doc/working/exception/impl/exception.h

    r4eb31f2 rf522618  
    88// These might be given simpler names and made public.
    99void __throw_terminate(exception except) __attribute__((noreturn));
     10void __rethrow_terminate(void) __attribute__((noreturn));
    1011void __throw_resume(exception except);
    1112
     
    2223
    2324
    24 // When I have it working in a single threaded environment.
     25
     26/* The following code is temperary. How exceptions interact with coroutines
     27 * and threads means that... well I'm going to get it working ignoring those
     28 * first, then get it working with concurrency.
     29 */
    2530struct shared_stack_t {
    2631        //struct lock lock;
  • doc/working/exception/impl/test-main.c

    r4eb31f2 rf522618  
    289289// Terminate Rethrow:
    290290// I don't have an implementation for this.
     291void reterminate() {
     292        {
     293                void fn_try1() {
     294                        void fn_try2() {
     295                                terminate(1);
     296                        }
     297                        void fn_catch2(int index, exception except) {
     298                                switch (index) {
     299                                case 1:
     300                                        printf("reterminate 2 caught and "
     301                                               "will rethrow exception 1\n");
     302                                        __rethrow_terminate();
     303                                        break;
     304                                default:
     305                                        printf("INVALID INDEX in reterminate 2: %d (%d)\n",
     306                                                index, except);
     307                                }
     308                        }
     309                        int fn_match2(exception except) {
     310                                if (1 == except) {
     311                                        return 1;
     312                                } else {
     313                                        return 0;
     314                                }
     315                        }
     316                        __try_terminate(fn_try2, fn_catch2, fn_match2);
     317                }
     318                void fn_catch1(int index, exception except) {
     319                        switch (index) {
     320                        case 1:
     321                                printf("reterminate 1 caught exception 1\n");
     322                                break;
     323                        default:
     324                                printf("INVALID INDEX in reterminate 1: %d (%d)\n",
     325                                        index, except);
     326                        }
     327                }
     328                int fn_match1(exception except) {
     329                        if (1 == except) {
     330                                return 1;
     331                        } else {
     332                                return 0;
     333                        }
     334                }
     335                __try_terminate(fn_try1, fn_catch1, fn_match1);
     336        }
     337}
    291338
    292339// Resume Rethrow:
     
    428475        terminate_swapped(); printf("\n");
    429476        resume_swapped(); printf("\n");
     477        reterminate(); printf("\n");
    430478        reresume(); printf("\n");
    431479        fee(); printf("\n");
  • doc/working/exception/translate.c

    r4eb31f2 rf522618  
    5454
    5555__throw_resume(exception_instance);
     56
     57
     58
     59// Rethrows (inside matching handlers):
     60"Cforall"
     61
     62throw;
     63
     64resume;
     65
     66"C"
     67
     68__rethrow_terminate();
     69
     70return false;
    5671
    5772
Note: See TracChangeset for help on using the changeset viewer.