Changeset a87c86f


Ignore:
Timestamp:
Apr 28, 2018, 9:17:12 AM (3 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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, with_gc
Children:
aa5fdac
Parents:
bc82fac
Message:

redo section on tour of Cforall

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/papers/concurrency/Paper.tex

    rbc82fac ra87c86f  
    2222\captionsetup{justification=raggedright,singlelinecheck=false}
    2323\usepackage{siunitx}
    24 \sisetup{ binary-units=true }
     24\sisetup{binary-units=true}
    2525
    2626\hypersetup{breaklinks=true}
     
    3232\renewcommand{\linenumberfont}{\scriptsize\sffamily}
    3333
    34 \renewcommand{\textfraction}{0.0}       % the entire page maybe devoted to floats with no text on the page at all
     34\renewcommand{\textfraction}{0.0}                       % the entire page maybe devoted to floats with no text on the page at all
    3535
    3636\lefthyphenmin=3                                                        % hyphen only after 4 characters
     
    7070%\DeclareTextCommandDefault{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}
    7171\renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}}
     72%\def\myCHarFont{\fontencoding{T1}\selectfont}%
     73% \def\{{\ttfamily\upshape\myCHarFont \char`\}}}%
    7274
    7375\makeatletter
     
    244246\maketitle
    245247
    246 % ======================================================================
    247 % ======================================================================
     248
    248249\section{Introduction}
    249 % ======================================================================
    250 % ======================================================================
    251250
    252251This paper provides a minimal concurrency \newterm{Abstract Program Interface} (API) that is simple, efficient and can be used to build other concurrency features.
     
    254253An easier approach for programmers is to support higher-level constructs as the basis of concurrency.
    255254Indeed, for highly productive concurrent programming, high-level approaches are much more popular~\cite{Hochstein05}.
    256 Examples of high-level approaches are task based~\cite{TBB}, message passing~\cite{Erlang,MPI}, and implicit threading~\cite{OpenMP}.
     255Examples of high-level approaches are task (work) based~\cite{TBB}, implicit threading~\cite{OpenMP}, monitors~\cite{Java}, channels~\cite{CSP,Go}, and message passing~\cite{Erlang,MPI}.
    257256
    258257This paper uses the following terminology.
     
    272271The paper discusses how the language features are added to the \CFA translator with respect to parsing, semantic, and type checking, and the corresponding high-perforamnce runtime-library to implement the concurrency features.
    273272
    274 % ======================================================================
    275 % ======================================================================
     273
    276274\section{\CFA Overview}
    277 % ======================================================================
    278 % ======================================================================
    279275
    280276The following is a quick introduction to the \CFA language, specifically tailored to the features needed to support concurrency.
    281 Most of the following code examples can be found on the \CFA website~\cite{Cforall}.
    282 
    283 \CFA is an extension of ISO-C, and therefore, supports all of the same paradigms as C.
     277Extended versions of the following code examples are available at the \CFA website~\cite{Cforall} or Moss~\etal~\cite{XXX}.
     278
     279\CFA is an extension of ISO-C, and hence, supports all C paradigms.
    284280%It is a non-object-oriented system-language, meaning most of the major abstractions have either no runtime overhead or can be opted out easily.
    285 Like C, the basics of \CFA revolve around structures and routines, which are thin abstractions over machine code.
    286 The vast majority of the code produced by the \CFA translator respects memory layouts and calling conventions laid out by C.
    287 Interestingly, while \CFA is not an object-oriented language, lacking the concept of a receiver (\eg @this@) and inheritance, it does have some notion of objects\footnote{C defines the term objects as : ``region of data storage in the execution environment, the contents of which can represent
    288 values''~\cite[3.15]{C11}}, most importantly construction and destruction of objects.
     281Like C, the basics of \CFA revolve around structures and functions.
     282Virtually all of the code generated by the \CFA translator respects C memory layouts and calling conventions.
     283While \CFA is not an object-oriented language, lacking the concept of a receiver (\eg @this@) and nominal inheritance-relationships, C does have a notion of objects: ``region of data storage in the execution environment, the contents of which can represent values''~\cite[3.15]{C11}.
    289284
    290285
    291286\subsection{References}
    292287
    293 Like \CC, \CFA introduces rebind-able references providing multiple dereferencing as an alternative to pointers.
    294 In regards to concurrency, the semantic difference between pointers and references are not particularly relevant, but since this document uses mostly references, here is a quick overview of the semantics:
    295 \begin{cfa}
    296 int x, y, z;
    297 int * p1 = &x, ** p2 = &p1, *** p3 = &p2,       $\C{// pointers to x}$
    298         & r1 = x,   && r2 = r1, &&& r3 = r2;    $\C{// references to x}$
    299 
    300 *p1 = 3; **p2 = 3; ***p3 = 3;                           $\C{// change x}$
    301   r1 = 3;    r2 = 3;      r3 = 3;                       $\C{// change x}$
    302 **p3 = &y; *p3 = &z;                                            $\C{// change p1, p2}$
    303 &&r3 = &y; &r3 = &z;                                            $\C{// change p1, p2}$
    304 int & ar[3] = {x, y, z};                                        $\C{// initialize array of references}$
    305 
    306 typeof( ar[1]) p;                                                       $\C{// is int, referenced object type}$
    307 typeof(&ar[1]) q;                                                       $\C{// is int \&, reference type}$
    308 sizeof( ar[1]) == sizeof(int);                          $\C{// is true, referenced object size}$
    309 sizeof(&ar[1]) == sizeof(int *);                        $\C{// is true, reference size}$
    310 \end{cfa}
    311 The important take away from this code example is that a reference offers a handle to an object, much like a pointer, but which is automatically dereferenced for convenience.
    312 
    313 % ======================================================================
     288\CFA provides multi-level rebindable references, as an alternative to pointers, which significantly reduces syntactic noise.
     289\begin{cfa}
     290int x = 1, y = 2, z = 3;
     291int * p1 = &x, ** p2 = &p1,  *** p3 = &p2,      $\C{// pointers to x}$
     292        `&` r1 = x,  `&&` r2 = r1,  `&&&` r3 = r2;      $\C{// references to x}$
     293int * p4 = &z, `&` r4 = z;
     294
     295*p1 = 3; **p2 = 3; ***p3 = 3;       // change x
     296r1 =  3;     r2 = 3;      r3 = 3;        // change x: implicit dereferences *r1, **r2, ***r3
     297**p3 = &y; *p3 = &p4;                // change p1, p2
     298`&`r3 = &y; `&&`r3 = &`&`r4;             // change r1, r2: cancel implicit deferences (&*)**r3, (&(&*)*)*r3, &(&*)r4
     299\end{cfa}
     300A reference is a handle to an object, like a pointer, but is automatically dereferenced the specified number of levels.
     301Referencing (address-of @&@) a reference variable cancels one of the implicit dereferences, until there are no more implicit references, after which normal expression behaviour applies.
     302
     303
     304\subsection{\texorpdfstring{\protect\lstinline{with} Statement}{with Statement}}
     305\label{s:WithStatement}
     306
     307Heterogeneous data is often aggregated into a structure/union.
     308To reduce syntactic noise, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate field-qualification by opening a scope containing the field identifiers.
     309\begin{cquote}
     310\vspace*{-\baselineskip}%???
     311\lstDeleteShortInline@%
     312\begin{cfa}
     313struct S { char c; int i; double d; };
     314struct T { double m, n; };
     315// multiple aggregate parameters
     316\end{cfa}
     317\begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}}
     318\begin{cfa}
     319void f( S & s, T & t ) {
     320        `s.`c; `s.`i; `s.`d;
     321        `t.`m; `t.`n;
     322}
     323\end{cfa}
     324&
     325\begin{cfa}
     326void f( S & s, T & t ) `with ( s, t )` {
     327        c; i; d;                // no qualification
     328        m; n;
     329}
     330\end{cfa}
     331\end{tabular}
     332\lstMakeShortInline@%
     333\end{cquote}
     334Object-oriented programming languages only provide implicit qualification for the receiver.
     335
     336In detail, the @with@ statement has the form:
     337\begin{cfa}
     338$\emph{with-statement}$:
     339        'with' '(' $\emph{expression-list}$ ')' $\emph{compound-statement}$
     340\end{cfa}
     341and may appear as the body of a function or nested within a function body.
     342Each expression in the expression-list provides a type and object.
     343The type must be an aggregate type.
     344(Enumerations are already opened.)
     345The object is the implicit qualifier for the open structure-fields.
     346All expressions in the expression list are open in parallel within the compound statement, which is different from Pascal, which nests the openings from left to right.
     347
     348
    314349\subsection{Overloading}
    315350
    316 Another important feature of \CFA is function overloading as in Java and \CC, where routines with the same name are selected based on the number and type of the arguments.
    317 As well, \CFA uses the return type as part of the selection criteria, as in Ada~\cite{Ada}.
    318 For routines with multiple parameters and returns, the selection is complex.
     351\CFA maximizes the ability to reuse names via overloading to aggressively address the naming problem.
     352Both variables and functions may be overloaded, where selection is based on types, and number of returns (as in Ada~\cite{Ada}) and arguments.
     353\begin{cquote}
     354\vspace*{-\baselineskip}%???
     355\lstDeleteShortInline@%
     356\begin{cfa}
     357// selection based on type
     358\end{cfa}
     359\begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}}
     360\begin{cfa}
     361const short int MIN = -32768;
     362const int MIN = -2147483648;
     363const long int MIN = -9223372036854775808L;
     364\end{cfa}
     365&
     366\begin{cfa}
     367short int si = MIN;
     368int i = MIN;
     369long int li = MIN;
     370\end{cfa}
     371\end{tabular}
    319372\begin{cfa}
    320373// selection based on type and number of parameters
    321 void f(void);                   $\C{// (1)}$
    322 void f(char);                   $\C{// (2)}$
    323 void f(int, double);    $\C{// (3)}$
    324 f();                                    $\C{// select (1)}$
    325 f('a');                                 $\C{// select (2)}$
    326 f(3, 5.2);                              $\C{// select (3)}$
    327 
    328 // selection based on  type and number of returns
    329 char   f(int);                  $\C{// (1)}$
    330 double f(int);                  $\C{// (2)}$
    331 char   c = f(3);                $\C{// select (1)}$
    332 double d = f(4);                $\C{// select (2)}$
    333 \end{cfa}
    334 This feature is particularly important for concurrency since the runtime system relies on creating different types to represent concurrency objects.
     374\end{cfa}
     375\begin{tabular}{@{}l@{\hspace{1.7\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}}
     376\begin{cfa}
     377void f( void );
     378void f( char );
     379void f( int, double );
     380\end{cfa}
     381&
     382\begin{cfa}
     383f();
     384f( 'a' );
     385f( 3, 5.2 );
     386\end{cfa}
     387\end{tabular}
     388\begin{cfa}
     389// selection based on type and number of returns
     390\end{cfa}
     391\begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}}
     392\begin{cfa}
     393char f( int );
     394double f( int );
     395[char, double] f( int );
     396\end{cfa}
     397&
     398\begin{cfa}
     399char c = f( 3 );
     400double d = f( 3 );
     401[d, c] = f( 3 );
     402\end{cfa}
     403\end{tabular}
     404\lstMakeShortInline@%
     405\end{cquote}
     406Overloading is important for \CFA concurrency since the runtime system relies on creating different types to represent concurrency objects.
    335407Therefore, overloading is necessary to prevent the need for long prefixes and other naming conventions that prevent name clashes.
    336 As seen in section \ref{basics}, routine @main@ is an example that benefits from overloading.
    337 
    338 % ======================================================================
     408As seen in Section~\ref{basics}, function @main@ is heavily overloaded.
     409
     410Variable overloading is useful in the parallel semantics of the @with@ statement for fields with the same name:
     411\begin{cfa}
     412struct S { int `i`; int j; double m; } s;
     413struct T { int `i`; int k; int m; } t;
     414with ( s, t ) {
     415        j + k;                                                                  $\C{// unambiguous, s.j + t.k}$
     416        m = 5.0;                                                                $\C{// unambiguous, t.m = 5.0}$
     417        m = 1;                                                                  $\C{// unambiguous, s.m = 1}$
     418        int a = m;                                                              $\C{// unambiguous, a = s.i }$
     419        double b = m;                                                   $\C{// unambiguous, b = t.m}$
     420        int c = `s.i` + `t.i`;                                  $\C{// unambiguous, qualification}$
     421        (double)m;                                                              $\C{// unambiguous, cast}$
     422}
     423\end{cfa}
     424For parallel semantics, both @s.i@ and @t.i@ are visible with the same type, so only @i@ is ambiguous without qualification.
     425
     426
    339427\subsection{Operators}
     428
    340429Overloading also extends to operators.
    341 The syntax for denoting operator-overloading is to name a routine with the symbol of the operator and question marks where the arguments of the operation appear, \eg:
    342 \begin{cfa}
    343 int ++? (int op);                       $\C{// unary prefix increment}$
    344 int ?++ (int op);                       $\C{// unary postfix increment}$
    345 int ?+? (int op1, int op2);             $\C{// binary plus}$
    346 int ?<=?(int op1, int op2);             $\C{// binary less than}$
    347 int ?=? (int & op1, int op2);           $\C{// binary assignment}$
    348 int ?+=?(int & op1, int op2);           $\C{// binary plus-assignment}$
    349 
    350 struct S {int i, j;};
    351 S ?+?(S op1, S op2) {                           $\C{// add two structures}$
     430Operator-overloading syntax names a routine with the operator symbol and question marks for the operands:
     431\begin{cquote}
     432\lstDeleteShortInline@%
     433\begin{tabular}{@{}ll@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}}
     434\begin{cfa}
     435int ++? (int op);
     436int ?++ (int op);
     437int `?+?` (int op1, int op2);
     438int ?<=?(int op1, int op2);
     439int ?=? (int & op1, int op2);
     440int ?+=?(int & op1, int op2);
     441\end{cfa}
     442&
     443\begin{cfa}
     444// unary prefix increment
     445// unary postfix increment
     446// binary plus
     447// binary less than
     448// binary assignment
     449// binary plus-assignment
     450\end{cfa}
     451&
     452\begin{cfa}
     453struct S { int i, j; };
     454S `?+?`( S op1, S op2) { // add two structures
    352455        return (S){op1.i + op2.i, op1.j + op2.j};
    353456}
    354457S s1 = {1, 2}, s2 = {2, 3}, s3;
    355 s3 = s1 + s2;                                           $\C{// compute sum: s3 == {2, 5}}$
    356 \end{cfa}
    357 While concurrency does not use operator overloading directly, this feature is more important as an introduction for the syntax of constructors.
    358 
    359 % ======================================================================
    360 \subsection{Constructors/Destructors}
    361 Object lifetime is often a challenge in concurrency. \CFA uses the approach of giving concurrent meaning to object lifetime as a means of synchronization and/or mutual exclusion.
    362 Since \CFA relies heavily on the lifetime of objects, constructors and destructors is a core feature required for concurrency and parallelism. \CFA uses the following syntax for constructors and destructors:
    363 \begin{cfa}
    364 struct S {
    365         size_t size;
    366         int * ia;
    367 };
    368 void ?{}(S & s, int asize) {    $\C{// constructor operator}$
    369         s.size = asize;                         $\C{// initialize fields}$
    370         s.ia = calloc(size, sizeof(S));
    371 }
    372 void ^?{}(S & s) {                              $\C{// destructor operator}$
    373         free(ia);                                       $\C{// de-initialization fields}$
    374 }
    375 int main() {
    376         S x = {10}, y = {100};          $\C{// implicit calls: ?\{\}(x, 10), ?\{\}(y, 100)}$
    377         ...                                                     $\C{// use x and y}$
    378         ^x{};  ^y{};                            $\C{// explicit calls to de-initialize}$
    379         x{20};  y{200};                         $\C{// explicit calls to reinitialize}$
    380         ...                                                     $\C{// reuse x and y}$
    381 }                                                               $\C{// implicit calls: \^?\{\}(y), \^?\{\}(x)}$
    382 \end{cfa}
    383 The language guarantees that every object and all their fields are constructed.
    384 Like \CC, construction of an object is automatically done on allocation and destruction of the object is done on deallocation.
    385 Allocation and deallocation can occur on the stack or on the heap.
    386 \begin{cfa}
    387 {
    388         struct S s = {10};      $\C{// allocation, call constructor}$
    389         ...
    390 }                                               $\C{// deallocation, call destructor}$
    391 struct S * s = new();   $\C{// allocation, call constructor}$
    392 ...
    393 delete(s);                              $\C{// deallocation, call destructor}$
    394 \end{cfa}
    395 Note that like \CC, \CFA introduces @new@ and @delete@, which behave like @malloc@ and @free@ in addition to constructing and destructing objects, after calling @malloc@ and before calling @free@, respectively.
    396 
    397 % ======================================================================
     458s3 = s1 `+` s2;         // compute sum: s3 == {2, 5}
     459\end{cfa}
     460\end{tabular}
     461\lstMakeShortInline@%
     462\end{cquote}
     463While concurrency does not use operator overloading directly, it provides an introduction for the syntax of constructors.
     464
     465
    398466\subsection{Parametric Polymorphism}
    399467\label{s:ParametricPolymorphism}
    400 Routines in \CFA can also be reused for multiple types.
    401 This capability is done using the @forall@ clauses, which allow separately compiled routines to support generic usage over multiple types.
     468
     469The signature feature of \CFA is parametric-polymorphic functions~\cite{} with functions generalized using a @forall@ clause (giving the language its name), which allow separately compiled routines to support generic usage over multiple types.
    402470For example, the following sum function works for any type that supports construction from 0 and addition:
    403471\begin{cfa}
    404 // constraint type, 0 and +
    405 forall(otype T | { void ?{}(T *, zero_t); T ?+?(T, T); })
    406 T sum(T a[ ], size_t size) {
    407         T total = 0;                            $\C{// construct T from 0}$
    408         for(size_t i = 0; i < size; i++)
    409                 total = total + a[i];   $\C{// select appropriate +}$
     472forall( otype T | { void `?{}`( T *, zero_t ); T `?+?`( T, T ); } ) // constraint type, 0 and +
     473T sum( T a[$\,$], size_t size ) {
     474        `T` total = { `0` };                                    $\C{// initialize by 0 constructor}$
     475        for ( size_t i = 0; i < size; i += 1 )
     476                total = total `+` a[i];                         $\C{// select appropriate +}$
    410477        return total;
    411478}
    412 
    413479S sa[5];
    414 int i = sum(sa, 5);                             $\C{// use S's 0 construction and +}$
    415 \end{cfa}
    416 
    417 Since writing constraints on types can become cumbersome for more constrained functions, \CFA also has the concept of traits.
    418 Traits are named collection of constraints that can be used both instead and in addition to regular constraints:
    419 \begin{cfa}
    420 trait summable( otype T ) {
    421         void ?{}(T *, zero_t);          $\C{// constructor from 0 literal}$
    422         T ?+?(T, T);                            $\C{// assortment of additions}$
    423         T ?+=?(T *, T);
    424         T ++?(T *);
    425         T ?++(T *);
     480int i = sum( sa, 5 );                                           $\C{// use S's 0 construction and +}$
     481\end{cfa}
     482
     483\CFA provides \newterm{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each function declaration:
     484\begin{cfa}
     485trait `sumable`( otype T ) {
     486        void `?{}`( T &, zero_t );                              $\C{// 0 literal constructor}$
     487        T `?+?`( T, T );                                                $\C{// assortment of additions}$
     488        T ?+=?( T &, T );
     489        T ++?( T & );
     490        T ?++( T & );
    426491};
    427 forall( otype T | summable(T) ) $\C{// use trait}$
    428 T sum(T a[], size_t size);
    429 \end{cfa}
    430 
    431 Note that the type use for assertions can be either an @otype@ or a @dtype@.
    432 Types declared as @otype@ refer to ``complete'' objects, \ie objects with a size, a default constructor, a copy constructor, a destructor and an assignment operator.
    433 Using @dtype@, on the other hand, has none of these assumptions but is extremely restrictive, it only guarantees the object is addressable.
    434 
    435 % ======================================================================
    436 \subsection{with Clause/Statement}
    437 Since \CFA lacks the concept of a receiver, certain functions end up needing to repeat variable names often.
    438 To remove this inconvenience, \CFA provides the @with@ statement, which opens an aggregate scope making its fields directly accessible (like Pascal).
    439 \begin{cfa}
    440 struct S { int i, j; };
    441 int mem(S & this) with (this)           $\C{// with clause}$
    442         i = 1;                                                  $\C{// this->i}$
    443         j = 2;                                                  $\C{// this->j}$
    444 }
    445 int foo() {
    446         struct S1 { ... } s1;
    447         struct S2 { ... } s2;
    448         with (s1)                                               $\C{// with statement}$
    449         {
    450                 // access fields of s1 without qualification
    451                 with (s2)                                       $\C{// nesting}$
    452                 {
    453                         // access fields of s1 and s2 without qualification
    454                 }
    455         }
    456         with (s1, s2)                                   $\C{// scopes open in parallel}$
    457         {
    458                 // access fields of s1 and s2 without qualification
    459         }
    460 }
    461 \end{cfa}
    462 
    463 For more information on \CFA see \cite{cforall-ug,Schluntz17,www-cfa}.
    464 
    465 % ======================================================================
    466 % ======================================================================
     492forall( otype T `| sumable( T )` )                      $\C{// use trait}$
     493T sum( T a[$\,$], size_t size );
     494\end{cfa}
     495
     496Assertions can be @otype@ or @dtype@.
     497@otype@ refers to a ``complete'' object, \ie an object has a size, default constructor, copy constructor, destructor and an assignment operator.
     498@dtype@ only guarantees an object has a size and alignment.
     499
     500Using the return type for discrimination, it is possible to write a type-safe @alloc@ based on the C @malloc@:
     501\begin{cfa}
     502forall( dtype T | sized(T) ) T * alloc( void ) { return (T *)malloc( sizeof(T) ); }
     503int * ip = alloc();                                                     $\C{// select type and size from left-hand side}$
     504double * dp = alloc();
     505struct S {...} * sp = alloc();
     506\end{cfa}
     507where the return type supplies the type/size of the allocation, which is impossible in most type systems.
     508
     509
     510\subsection{Constructors / Destructors}
     511
     512Object lifetime is a challenge in non-managed programming languages.
     513\CFA responds with \CC-like constructors and destructors:
     514\begin{cfa}
     515struct VLA { int len, * data; };                        $\C{// variable length array of integers}$
     516void ?{}( VLA & vla ) with ( vla ) { len = 10;  data = alloc( len ); }  // default constructor
     517void ?{}( VLA & vla, int size, char fill ) with ( vla ) { len = size;  data = alloc( len, fill ); } // initialization
     518void ?{}( VLA & vla, VLA other ) { vla.len = other.len;  vla.data = other.data; } // copy, shallow
     519void ^?{}( VLA & vla ) with ( vla ) { free( data ); } $\C{// destructor}$
     520{
     521        VLA  x,            y = { 20, 0x01 },     z = y; $\C{// z points to y}$
     522        //    ?{}( x );   ?{}( y, 20, 0x01 );   ?{}( z, y );
     523        ^x{};                                                                   $\C{// deallocate x}$
     524        x{};                                                                    $\C{// reallocate x}$
     525        z{ 5, 0xff };                                                   $\C{// reallocate z, not pointing to y}$
     526        ^y{};                                                                   $\C{// deallocate y}$
     527        y{ x };                                                                 $\C{// reallocate y, points to x}$
     528        x{};                                                                    $\C{// reallocate x, not pointing to y}$
     529        // ^?{}(z);  ^?{}(y);  ^?{}(x);
     530}
     531\end{cfa}
     532Like \CC, construction is implicit on allocation (stack/heap) and destruction is implicit on deallocation.
     533The object and all their fields are constructed/destructed.
     534\CFA also provides @new@ and @delete@, which behave like @malloc@ and @free@, in addition to constructing and destructing objects:
     535\begin{cfa}
     536{       struct S s = {10};                                              $\C{// allocation, call constructor}$
     537        ...
     538}                                                                                       $\C{// deallocation, call destructor}$
     539struct S * s = new();                                           $\C{// allocation, call constructor}$
     540...
     541delete( s );                                                            $\C{// deallocation, call destructor}$
     542\end{cfa}
     543\CFA concurrency uses object lifetime as a means of synchronization and/or mutual exclusion.
     544
     545
    467546\section{Concurrency Basics}\label{basics}
    468 % ======================================================================
    469 % ======================================================================
    470 
    471 At its core, concurrency is based on having multiple call-stacks and scheduling among threads of execution executing on these stacks.
     547
     548At its core, concurrency is based on multiple call-stacks and scheduling among threads executing on these stacks.
    472549Multiple call stacks (or contexts) and a single thread of execution does \emph{not} imply concurrency.
    473550Execution with a single thread and multiple stacks where the thread is deterministically self-scheduling across the stacks is called \newterm{coroutining};
     
    585662\begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
    586663`coroutine` Fib { int fn; };
     664void ?{}( Fibonacci & fib ) with( fib ) { fn = 0; }
    587665void main( Fib & f ) with( f ) {
    588666        int f1, f2;
Note: See TracChangeset for help on using the changeset viewer.