Ignore:
File:
1 edited

Legend:

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

    ra87c86f rc8ad5d9  
    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`\}}}%
    7472
    7573\makeatletter
     
    246244\maketitle
    247245
    248 
     246% ======================================================================
     247% ======================================================================
    249248\section{Introduction}
     249% ======================================================================
     250% ======================================================================
    250251
    251252This paper provides a minimal concurrency \newterm{Abstract Program Interface} (API) that is simple, efficient and can be used to build other concurrency features.
     
    253254An easier approach for programmers is to support higher-level constructs as the basis of concurrency.
    254255Indeed, for highly productive concurrent programming, high-level approaches are much more popular~\cite{Hochstein05}.
    255 Examples 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}.
     256Examples of high-level approaches are task based~\cite{TBB}, message passing~\cite{Erlang,MPI}, and implicit threading~\cite{OpenMP}.
    256257
    257258This paper uses the following terminology.
     
    271272The 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.
    272273
    273 
     274% ======================================================================
     275% ======================================================================
    274276\section{\CFA Overview}
     277% ======================================================================
     278% ======================================================================
    275279
    276280The following is a quick introduction to the \CFA language, specifically tailored to the features needed to support concurrency.
    277 Extended 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.
     281Most 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.
    280284%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.
    281 Like C, the basics of \CFA revolve around structures and functions.
    282 Virtually all of the code generated by the \CFA translator respects C memory layouts and calling conventions.
    283 While \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}.
     285Like C, the basics of \CFA revolve around structures and routines, which are thin abstractions over machine code.
     286The vast majority of the code produced by the \CFA translator respects memory layouts and calling conventions laid out by C.
     287Interestingly, 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
     288values''~\cite[3.15]{C11}}, most importantly construction and destruction of objects.
    284289
    285290
    286291\subsection{References}
    287292
    288 \CFA provides multi-level rebindable references, as an alternative to pointers, which significantly reduces syntactic noise.
    289 \begin{cfa}
    290 int x = 1, y = 2, z = 3;
    291 int * p1 = &x, ** p2 = &p1,  *** p3 = &p2,      $\C{// pointers to x}$
    292         `&` r1 = x,  `&&` r2 = r1,  `&&&` r3 = r2;      $\C{// references to x}$
    293 int * p4 = &z, `&` r4 = z;
    294 
    295 *p1 = 3; **p2 = 3; ***p3 = 3;       // change x
    296 r1 =  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}
    300 A reference is a handle to an object, like a pointer, but is automatically dereferenced the specified number of levels.
    301 Referencing (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 
    307 Heterogeneous data is often aggregated into a structure/union.
    308 To 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}
    313 struct S { char c; int i; double d; };
    314 struct T { double m, n; };
    315 // multiple aggregate parameters
    316 \end{cfa}
    317 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}}
    318 \begin{cfa}
    319 void 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}
    326 void 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}
    334 Object-oriented programming languages only provide implicit qualification for the receiver.
    335 
    336 In 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}
    341 and may appear as the body of a function or nested within a function body.
    342 Each expression in the expression-list provides a type and object.
    343 The type must be an aggregate type.
    344 (Enumerations are already opened.)
    345 The object is the implicit qualifier for the open structure-fields.
    346 All 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 
     293Like \CC, \CFA introduces rebind-able references providing multiple dereferencing as an alternative to pointers.
     294In 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}
     296int x, y, z;
     297int * 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}$
     304int & ar[3] = {x, y, z};                                        $\C{// initialize array of references}$
     305
     306typeof( ar[1]) p;                                                       $\C{// is int, referenced object type}$
     307typeof(&ar[1]) q;                                                       $\C{// is int \&, reference type}$
     308sizeof( ar[1]) == sizeof(int);                          $\C{// is true, referenced object size}$
     309sizeof(&ar[1]) == sizeof(int *);                        $\C{// is true, reference size}$
     310\end{cfa}
     311The 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% ======================================================================
    349314\subsection{Overloading}
    350315
    351 \CFA maximizes the ability to reuse names via overloading to aggressively address the naming problem.
    352 Both 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}
    361 const short int MIN = -32768;
    362 const int MIN = -2147483648;
    363 const long int MIN = -9223372036854775808L;
    364 \end{cfa}
    365 &
    366 \begin{cfa}
    367 short int si = MIN;
    368 int i = MIN;
    369 long int li = MIN;
    370 \end{cfa}
    371 \end{tabular}
     316Another 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.
     317As well, \CFA uses the return type as part of the selection criteria, as in Ada~\cite{Ada}.
     318For routines with multiple parameters and returns, the selection is complex.
    372319\begin{cfa}
    373320// selection based on type and number of parameters
    374 \end{cfa}
    375 \begin{tabular}{@{}l@{\hspace{1.7\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}}
    376 \begin{cfa}
    377 void f( void );
    378 void f( char );
    379 void f( int, double );
    380 \end{cfa}
    381 &
    382 \begin{cfa}
    383 f();
    384 f( 'a' );
    385 f( 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}
    393 char f( int );
    394 double f( int );
    395 [char, double] f( int );
    396 \end{cfa}
    397 &
    398 \begin{cfa}
    399 char c = f( 3 );
    400 double d = f( 3 );
    401 [d, c] = f( 3 );
    402 \end{cfa}
    403 \end{tabular}
    404 \lstMakeShortInline@%
    405 \end{cquote}
    406 Overloading is important for \CFA concurrency since the runtime system relies on creating different types to represent concurrency objects.
     321void f(void);                   $\C{// (1)}$
     322void f(char);                   $\C{// (2)}$
     323void f(int, double);    $\C{// (3)}$
     324f();                                    $\C{// select (1)}$
     325f('a');                                 $\C{// select (2)}$
     326f(3, 5.2);                              $\C{// select (3)}$
     327
     328// selection based on  type and number of returns
     329char   f(int);                  $\C{// (1)}$
     330double f(int);                  $\C{// (2)}$
     331char   c = f(3);                $\C{// select (1)}$
     332double d = f(4);                $\C{// select (2)}$
     333\end{cfa}
     334This feature is particularly important for concurrency since the runtime system relies on creating different types to represent concurrency objects.
    407335Therefore, overloading is necessary to prevent the need for long prefixes and other naming conventions that prevent name clashes.
    408 As seen in Section~\ref{basics}, function @main@ is heavily overloaded.
    409 
    410 Variable overloading is useful in the parallel semantics of the @with@ statement for fields with the same name:
    411 \begin{cfa}
    412 struct S { int `i`; int j; double m; } s;
    413 struct T { int `i`; int k; int m; } t;
    414 with ( 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}
    424 For parallel semantics, both @s.i@ and @t.i@ are visible with the same type, so only @i@ is ambiguous without qualification.
    425 
    426 
     336As seen in section \ref{basics}, routine @main@ is an example that benefits from overloading.
     337
     338% ======================================================================
    427339\subsection{Operators}
    428 
    429340Overloading also extends to operators.
    430 Operator-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}
    435 int ++? (int op);
    436 int ?++ (int op);
    437 int `?+?` (int op1, int op2);
    438 int ?<=?(int op1, int op2);
    439 int ?=? (int & op1, int op2);
    440 int ?+=?(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}
    453 struct S { int i, j; };
    454 S `?+?`( S op1, S op2) { // add two structures
     341The 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}
     343int ++? (int op);                       $\C{// unary prefix increment}$
     344int ?++ (int op);                       $\C{// unary postfix increment}$
     345int ?+? (int op1, int op2);             $\C{// binary plus}$
     346int ?<=?(int op1, int op2);             $\C{// binary less than}$
     347int ?=? (int & op1, int op2);           $\C{// binary assignment}$
     348int ?+=?(int & op1, int op2);           $\C{// binary plus-assignment}$
     349
     350struct S {int i, j;};
     351S ?+?(S op1, S op2) {                           $\C{// add two structures}$
    455352        return (S){op1.i + op2.i, op1.j + op2.j};
    456353}
    457354S s1 = {1, 2}, s2 = {2, 3}, s3;
    458 s3 = s1 `+` s2;         // compute sum: s3 == {2, 5}
    459 \end{cfa}
    460 \end{tabular}
    461 \lstMakeShortInline@%
    462 \end{cquote}
    463 While concurrency does not use operator overloading directly, it provides an introduction for the syntax of constructors.
    464 
    465 
     355s3 = s1 + s2;                                           $\C{// compute sum: s3 == {2, 5}}$
     356\end{cfa}
     357While 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}
     361Object 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.
     362Since \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}
     364struct S {
     365        size_t size;
     366        int * ia;
     367};
     368void ?{}(S & s, int asize) {    $\C{// constructor operator}$
     369        s.size = asize;                         $\C{// initialize fields}$
     370        s.ia = calloc(size, sizeof(S));
     371}
     372void ^?{}(S & s) {                              $\C{// destructor operator}$
     373        free(ia);                                       $\C{// de-initialization fields}$
     374}
     375int 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}
     383The language guarantees that every object and all their fields are constructed.
     384Like \CC, construction of an object is automatically done on allocation and destruction of the object is done on deallocation.
     385Allocation 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}$
     391struct S * s = new();   $\C{// allocation, call constructor}$
     392...
     393delete(s);                              $\C{// deallocation, call destructor}$
     394\end{cfa}
     395Note 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% ======================================================================
    466398\subsection{Parametric Polymorphism}
    467399\label{s:ParametricPolymorphism}
    468 
    469 The 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.
     400Routines in \CFA can also be reused for multiple types.
     401This capability is done using the @forall@ clauses, which allow separately compiled routines to support generic usage over multiple types.
    470402For example, the following sum function works for any type that supports construction from 0 and addition:
    471403\begin{cfa}
    472 forall( otype T | { void `?{}`( T *, zero_t ); T `?+?`( T, T ); } ) // constraint type, 0 and +
    473 T 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 +}$
     404// constraint type, 0 and +
     405forall(otype T | { void ?{}(T *, zero_t); T ?+?(T, T); })
     406T 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 +}$
    477410        return total;
    478411}
     412
    479413S sa[5];
    480 int 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}
    485 trait `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 & );
     414int i = sum(sa, 5);                             $\C{// use S's 0 construction and +}$
     415\end{cfa}
     416
     417Since writing constraints on types can become cumbersome for more constrained functions, \CFA also has the concept of traits.
     418Traits are named collection of constraints that can be used both instead and in addition to regular constraints:
     419\begin{cfa}
     420trait 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 *);
    491426};
    492 forall( otype T `| sumable( T )` )                      $\C{// use trait}$
    493 T sum( T a[$\,$], size_t size );
    494 \end{cfa}
    495 
    496 Assertions 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 
    500 Using the return type for discrimination, it is possible to write a type-safe @alloc@ based on the C @malloc@:
    501 \begin{cfa}
    502 forall( dtype T | sized(T) ) T * alloc( void ) { return (T *)malloc( sizeof(T) ); }
    503 int * ip = alloc();                                                     $\C{// select type and size from left-hand side}$
    504 double * dp = alloc();
    505 struct S {...} * sp = alloc();
    506 \end{cfa}
    507 where the return type supplies the type/size of the allocation, which is impossible in most type systems.
    508 
    509 
    510 \subsection{Constructors / Destructors}
    511 
    512 Object lifetime is a challenge in non-managed programming languages.
    513 \CFA responds with \CC-like constructors and destructors:
    514 \begin{cfa}
    515 struct VLA { int len, * data; };                        $\C{// variable length array of integers}$
    516 void ?{}( VLA & vla ) with ( vla ) { len = 10;  data = alloc( len ); }  // default constructor
    517 void ?{}( VLA & vla, int size, char fill ) with ( vla ) { len = size;  data = alloc( len, fill ); } // initialization
    518 void ?{}( VLA & vla, VLA other ) { vla.len = other.len;  vla.data = other.data; } // copy, shallow
    519 void ^?{}( 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}
    532 Like \CC, construction is implicit on allocation (stack/heap) and destruction is implicit on deallocation.
    533 The 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}$
    539 struct S * s = new();                                           $\C{// allocation, call constructor}$
    540 ...
    541 delete( 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 
     427forall( otype T | summable(T) ) $\C{// use trait}$
     428T sum(T a[], size_t size);
     429\end{cfa}
     430
     431Note that the type use for assertions can be either an @otype@ or a @dtype@.
     432Types declared as @otype@ refer to ``complete'' objects, \ie objects with a size, a default constructor, a copy constructor, a destructor and an assignment operator.
     433Using @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}
     437Since \CFA lacks the concept of a receiver, certain functions end up needing to repeat variable names often.
     438To remove this inconvenience, \CFA provides the @with@ statement, which opens an aggregate scope making its fields directly accessible (like Pascal).
     439\begin{cfa}
     440struct S { int i, j; };
     441int mem(S & this) with (this)           $\C{// with clause}$
     442        i = 1;                                                  $\C{// this->i}$
     443        j = 2;                                                  $\C{// this->j}$
     444}
     445int 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
     463For more information on \CFA see \cite{cforall-ug,Schluntz17,www-cfa}.
     464
     465% ======================================================================
     466% ======================================================================
    546467\section{Concurrency Basics}\label{basics}
    547 
    548 At its core, concurrency is based on multiple call-stacks and scheduling among threads executing on these stacks.
     468% ======================================================================
     469% ======================================================================
     470
     471At its core, concurrency is based on having multiple call-stacks and scheduling among threads of execution executing on these stacks.
    549472Multiple call stacks (or contexts) and a single thread of execution does \emph{not} imply concurrency.
    550473Execution with a single thread and multiple stacks where the thread is deterministically self-scheduling across the stacks is called \newterm{coroutining};
     
    662585\begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
    663586`coroutine` Fib { int fn; };
    664 void ?{}( Fibonacci & fib ) with( fib ) { fn = 0; }
    665587void main( Fib & f ) with( f ) {
    666588        int f1, f2;
Note: See TracChangeset for help on using the changeset viewer.