Ignore:
File:
1 edited

Legend:

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

    r08b5a7e r5453237  
    33\articletype{RESEARCH ARTICLE}%
    44
    5 \received{26 April 2016}
    6 \revised{6 June 2016}
    7 \accepted{6 June 2016}
     5% Referees
     6% Doug Lea, dl@cs.oswego.edu, SUNY Oswego
     7% Herb Sutter, hsutter@microsoft.com, Microsoft Corp
     8% Gor Nishanov, gorn@microsoft.com, Microsoft Corp
     9% James Noble, kjx@ecs.vuw.ac.nz, Victoria University of Wellington, School of Engineering and Computer Science
     10
     11\received{XXXXX}
     12\revised{XXXXX}
     13\accepted{XXXXX}
    814
    915\raggedbottom
     
    1521\usepackage{epic,eepic}
    1622\usepackage{xspace}
     23\usepackage{enumitem}
    1724\usepackage{comment}
    1825\usepackage{upquote}                                            % switch curled `'" to straight
     
    2128\renewcommand{\thesubfigure}{(\Alph{subfigure})}
    2229\captionsetup{justification=raggedright,singlelinecheck=false}
    23 \usepackage{siunitx}
    24 \sisetup{binary-units=true}
     30\usepackage{dcolumn}                                            % align decimal points in tables
     31\usepackage{capt-of}
     32\setlength{\multicolsep}{6.0pt plus 2.0pt minus 1.5pt}
    2533
    2634\hypersetup{breaklinks=true}
     
    3240\renewcommand{\linenumberfont}{\scriptsize\sffamily}
    3341
     42\renewcommand{\topfraction}{0.8}                        % float must be greater than X of the page before it is forced onto its own page
     43\renewcommand{\bottomfraction}{0.8}                     % float must be greater than X of the page before it is forced onto its own page
     44\renewcommand{\floatpagefraction}{0.8}          % float must be greater than X of the page before it is forced onto its own page
    3445\renewcommand{\textfraction}{0.0}                       % the entire page maybe devoted to floats with no text on the page at all
    3546
     
    132143\makeatother
    133144
    134 \newenvironment{cquote}{%
    135         \list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=3pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}%
    136         \item\relax
    137 }{%
    138         \endlist
    139 }% cquote
     145\newenvironment{cquote}
     146               {\list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=3pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}%
     147                \item\relax}
     148               {\endlist}
     149
     150%\newenvironment{cquote}{%
     151%\list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=3pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}%
     152%\item\relax%
     153%}{%
     154%\endlist%
     155%}% cquote
    140156
    141157% CFA programming language, based on ANSI C (with some gcc additions)
     
    145161                auto, _Bool, catch, catchResume, choose, _Complex, __complex, __complex__, __const, __const__,
    146162                coroutine, disable, dtype, enable, exception, __extension__, fallthrough, fallthru, finally,
    147                 __float80, float80, __float128, float128, forall, ftype, _Generic, _Imaginary, __imag, __imag__,
     163                __float80, float80, __float128, float128, forall, ftype, generator, _Generic, _Imaginary, __imag, __imag__,
    148164                inline, __inline, __inline__, __int128, int128, __label__, monitor, mutex, _Noreturn, one_t, or,
    149165                otype, restrict, __restrict, __restrict__, __signed, __signed__, _Static_assert, thread,
    150166                _Thread_local, throw, throwResume, timeout, trait, try, ttype, typeof, __typeof, __typeof__,
    151167                virtual, __volatile, __volatile__, waitfor, when, with, zero_t},
    152         moredirectives={defined,include_next}%
     168        moredirectives={defined,include_next},
     169        % replace/adjust listing characters that look bad in sanserif
     170        literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptstyle\land\,$}}1
     171                {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1
     172                {<}{\textrm{\textless}}1 {>}{\textrm{\textgreater}}1
     173                {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.5ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex{\textrm{\textgreater}}}2,
    153174}
    154175
     
    167188aboveskip=4pt,                                                                                  % spacing above/below code block
    168189belowskip=3pt,
    169 % replace/adjust listing characters that look bad in sanserif
    170 literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptstyle\land\,$}}1
    171         {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1
    172         {<}{\textrm{\textless}}1 {>}{\textrm{\textgreater}}1
    173         {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.5ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex{\textrm{\textgreater}}}2,
    174190moredelim=**[is][\color{red}]{`}{`},
    175191}% lstset
     
    197213}
    198214
     215% Go programming language: https://github.com/julienc91/listings-golang/blob/master/listings-golang.sty
     216\lstdefinelanguage{Golang}{
     217        morekeywords=[1]{package,import,func,type,struct,return,defer,panic,recover,select,var,const,iota,},
     218        morekeywords=[2]{string,uint,uint8,uint16,uint32,uint64,int,int8,int16,int32,int64,
     219                bool,float32,float64,complex64,complex128,byte,rune,uintptr, error,interface},
     220        morekeywords=[3]{map,slice,make,new,nil,len,cap,copy,close,true,false,delete,append,real,imag,complex,chan,},
     221        morekeywords=[4]{for,break,continue,range,goto,switch,case,fallthrough,if,else,default,},
     222        morekeywords=[5]{Println,Printf,Error,},
     223        sensitive=true,
     224        morecomment=[l]{//},
     225        morecomment=[s]{/*}{*/},
     226        morestring=[b]',
     227        morestring=[b]",
     228        morestring=[s]{`}{`},
     229        % replace/adjust listing characters that look bad in sanserif
     230        literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptstyle\land\,$}}1
     231                {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1
     232                {<}{\textrm{\textless}}1 {>}{\textrm{\textgreater}}1
     233                {<-}{\makebox[2ex][c]{\textrm{\textless}\raisebox{0.5ex}{\rule{0.8ex}{0.075ex}}}}2,
     234}
     235
    199236\lstnewenvironment{cfa}[1][]
    200237{\lstset{#1}}
     
    207244{}
    208245\lstnewenvironment{Go}[1][]
    209 {\lstset{#1}}
     246{\lstset{language=Golang,moredelim=**[is][\protect\color{red}]{`}{`},#1}\lstset{#1}}
     247{}
     248\lstnewenvironment{python}[1][]
     249{\lstset{language=python,moredelim=**[is][\protect\color{red}]{`}{`},#1}\lstset{#1}}
    210250{}
    211251
     
    220260}
    221261
    222 \title{\texorpdfstring{Concurrency in \protect\CFA}{Concurrency in Cforall}}
     262\newbox\myboxA
     263\newbox\myboxB
     264\newbox\myboxC
     265\newbox\myboxD
     266
     267\title{\texorpdfstring{Advanced Control-flow and Concurrency in \protect\CFA}{Advanced Control-flow in Cforall}}
    223268
    224269\author[1]{Thierry Delisle}
     
    230275\corres{*Peter A. Buhr, Cheriton School of Computer Science, University of Waterloo, 200 University Avenue West, Waterloo, ON, N2L 3G1, Canada. \email{pabuhr{\char`\@}uwaterloo.ca}}
    231276
    232 \fundingInfo{Natural Sciences and Engineering Research Council of Canada}
     277% \fundingInfo{Natural Sciences and Engineering Research Council of Canada}
    233278
    234279\abstract[Summary]{
    235 \CFA is a modern, polymorphic, \emph{non-object-oriented} extension of the C programming language.
    236 This paper discusses the design of the concurrency and parallelism features in \CFA, and the concurrent runtime-system.
    237 These features are created from scratch as ISO C lacks concurrency, relying largely on the pthreads library.
    238 Coroutines and lightweight (user) threads are introduced into the language.
    239 In addition, monitors are added as a high-level mechanism for mutual exclusion and synchronization.
    240 A unique contribution is allowing multiple monitors to be safely acquired simultaneously.
    241 All features respect the expectations of C programmers, while being fully integrate with the \CFA polymorphic type-system and other language features.
    242 Finally, experimental results are presented to compare the performance of the new features with similar mechanisms in other concurrent programming-languages.
     280\CFA is a polymorphic, non-object-oriented, concurrent, backwards-compatible extension of the C programming language.
     281This paper discusses the design philosophy and implementation of its advanced control-flow and concurrent/parallel features, along with the supporting runtime written in \CFA.
     282These features are created from scratch as ISO C has only low-level and/or unimplemented concurrency, so C programmers continue to rely on library features like pthreads.
     283\CFA introduces modern language-level control-flow mechanisms, like generators, coroutines, user-level threading, and monitors for mutual exclusion and synchronization.
     284% Library extension for executors, futures, and actors are built on these basic mechanisms.
     285The runtime provides significant programmer simplification and safety by eliminating spurious wakeup and monitor barging.
     286The runtime also ensures multiple monitors can be safely acquired \emph{simultaneously} (deadlock free), and this feature is fully integrated with all monitor synchronization mechanisms.
     287All control-flow features integrate with the \CFA polymorphic type-system and exception handling, while respecting the expectations and style of C programmers.
     288Experimental results show comparable performance of the new features with similar mechanisms in other concurrent programming languages.
    243289}%
    244290
    245 \keywords{concurrency, parallelism, coroutines, threads, monitors, runtime, C, Cforall}
     291\keywords{generator, coroutine, concurrency, parallelism, thread, monitor, runtime, C, \CFA (Cforall)}
    246292
    247293
     
    254300\section{Introduction}
    255301
    256 This paper provides a minimal concurrency \newterm{Application Program Interface} (API) that is simple, efficient and can be used to build other concurrency features.
    257 While the simplest concurrency system is a thread and a lock, this low-level approach is hard to master.
    258 An easier approach for programmers is to support higher-level constructs as the basis of concurrency.
    259 Indeed, for highly productive concurrent programming, high-level approaches are much more popular~\cite{Hochstein05}.
    260 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}.
    261 
    262 The following terminology is used.
    263 A \newterm{thread} is a fundamental unit of execution that runs a sequence of code and requires a stack to maintain state.
    264 Multiple simultaneous threads give rise to \newterm{concurrency}, which requires locking to ensure safe communication and access to shared data.
    265 % Correspondingly, concurrency is defined as the concepts and challenges that occur when multiple independent (sharing memory, timing dependencies, \etc) concurrent threads are introduced.
    266 \newterm{Locking}, and by extension \newterm{locks}, are defined as a mechanism to prevent progress of threads to provide safety.
    267 \newterm{Parallelism} is running multiple threads simultaneously.
    268 Parallelism implies \emph{actual} simultaneous execution, where concurrency only requires \emph{apparent} simultaneous execution.
    269 As such, parallelism only affects performance, which is observed through differences in space and/or time at runtime.
    270 
    271 Hence, there are two problems to be solved: concurrency and parallelism.
    272 While these two concepts are often combined, they are distinct, requiring different tools~\cite[\S~2]{Buhr05a}.
    273 Concurrency tools handle synchronization and mutual exclusion, while parallelism tools handle performance, cost and resource utilization.
    274 
    275 The proposed concurrency API is implemented in a dialect of C, called \CFA.
    276 The paper discusses how the language features are added to the \CFA translator with respect to parsing, semantic, and type checking, and the corresponding high-performance runtime-library to implement the concurrency features.
    277 
    278 
    279 \section{\CFA Overview}
    280 
    281 The following is a quick introduction to the \CFA language, specifically tailored to the features needed to support concurrency.
    282 Extended versions and explanation of the following code examples are available at the \CFA website~\cite{Cforall} or in Moss~\etal~\cite{Moss18}.
    283 
    284 \CFA is an extension of ISO-C, and hence, supports all C paradigms.
    285 %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.
    286 Like C, the basics of \CFA revolve around structures and routines.
    287 Virtually all of the code generated by the \CFA translator respects C memory layouts and calling conventions.
    288 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}.
    289 While some \CFA features are common in object-oriented programming-languages, they are an independent capability allowing \CFA to adopt them while retaining a procedural paradigm.
    290 
    291 
    292 \subsection{References}
    293 
    294 \CFA provides multi-level rebindable references, as an alternative to pointers, which significantly reduces syntactic noise.
    295 \begin{cfa}
    296 int x = 1, y = 2, z = 3;
    297 int * p1 = &x, ** p2 = &p1,  *** p3 = &p2,      $\C{// pointers to x}$
    298         `&` r1 = x,  `&&` r2 = r1,  `&&&` r3 = r2;      $\C{// references to x}$
    299 int * p4 = &z, `&` r4 = z;
    300 
    301 *p1 = 3; **p2 = 3; ***p3 = 3;       // change x
    302 r1 =  3;     r2 = 3;      r3 = 3;        // change x: implicit dereferences *r1, **r2, ***r3
    303 **p3 = &y; *p3 = &p4;                // change p1, p2
    304 `&`r3 = &y; `&&`r3 = &`&`r4;             // change r1, r2: cancel implicit dereferences (&*)**r3, (&(&*)*)*r3, &(&*)r4
    305 \end{cfa}
    306 A reference is a handle to an object, like a pointer, but is automatically dereferenced the specified number of levels.
    307 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.
    308 
    309 
    310 \subsection{\texorpdfstring{\protect\lstinline{with} Statement}{with Statement}}
    311 \label{s:WithStatement}
    312 
    313 Heterogeneous data is aggregated into a structure/union.
    314 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.
    315 \begin{cquote}
    316 \vspace*{-\baselineskip}%???
    317 \lstDeleteShortInline@%
    318 \begin{cfa}
    319 struct S { char c; int i; double d; };
    320 struct T { double m, n; };
    321 // multiple aggregate parameters
    322 \end{cfa}
    323 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}|@{\hspace{2\parindentlnth}}l@{}}
    324 \begin{cfa}
    325 void f( S & s, T & t ) {
    326         `s.`c; `s.`i; `s.`d;
    327         `t.`m; `t.`n;
    328 }
    329 \end{cfa}
    330 &
    331 \begin{cfa}
    332 void f( S & s, T & t ) `with ( s, t )` {
    333         c; i; d;                // no qualification
    334         m; n;
    335 }
    336 \end{cfa}
    337 \end{tabular}
    338 \lstMakeShortInline@%
    339 \end{cquote}
    340 Object-oriented programming languages only provide implicit qualification for the receiver.
    341 
    342 In detail, the @with@ statement has the form:
    343 \begin{cfa}
    344 $\emph{with-statement}$:
    345         'with' '(' $\emph{expression-list}$ ')' $\emph{compound-statement}$
    346 \end{cfa}
    347 and may appear as the body of a routine or nested within a routine body.
    348 Each expression in the expression-list provides a type and object.
    349 The type must be an aggregate type.
    350 (Enumerations are already opened.)
    351 The object is the implicit qualifier for the open structure-fields.
    352 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.
    353 
    354 
    355 \subsection{Overloading}
    356 
    357 \CFA maximizes the ability to reuse names via overloading to aggressively address the naming problem.
    358 Both variables and routines may be overloaded, where selection is based on types, and number of returns (as in Ada~\cite{Ada}) and arguments.
    359 \begin{cquote}
    360 \vspace*{-\baselineskip}%???
    361 \lstDeleteShortInline@%
    362 \begin{cfa}
    363 // selection based on type
    364 \end{cfa}
    365 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}|@{\hspace{2\parindentlnth}}l@{}}
    366 \begin{cfa}
    367 const short int `MIN` = -32768;
    368 const int `MIN` = -2147483648;
    369 const long int `MIN` = -9223372036854775808L;
    370 \end{cfa}
    371 &
    372 \begin{cfa}
    373 short int si = `MIN`;
    374 int i = `MIN`;
    375 long int li = `MIN`;
    376 \end{cfa}
    377 \end{tabular}
    378 \begin{cfa}
    379 // selection based on type and number of parameters
    380 \end{cfa}
    381 \begin{tabular}{@{}l@{\hspace{2.7\parindentlnth}}|@{\hspace{2\parindentlnth}}l@{}}
    382 \begin{cfa}
    383 void `f`( void );
    384 void `f`( char );
    385 void `f`( int, double );
    386 \end{cfa}
    387 &
    388 \begin{cfa}
    389 `f`();
    390 `f`( 'a' );
    391 `f`( 3, 5.2 );
    392 \end{cfa}
    393 \end{tabular}
    394 \begin{cfa}
    395 // selection based on type and number of returns
    396 \end{cfa}
    397 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}|@{\hspace{2\parindentlnth}}l@{}}
    398 \begin{cfa}
    399 char `f`( int );
    400 double `f`( int );
    401 [char, double] `f`( int );
    402 \end{cfa}
    403 &
    404 \begin{cfa}
    405 char c = `f`( 3 );
    406 double d = `f`( 3 );
    407 [d, c] = `f`( 3 );
    408 \end{cfa}
    409 \end{tabular}
    410 \lstMakeShortInline@%
    411 \end{cquote}
    412 Overloading is important for \CFA concurrency since the runtime system relies on creating different types to represent concurrency objects.
    413 Therefore, overloading is necessary to prevent the need for long prefixes and other naming conventions to prevent name clashes.
    414 As seen in Section~\ref{basics}, routine @main@ is heavily overloaded.
    415 
    416 Variable overloading is useful in the parallel semantics of the @with@ statement for fields with the same name:
    417 \begin{cfa}
    418 struct S { int `i`; int j; double m; } s;
    419 struct T { int `i`; int k; int m; } t;
    420 with ( s, t ) {
    421         j + k;                                                                  $\C{// unambiguous, s.j + t.k}$
    422         m = 5.0;                                                                $\C{// unambiguous, s.m = 5.0}$
    423         m = 1;                                                                  $\C{// unambiguous, t.m = 1}$
    424         int a = m;                                                              $\C{// unambiguous, a = t.m }$
    425         double b = m;                                                   $\C{// unambiguous, b = s.m}$
    426         int c = `s.i` + `t.i`;                                  $\C{// unambiguous, qualification}$
    427         (double)m;                                                              $\C{// unambiguous, cast s.m}$
    428 }
    429 \end{cfa}
    430 For parallel semantics, both @s.i@ and @t.i@ are visible the same type, so only @i@ is ambiguous without qualification.
    431 
    432 
    433 \subsection{Operators}
    434 
    435 Overloading also extends to operators.
    436 Operator-overloading syntax creates a routine name with an operator symbol and question marks for the operands:
    437 \begin{cquote}
    438 \lstDeleteShortInline@%
    439 \begin{tabular}{@{}ll@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}}
    440 \begin{cfa}
    441 int ++? (int op);
    442 int ?++ (int op);
    443 int `?+?` (int op1, int op2);
    444 int ?<=?(int op1, int op2);
    445 int ?=? (int & op1, int op2);
    446 int ?+=?(int & op1, int op2);
    447 \end{cfa}
    448 &
    449 \begin{cfa}
    450 // unary prefix increment
    451 // unary postfix increment
    452 // binary plus
    453 // binary less than
    454 // binary assignment
    455 // binary plus-assignment
    456 \end{cfa}
    457 &
    458 \begin{cfa}
    459 struct S { int i, j; };
    460 S `?+?`( S op1, S op2) { // add two structures
    461         return (S){op1.i + op2.i, op1.j + op2.j};
    462 }
    463 S s1 = {1, 2}, s2 = {2, 3}, s3;
    464 s3 = s1 `+` s2;         // compute sum: s3 == {2, 5}
    465 \end{cfa}
    466 \end{tabular}
    467 \lstMakeShortInline@%
    468 \end{cquote}
    469 While concurrency does not use operator overloading directly, it provides an introduction for the syntax of constructors.
    470 
    471 
    472 \subsection{Parametric Polymorphism}
    473 \label{s:ParametricPolymorphism}
    474 
    475 The signature feature of \CFA is parametric-polymorphic routines~\cite{} with routines generalized using a @forall@ clause (giving the language its name), which allow separately compiled routines to support generic usage over multiple types.
    476 For example, the following sum routine works for any type that supports construction from 0 and addition:
    477 \begin{cfa}
    478 forall( otype T | { void `?{}`( T *, zero_t ); T `?+?`( T, T ); } ) // constraint type, 0 and +
    479 T sum( T a[$\,$], size_t size ) {
    480         `T` total = { `0` };                                    $\C{// initialize by 0 constructor}$
    481         for ( size_t i = 0; i < size; i += 1 )
    482                 total = total `+` a[i];                         $\C{// select appropriate +}$
    483         return total;
    484 }
    485 S sa[5];
    486 int i = sum( sa, 5 );                                           $\C{// use S's 0 construction and +}$
    487 \end{cfa}
    488 
    489 \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 routine declaration:
    490 \begin{cfa}
    491 trait `sumable`( otype T ) {
    492         void `?{}`( T &, zero_t );                              $\C{// 0 literal constructor}$
    493         T `?+?`( T, T );                                                $\C{// assortment of additions}$
    494         T ?+=?( T &, T );
    495         T ++?( T & );
    496         T ?++( T & );
    497 };
    498 forall( otype T `| sumable( T )` )                      $\C{// use trait}$
    499 T sum( T a[$\,$], size_t size );
    500 \end{cfa}
    501 
    502 Assertions can be @otype@ or @dtype@.
    503 @otype@ refers to a ``complete'' object, \ie an object has a size, default constructor, copy constructor, destructor and an assignment operator.
    504 @dtype@ only guarantees an object has a size and alignment.
    505 
    506 Using the return type for discrimination, it is possible to write a type-safe @alloc@ based on the C @malloc@:
    507 \begin{cfa}
    508 forall( dtype T | sized(T) ) T * alloc( void ) { return (T *)malloc( sizeof(T) ); }
    509 int * ip = alloc();                                                     $\C{// select type and size from left-hand side}$
    510 double * dp = alloc();
    511 struct S {...} * sp = alloc();
    512 \end{cfa}
    513 where the return type supplies the type/size of the allocation, which is impossible in most type systems.
    514 
    515 
    516 \subsection{Constructors / Destructors}
    517 
    518 Object lifetime is a challenge in non-managed programming languages.
    519 \CFA responds with \CC-like constructors and destructors:
    520 \begin{cfa}
    521 struct VLA { int len, * data; };                        $\C{// variable length array of integers}$
    522 void ?{}( VLA & vla ) with ( vla ) { len = 10;  data = alloc( len ); }  $\C{// default constructor}$
    523 void ?{}( VLA & vla, int size, char fill ) with ( vla ) { len = size;  data = alloc( len, fill ); } // initialization
    524 void ?{}( VLA & vla, VLA other ) { vla.len = other.len;  vla.data = other.data; } $\C{// copy, shallow}$
    525 void ^?{}( VLA & vla ) with ( vla ) { free( data ); } $\C{// destructor}$
    526 {
    527         VLA  x,            y = { 20, 0x01 },     z = y; $\C{// z points to y}$
    528         //    x{};         y{ 20, 0x01 };          z{ z, y };
    529         ^x{};                                                                   $\C{// deallocate x}$
    530         x{};                                                                    $\C{// reallocate x}$
    531         z{ 5, 0xff };                                                   $\C{// reallocate z, not pointing to y}$
    532         ^y{};                                                                   $\C{// deallocate y}$
    533         y{ x };                                                                 $\C{// reallocate y, points to x}$
    534         x{};                                                                    $\C{// reallocate x, not pointing to y}$
    535         //  ^z{};  ^y{};  ^x{};
    536 }
    537 \end{cfa}
    538 Like \CC, construction is implicit on allocation (stack/heap) and destruction is implicit on deallocation.
    539 The object and all their fields are constructed/destructed.
    540 \CFA also provides @new@ and @delete@, which behave like @malloc@ and @free@, in addition to constructing and destructing objects:
    541 \begin{cfa}
    542 {       struct S s = {10};                                              $\C{// allocation, call constructor}$
    543         ...
    544 }                                                                                       $\C{// deallocation, call destructor}$
    545 struct S * s = new();                                           $\C{// allocation, call constructor}$
    546 ...
    547 delete( s );                                                            $\C{// deallocation, call destructor}$
    548 \end{cfa}
    549 \CFA concurrency uses object lifetime as a means of synchronization and/or mutual exclusion.
    550 
    551 
    552 \section{Concurrency Basics}\label{basics}
    553 
    554 At its core, concurrency is based on multiple call-stacks and scheduling threads executing on these stacks.
    555 Multiple call stacks (or contexts) and a single thread of execution, called \newterm{coroutining}~\cite{Conway63,Marlin80}, does \emph{not} imply concurrency~\cite[\S~2]{Buhr05a}.
    556 In coroutining, the single thread is self-scheduling across the stacks, so execution is deterministic, \ie given fixed inputs, the execution path to the outputs is fixed and predictable.
    557 A \newterm{stackless} coroutine executes on the caller's stack~\cite{Python} but this approach is restrictive, \eg preventing modularization and supporting only iterator/generator-style programming;
    558 a \newterm{stackfull} coroutine executes on its own stack, allowing full generality.
    559 Only stackfull coroutines are a stepping-stone to concurrency.
    560 
    561 The transition to concurrency, even for execution with a single thread and multiple stacks, occurs when coroutines also context switch to a scheduling oracle, introducing non-determinism from the coroutine perspective~\cite[\S~3]{Buhr05a}.
    562 Therefore, a minimal concurrency system is possible using coroutines (see Section \ref{coroutine}) in conjunction with a scheduler to decide where to context switch next.
    563 The resulting execution system now follows a cooperative threading-model, called \newterm{non-preemptive scheduling}.
    564 
    565 Because the scheduler is special, it can either be a stackless or stackfull coroutine.
    566 For stackless, the scheduler performs scheduling on the stack of the current coroutine and switches directly to the next coroutine, so there is one context switch.
    567 For stackfull, the current coroutine switches to the scheduler, which performs scheduling, and it then switches to the next coroutine, so there are two context switches.
    568 A stackfull scheduler is often used for simplicity and security, even through there is a slightly higher runtime-cost.
    569 
    570 Regardless of the approach used, a subset of concurrency related challenges start to appear.
    571 For the complete set of concurrency challenges to occur, the missing feature is \newterm{preemption}, where context switching occurs randomly between any two instructions, often based on a timer interrupt, called \newterm{preemptive scheduling}.
    572 While a scheduler introduces uncertainty in the order of execution, preemption introduces uncertainty where context switches occur.
    573 Interestingly, uncertainty is necessary for the runtime (operating) system to give the illusion of parallelism on a single processor and increase performance on multiple processors.
    574 The reason is that only the runtime has complete knowledge about resources and how to best utilized them.
    575 However, the introduction of unrestricted non-determinism results in the need for \newterm{mutual exclusion} and \newterm{synchronization} to restrict non-determinism for correctness;
    576 otherwise, it is impossible to write meaningful programs.
    577 Optimal performance in concurrent applications is often obtained by having as much non-determinism as correctness allows.
    578 
    579 
    580 \subsection{\protect\CFA's Thread Building Blocks}
    581 
    582 An important missing feature in C is threading\footnote{While the C11 standard defines a ``threads.h'' header, it is minimal and defined as optional.
    583 As such, library support for threading is far from widespread.
    584 At the time of writing the paper, neither \protect\lstinline|gcc| nor \protect\lstinline|clang| support ``threads.h'' in their standard libraries.}.
    585 In modern programming languages, a lack of threading is unacceptable~\cite{Sutter05, Sutter05b}, and therefore existing and new programming languages must have tools for writing efficient concurrent programs to take advantage of parallelism.
    586 As an extension of C, \CFA needs to express these concepts in a way that is as natural as possible to programmers familiar with imperative languages.
    587 Furthermore, because C is a system-level language, programmers expect to choose precisely which features they need and which cost they are willing to pay.
    588 Hence, concurrent programs should be written using high-level mechanisms, and only step down to lower-level mechanisms when performance bottlenecks are encountered.
    589 
    590 
    591 \subsection{Coroutines: A Stepping Stone}\label{coroutine}
    592 
    593 While the focus of this discussion is concurrency and parallelism, it is important to address coroutines, which are a significant building block of a concurrency system.
    594 Coroutines are generalized routines allowing execution to be temporarily suspend and later resumed.
    595 Hence, unlike a normal routine, a coroutine may not terminate when it returns to its caller, allowing it to be restarted with the values and execution location present at the point of suspension.
    596 This capability is accomplish via the coroutine's stack, where suspend/resume context switch among stacks.
    597 Because threading design-challenges are present in coroutines, their design effort is relevant, and this effort can be easily exposed to programmers giving them a useful new programming paradigm because a coroutine handles the class of problems that need to retain state between calls, \eg plugins, device drivers, and finite-state machines.
    598 Therefore, the core \CFA coroutine-API for has two fundamental features: independent call-stacks and @suspend@/@resume@ operations.
    599 
    600 For example, a problem made easier with coroutines is unbounded generators, \eg generating an infinite sequence of Fibonacci numbers, where Figure~\ref{f:C-fibonacci} shows conventional approaches for writing a Fibonacci generator in C.
    601 \begin{displaymath}
    602 \mathsf{fib}(n) = \left \{
    603 \begin{array}{ll}
    604 0                                       & n = 0         \\
    605 1                                       & n = 1         \\
    606 \mathsf{fib}(n-1) + \mathsf{fib}(n-2)   & n \ge 2       \\
    607 \end{array}
    608 \right.
    609 \end{displaymath}
    610 Figure~\ref{f:GlobalVariables} illustrates the following problems:
    611 unique unencapsulated global variables necessary to retain state between calls;
    612 only one Fibonacci generator;
    613 execution state must be explicitly retained via explicit state variables.
    614 Figure~\ref{f:ExternalState} addresses these issues:
    615 unencapsulated program global variables become encapsulated structure variables;
    616 unique global variables are replaced by multiple Fibonacci objects;
    617 explicit execution state is removed by precomputing the first two Fibonacci numbers and returning $\mathsf{fib}(n-2)$.
     302This paper discusses the design philosophy and implementation of advanced language-level control-flow and concurrent/parallel features in \CFA~\cite{Moss18,Cforall} and its runtime, which is written entirely in \CFA.
     303\CFA is a modern, polymorphic, non-object-oriented\footnote{
     304\CFA has features often associated with object-oriented programming languages, such as constructors, destructors, virtuals and simple inheritance.
     305However, functions \emph{cannot} be nested in structures, so there is no lexical binding between a structure and set of functions (member/method) implemented by an implicit \lstinline@this@ (receiver) parameter.},
     306backwards-compatible extension of the C programming language.
     307In many ways, \CFA is to C as Scala~\cite{Scala} is to Java, providing a \emph{research vehicle} for new typing and control-flow capabilities on top of a highly popular programming language allowing immediate dissemination.
     308Within the \CFA framework, new control-flow features are created from scratch because ISO \Celeven defines only a subset of the \CFA extensions, where the overlapping features are concurrency~\cite[\S~7.26]{C11}.
     309However, \Celeven concurrency is largely wrappers for a subset of the pthreads library~\cite{Butenhof97,Pthreads}, and \Celeven and pthreads concurrency is simple, based on thread fork/join in a function and mutex/condition locks, which is low-level and error-prone;
     310no high-level language concurrency features are defined.
     311Interestingly, almost a decade after publication of the \Celeven standard, neither gcc-8, clang-9 nor msvc-19 (most recent versions) support the \Celeven include @threads.h@, indicating little interest in the C11 concurrency approach (possibly because the effort to add concurrency to \CC).
     312Finally, while the \Celeven standard does not state a threading model, the historical association with pthreads suggests implementations would adopt kernel-level threading (1:1)~\cite{ThreadModel}.
     313
     314In contrast, there has been a renewed interest during the past decade in user-level (M:N, green) threading in old and new programming languages.
     315As multi-core hardware became available in the 1980/90s, both user and kernel threading were examined.
     316Kernel threading was chosen, largely because of its simplicity and fit with the simpler operating systems and hardware architectures at the time, which gave it a performance advantage~\cite{Drepper03}.
     317Libraries like pthreads were developed for C, and the Solaris operating-system switched from user (JDK 1.1~\cite{JDK1.1}) to kernel threads.
     318As a result, languages like Java, Scala, Objective-C~\cite{obj-c-book}, \CCeleven~\cite{C11}, and C\#~\cite{Csharp} adopt the 1:1 kernel-threading model, with a variety of presentation mechanisms.
     319From 2000 onwards, languages like Go~\cite{Go}, Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, D~\cite{D}, and \uC~\cite{uC++,uC++book} have championed the M:N user-threading model, and many user-threading libraries have appeared~\cite{Qthreads,MPC,Marcel}, including putting green threads back into Java~\cite{Quasar}.
     320The main argument for user-level threading is that it is lighter weight than kernel threading (locking and context switching do not cross the kernel boundary), so there is less restriction on programming styles that encourage large numbers of threads performing medium work units to facilitate load balancing by the runtime~\cite{Verch12}.
     321As well, user-threading facilitates a simpler concurrency approach using thread objects that leverage sequential patterns versus events with call-backs~\cite{Adya02,vonBehren03}.
     322Finally, performant user-threading implementations (both time and space) meet or exceed direct kernel-threading implementations, while achieving the programming advantages of high concurrency levels and safety.
     323
     324A further effort over the past two decades is the development of language memory models to deal with the conflict between language features and compiler/hardware optimizations, \ie some language features are unsafe in the presence of aggressive sequential optimizations~\cite{Buhr95a,Boehm05}.
     325The consequence is that a language must provide sufficient tools to program around safety issues, as inline and library code is all sequential to the compiler.
     326One solution is low-level qualifiers and functions (\eg @volatile@ and atomics) allowing \emph{programmers} to explicitly write safe (race-free~\cite{Boehm12}) programs.
     327A safer solution is high-level language constructs so the \emph{compiler} knows the optimization boundaries, and hence, provides implicit safety.
     328This problem is best known with respect to concurrency, but applies to other complex control-flow, like exceptions\footnote{
     329\CFA exception handling will be presented in a separate paper.
     330The key feature that dovetails with this paper is nonlocal exceptions allowing exceptions to be raised across stacks, with synchronous exceptions raised among coroutines and asynchronous exceptions raised among threads, similar to that in \uC~\cite[\S~5]{uC++}
     331} and coroutines.
     332Finally, language solutions allow matching constructs with language paradigm, \ie imperative and functional languages often have different presentations of the same concept to fit their programming model.
     333
     334Finally, it is important for a language to provide safety over performance \emph{as the default}, allowing careful reduction of safety for performance when necessary.
     335Two concurrency violations of this philosophy are \emph{spurious wakeup} (random wakeup~\cite[\S~8]{Buhr05a}) and \emph{barging}\footnote{
     336The notion of competitive succession instead of direct handoff, \ie a lock owner releases the lock and an arriving thread acquires it ahead of preexisting waiter threads.
     337} (signals-as-hints~\cite[\S~8]{Buhr05a}), where one is a consequence of the other, \ie once there is spurious wakeup, signals-as-hints follow.
     338However, spurious wakeup is \emph{not} a foundational concurrency property~\cite[\S~8]{Buhr05a}, it is a performance design choice.
     339Similarly, signals-as-hints are often a performance decision.
     340We argue removing spurious wakeup and signals-as-hints make concurrent programming significantly safer because it removes local non-determinism and matches with programmer expectation.
     341(Author experience teaching concurrency is that students are highly confused by these semantics.)
     342Clawing back performance, when local non-determinism is unimportant, should be an option not the default.
     343
     344\begin{comment}
     345Most augmented traditional (Fortran 18~\cite{Fortran18}, Cobol 14~\cite{Cobol14}, Ada 12~\cite{Ada12}, Java 11~\cite{Java11}) and new languages (Go~\cite{Go}, Rust~\cite{Rust}, and D~\cite{D}), except \CC, diverge from C with different syntax and semantics, only interoperate indirectly with C, and are not systems languages, for those with managed memory.
     346As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten.
     347While \CC, like \CFA, takes an evolutionary approach to extend C, \CC's constantly growing complex and interdependent features-set (\eg objects, inheritance, templates, etc.) mean idiomatic \CC code is difficult to use from C, and C programmers must expend significant effort learning \CC.
     348Hence, rewriting and retraining costs for these languages, even \CC, are prohibitive for companies with a large C software-base.
     349\CFA with its orthogonal feature-set, its high-performance runtime, and direct access to all existing C libraries circumvents these problems.
     350\end{comment}
     351
     352\CFA embraces user-level threading, language extensions for advanced control-flow, and safety as the default.
     353We present comparative examples so the reader can judge if the \CFA control-flow extensions are better and safer than those in other concurrent, imperative programming languages, and perform experiments to show the \CFA runtime is competitive with other similar mechanisms.
     354The main contributions of this work are:
     355\begin{itemize}[topsep=3pt,itemsep=1pt]
     356\item
     357language-level generators, coroutines and user-level threading, which respect the expectations of C programmers.
     358\item
     359monitor synchronization without barging, and the ability to safely acquiring multiple monitors \emph{simultaneously} (deadlock free), while seamlessly integrating these capabilities with all monitor synchronization mechanisms.
     360\item
     361providing statically type-safe interfaces that integrate with the \CFA polymorphic type-system and other language features.
     362% \item
     363% library extensions for executors, futures, and actors built on the basic mechanisms.
     364\item
     365a runtime system with no spurious wakeup.
     366\item
     367a dynamic partitioning mechanism to segregate the execution environment for specialized requirements.
     368% \item
     369% a non-blocking I/O library
     370\item
     371experimental results showing comparable performance of the new features with similar mechanisms in other programming languages.
     372\end{itemize}
     373
     374Section~\ref{s:StatefulFunction} begins advanced control by introducing sequential functions that retain data and execution state between calls, which produces constructs @generator@ and @coroutine@.
     375Section~\ref{s:Concurrency} begins concurrency, or how to create (fork) and destroy (join) a thread, which produces the @thread@ construct.
     376Section~\ref{s:MutualExclusionSynchronization} discusses the two mechanisms to restricted nondeterminism when controlling shared access to resources (mutual exclusion) and timing relationships among threads (synchronization).
     377Section~\ref{s:Monitor} shows how both mutual exclusion and synchronization are safely embedded in the @monitor@ and @thread@ constructs.
     378Section~\ref{s:CFARuntimeStructure} describes the large-scale mechanism to structure (cluster) threads and virtual processors (kernel threads).
     379Section~\ref{s:Performance} uses a series of microbenchmarks to compare \CFA threading with pthreads, Java OpenJDK-9, Go 1.12.6 and \uC 7.0.0.
     380
     381
     382\section{Stateful Function}
     383\label{s:StatefulFunction}
     384
     385The stateful function is an old idea~\cite{Conway63,Marlin80} that is new again~\cite{C++20Coroutine19}, where execution is temporarily suspended and later resumed, \eg plugin, device driver, finite-state machine.
     386Hence, a stateful function may not end when it returns to its caller, allowing it to be restarted with the data and execution location present at the point of suspension.
     387This capability is accomplished by retaining a data/execution \emph{closure} between invocations.
     388If the closure is fixed size, we call it a \emph{generator} (or \emph{stackless}), and its control flow is restricted, \eg suspending outside the generator is prohibited.
     389If the closure is variable size, we call it a \emph{coroutine} (or \emph{stackful}), and as the names implies, often implemented with a separate stack with no programming restrictions.
     390Hence, refactoring a stackless coroutine may require changing it to stackful.
     391A foundational property of all \emph{stateful functions} is that resume/suspend \emph{do not} cause incremental stack growth, \ie resume/suspend operations are remembered through the closure not the stack.
     392As well, activating a stateful function is \emph{asymmetric} or \emph{symmetric}, identified by resume/suspend (no cycles) and resume/resume (cycles).
     393A fixed closure activated by modified call/return is faster than a variable closure activated by context switching.
     394Additionally, any storage management for the closure (especially in unmanaged languages, \ie no garbage collection) must also be factored into design and performance.
     395Therefore, selecting between stackless and stackful semantics is a tradeoff between programming requirements and performance, where stackless is faster and stackful is more general.
     396Note, creation cost is amortized across usage, so activation cost is usually the dominant factor.
    618397
    619398\begin{figure}
    620399\centering
    621 \newbox\myboxA
    622400\begin{lrbox}{\myboxA}
    623401\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    624 `int f1, f2, state = 1;`   // single global variables
    625 int fib() {
    626         int fn;
    627         `switch ( state )` {  // explicit execution state
    628           case 1: fn = 0;  f1 = fn;  state = 2;  break;
    629           case 2: fn = 1;  f2 = f1;  f1 = fn;  state = 3;  break;
    630           case 3: fn = f1 + f2;  f2 = f1;  f1 = fn;  break;
    631         }
     402typedef struct {
     403        int fn1, fn;
     404} Fib;
     405#define FibCtor { 1, 0 }
     406int fib( Fib * f ) {
     407
     408
     409
     410        int fn = f->fn; f->fn = f->fn1;
     411                f->fn1 = f->fn + fn;
    632412        return fn;
     413
    633414}
    634415int main() {
    635 
    636         for ( int i = 0; i < 10; i += 1 ) {
    637                 printf( "%d\n", fib() );
    638         }
     416        Fib f1 = FibCtor, f2 = FibCtor;
     417        for ( int i = 0; i < 10; i += 1 )
     418                printf( "%d %d\n",
     419                           fib( &f1 ), fib( &f2 ) );
    639420}
    640421\end{cfa}
    641422\end{lrbox}
    642423
    643 \newbox\myboxB
    644424\begin{lrbox}{\myboxB}
    645425\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    646 #define FIB_INIT `{ 0, 1 }`
    647 typedef struct { int f2, f1; } Fib;
    648 int fib( Fib * f ) {
    649 
    650         int ret = f->f2;
    651         int fn = f->f1 + f->f2;
    652         f->f2 = f->f1; f->f1 = fn;
    653 
    654         return ret;
     426`generator` Fib {
     427        int fn1, fn;
     428};
     429
     430void `main(Fib & fib)` with(fib) {
     431
     432        [fn1, fn] = [1, 0];
     433        for () {
     434                `suspend;`
     435                [fn1, fn] = [fn, fn + fn1];
     436
     437        }
    655438}
    656439int main() {
    657         Fib f1 = FIB_INIT, f2 = FIB_INIT;
    658         for ( int i = 0; i < 10; i += 1 ) {
    659                 printf( "%d %d\n", fib( &f1 ), fib( &f2 ) );
     440        Fib f1, f2;
     441        for ( 10 )
     442                sout | `resume( f1 )`.fn
     443                         | `resume( f2 )`.fn;
     444}
     445\end{cfa}
     446\end{lrbox}
     447
     448\begin{lrbox}{\myboxC}
     449\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     450typedef struct {
     451        int fn1, fn;  void * `next`;
     452} Fib;
     453#define FibCtor { 1, 0, NULL }
     454Fib * comain( Fib * f ) {
     455        if ( f->next ) goto *f->next;
     456        f->next = &&s1;
     457        for ( ;; ) {
     458                return f;
     459          s1:; int fn = f->fn + f->fn1;
     460                        f->fn1 = f->fn; f->fn = fn;
    660461        }
    661462}
     463int main() {
     464        Fib f1 = FibCtor, f2 = FibCtor;
     465        for ( int i = 0; i < 10; i += 1 )
     466                printf("%d %d\n",comain(&f1)->fn,
     467                                 comain(&f2)->fn);
     468}
    662469\end{cfa}
    663470\end{lrbox}
    664471
    665 \subfloat[3 States: global variables]{\label{f:GlobalVariables}\usebox\myboxA}
    666 \qquad
    667 \subfloat[1 State: external variables]{\label{f:ExternalState}\usebox\myboxB}
    668 \caption{C Fibonacci Implementations}
    669 \label{f:C-fibonacci}
     472\subfloat[C asymmetric generator]{\label{f:CFibonacci}\usebox\myboxA}
     473\hspace{3pt}
     474\vrule
     475\hspace{3pt}
     476\subfloat[\CFA asymmetric generator]{\label{f:CFAFibonacciGen}\usebox\myboxB}
     477\hspace{3pt}
     478\vrule
     479\hspace{3pt}
     480\subfloat[C generator implementation]{\label{f:CFibonacciSim}\usebox\myboxC}
     481\caption{Fibonacci (output) asymmetric generator}
     482\label{f:FibonacciAsymmetricGenerator}
    670483
    671484\bigskip
    672485
    673 \newbox\myboxA
    674486\begin{lrbox}{\myboxA}
    675487\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    676 `coroutine` Fib { int fn; };
    677 void main( Fib & fib ) with( fib ) {
    678         int f1, f2;
    679         fn = 0;  f1 = fn;  `suspend()`;
    680         fn = 1;  f2 = f1;  f1 = fn;  `suspend()`;
    681         for ( ;; ) {
    682                 fn = f1 + f2;  f2 = f1;  f1 = fn;  `suspend()`;
     488`generator Fmt` {
     489        char ch;
     490        int g, b;
     491};
     492void ?{}( Fmt & fmt ) { `resume(fmt);` } // constructor
     493void ^?{}( Fmt & f ) with(f) { $\C[1.75in]{// destructor}$
     494        if ( g != 0 || b != 0 ) sout | nl; }
     495void `main( Fmt & f )` with(f) {
     496        for () { $\C{// until destructor call}$
     497                for ( ; g < 5; g += 1 ) { $\C{// groups}$
     498                        for ( ; b < 4; b += 1 ) { $\C{// blocks}$
     499                                `suspend;` $\C{// wait for character}$
     500                                while ( ch == '\n' ) `suspend;` // ignore
     501                                sout | ch;                                              // newline
     502                        } sout | " ";  // block spacer
     503                } sout | nl; // group newline
    683504        }
    684505}
    685 int next( Fib & fib ) with( fib ) {
    686         `resume( fib );`
    687         return fn;
    688 }
    689506int main() {
    690         Fib f1, f2;
    691         for ( int i = 1; i <= 10; i += 1 ) {
    692                 sout | next( f1 ) | next( f2 ) | endl;
     507        Fmt fmt; $\C{// fmt constructor called}$
     508        for () {
     509                sin | fmt.ch; $\C{// read into generator}$
     510          if ( eof( sin ) ) break;
     511                `resume( fmt );`
    693512        }
    694 }
     513
     514} $\C{// fmt destructor called}\CRT$
    695515\end{cfa}
    696516\end{lrbox}
    697 \newbox\myboxB
     517
    698518\begin{lrbox}{\myboxB}
    699519\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    700 `coroutine` Fib { int ret; };
    701 void main( Fib & f ) with( fib ) {
    702         int fn, f1 = 1, f2 = 0;
     520typedef struct {
     521        void * next;
     522        char ch;
     523        int g, b;
     524} Fmt;
     525void comain( Fmt * f ) {
     526        if ( f->next ) goto *f->next;
     527        f->next = &&s1;
    703528        for ( ;; ) {
    704                 ret = f2;
    705 
    706                 fn = f1 + f2;  f2 = f1;  f1 = fn; `suspend();`
     529                for ( f->g = 0; f->g < 5; f->g += 1 ) {
     530                        for ( f->b = 0; f->b < 4; f->b += 1 ) {
     531                                return;
     532                          s1:;  while ( f->ch == '\n' ) return;
     533                                printf( "%c", f->ch );
     534                        } printf( " " );
     535                } printf( "\n" );
    707536        }
    708537}
    709 int next( Fib & fib ) with( fib ) {
    710         `resume( fib );`
    711         return ret;
    712 }
    713 
    714 
    715 
    716 
    717 
    718 
     538int main() {
     539        Fmt fmt = { NULL };  comain( &fmt ); // prime
     540        for ( ;; ) {
     541                scanf( "%c", &fmt.ch );
     542          if ( feof( stdin ) ) break;
     543                comain( &fmt );
     544        }
     545        if ( fmt.g != 0 || fmt.b != 0 ) printf( "\n" );
     546}
    719547\end{cfa}
    720548\end{lrbox}
    721 \subfloat[3 States, internal variables]{\label{f:Coroutine3States}\usebox\myboxA}
    722 \qquad\qquad
    723 \subfloat[1 State, internal variables]{\label{f:Coroutine1State}\usebox\myboxB}
    724 \caption{\CFA Coroutine Fibonacci Implementations}
    725 \label{f:fibonacci-cfa}
     549
     550\subfloat[\CFA asymmetric generator]{\label{f:CFAFormatGen}\usebox\myboxA}
     551\hspace{3pt}
     552\vrule
     553\hspace{3pt}
     554\subfloat[C generator simulation]{\label{f:CFormatSim}\usebox\myboxB}
     555\hspace{3pt}
     556\caption{Formatter (input) asymmetric generator}
     557\label{f:FormatterAsymmetricGenerator}
    726558\end{figure}
    727559
    728 Using a coroutine, it is possible to express the Fibonacci formula directly without any of the C problems.
    729 Figure~\ref{f:Coroutine3States} creates a @coroutine@ type:
    730 \begin{cfa}
    731 `coroutine` Fib { int fn; };
    732 \end{cfa}
    733 which provides communication, @fn@, for the \newterm{coroutine main}, @main@, which runs on the coroutine stack, and possibly multiple interface routines @next@.
    734 Like the structure in Figure~\ref{f:ExternalState}, the coroutine type allows multiple instances, where instances of this type are passed to the (overloaded) coroutine main.
    735 The coroutine main's stack holds the state for the next generation, @f1@ and @f2@, and the code has the three suspend points, representing the three states in the Fibonacci formula, to context switch back to the caller's resume.
    736 The interface routine @next@, takes a Fibonacci instance and context switches to it using @resume@;
    737 on restart, the Fibonacci field, @fn@, contains the next value in the sequence, which is returned.
    738 The first @resume@ is special because it cocalls the coroutine at its coroutine main and allocates the stack;
    739 when the coroutine main returns, its stack is deallocated.
    740 Hence, @Fib@ is an object at creation, transitions to a coroutine on its first resume, and transitions back to an object when the coroutine main finishes.
    741 Figure~\ref{f:Coroutine1State} shows the coroutine version of the C version in Figure~\ref{f:ExternalState}.
    742 Coroutine generators are called \newterm{output coroutines} because values are only returned.
    743 
    744 Figure~\ref{f:CFAFmt} shows an \newterm{input coroutine}, @Format@, for restructuring text into groups of characters of fixed-size blocks.
    745 For example, the input of the left is reformatted into the output on the right.
    746 \begin{quote}
     560Stateful functions appear as generators, coroutines, and threads, where presentations are based on function objects or pointers~\cite{Butenhof97, C++14, MS:VisualC++, BoostCoroutines15}.
     561For example, Python presents generators as a function object:
     562\begin{python}
     563def Gen():
     564        ... `yield val` ...
     565gen = Gen()
     566for i in range( 10 ):
     567        print( next( gen ) )
     568\end{python}
     569Boost presents coroutines in terms of four functor object-types:
     570\begin{cfa}
     571asymmetric_coroutine<>::pull_type
     572asymmetric_coroutine<>::push_type
     573symmetric_coroutine<>::call_type
     574symmetric_coroutine<>::yield_type
     575\end{cfa}
     576and many languages present threading using function pointers, @pthreads@~\cite{Butenhof97}, \Csharp~\cite{Csharp}, Go~\cite{Go}, and Scala~\cite{Scala}, \eg pthreads:
     577\begin{cfa}
     578void * rtn( void * arg ) { ... }
     579int i = 3, rc;
     580pthread_t t; $\C{// thread id}$
     581`rc = pthread_create( &t, rtn, (void *)i );` $\C{// create and initialized task, type-unsafe input parameter}$
     582\end{cfa}
     583% void mycor( pthread_t cid, void * arg ) {
     584%       int * value = (int *)arg;                               $\C{// type unsafe, pointer-size only}$
     585%       // thread body
     586% }
     587% int main() {
     588%       int input = 0, output;
     589%       coroutine_t cid = coroutine_create( &mycor, (void *)&input ); $\C{// type unsafe, pointer-size only}$
     590%       coroutine_resume( cid, (void *)input, (void **)&output ); $\C{// type unsafe, pointer-size only}$
     591% }
     592\CFA's preferred presentation model for generators/coroutines/threads is a hybrid of objects and functions, with an object-oriented flavour.
     593Essentially, the generator/coroutine/thread function is semantically coupled with a generator/coroutine/thread custom type.
     594The custom type solves several issues, while accessing the underlying mechanisms used by the custom types is still allowed.
     595
     596
     597\subsection{Generator}
     598
     599Stackless generators have the potential to be very small and fast, \ie as small and fast as function call/return for both creation and execution.
     600The \CFA goal is to achieve this performance target, possibly at the cost of some semantic complexity.
     601A series of different kinds of generators and their implementation demonstrate how this goal is accomplished.
     602
     603Figure~\ref{f:FibonacciAsymmetricGenerator} shows an unbounded asymmetric generator for an infinite sequence of Fibonacci numbers written in C and \CFA, with a simple C implementation for the \CFA version.
     604This generator is an \emph{output generator}, producing a new result on each resumption.
     605To compute Fibonacci, the previous two values in the sequence are retained to generate the next value, \ie @fn1@ and @fn@, plus the execution location where control restarts when the generator is resumed, \ie top or middle.
     606An additional requirement is the ability to create an arbitrary number of generators (of any kind), \ie retaining one state in global variables is insufficient;
     607hence, state is retained in a closure between calls.
     608Figure~\ref{f:CFibonacci} shows the C approach of manually creating the closure in structure @Fib@, and multiple instances of this closure provide multiple Fibonacci generators.
     609The C version only has the middle execution state because the top execution state is declaration initialization.
     610Figure~\ref{f:CFAFibonacciGen} shows the \CFA approach, which also has a manual closure, but replaces the structure with a custom \CFA @generator@ type.
     611This generator type is then connected to a function that \emph{must be named \lstinline|main|},\footnote{
     612The name \lstinline|main| has special meaning in C, specifically the function where a program starts execution.
     613Hence, overloading this name for other starting points (generator/coroutine/thread) is a logical extension.}
     614called a \emph{generator main},which takes as its only parameter a reference to the generator type.
     615The generator main contains @suspend@ statements that suspend execution without ending the generator versus @return@.
     616For the Fibonacci generator-main,\footnote{
     617The \CFA \lstinline|with| opens an aggregate scope making its fields directly accessible, like Pascal \lstinline|with|, but using parallel semantics.
     618Multiple aggregates may be opened.}
     619the top initialization state appears at the start and the middle execution state is denoted by statement @suspend@.
     620Any local variables in @main@ \emph{are not retained} between calls;
     621hence local variables are only for temporary computations \emph{between} suspends.
     622All retained state \emph{must} appear in the generator's type.
     623As well, generator code containing a @suspend@ cannot be refactored into a helper function called by the generator, because @suspend@ is implemented via @return@, so a return from the helper function goes back to the current generator not the resumer.
     624The generator is started by calling function @resume@ with a generator instance, which begins execution at the top of the generator main, and subsequent @resume@ calls restart the generator at its point of last suspension.
     625Resuming an ended (returned) generator is undefined.
     626Function @resume@ returns its argument generator so it can be cascaded in an expression, in this case to print the next Fibonacci value @fn@ computed in the generator instance.
     627Figure~\ref{f:CFibonacciSim} shows the C implementation of the \CFA generator only needs one additional field, @next@, to handle retention of execution state.
     628The computed @goto@ at the start of the generator main, which branches after the previous suspend, adds very little cost to the resume call.
     629Finally, an explicit generator type provides both design and performance benefits, such as multiple type-safe interface functions taking and returning arbitrary types.\footnote{
     630The \CFA operator syntax uses \lstinline|?| to denote operands, which allows precise definitions for pre, post, and infix operators, \eg \lstinline|++?|, \lstinline|?++|, and \lstinline|?+?|, in addition \lstinline|?\{\}| denotes a constructor, as in \lstinline|foo `f` = `\{`...`\}`|, \lstinline|^?\{\}| denotes a destructor, and \lstinline|?()| is \CC function call \lstinline|operator()|.
     631}%
     632\begin{cfa}
     633int ?()( Fib & fib ) { return `resume( fib )`.fn; } $\C[3.9in]{// function-call interface}$
     634int ?()( Fib & fib, int N ) { for ( N - 1 ) `fib()`; return `fib()`; } $\C{// use function-call interface to skip N values}$
     635double ?()( Fib & fib ) { return (int)`fib()` / 3.14159; } $\C{// different return type, cast prevents recursive call}\CRT$
     636sout | (int)f1() | (double)f1() | f2( 2 ); // alternative interface, cast selects call based on return type, step 2 values
     637\end{cfa}
     638Now, the generator can be a separately compiled opaque-type only accessed through its interface functions.
     639For contrast, Figure~\ref{f:PythonFibonacci} shows the equivalent Python Fibonacci generator, which does not use a generator type, and hence only has a single interface, but an implicit closure.
     640
     641Having to manually create the generator closure by moving local-state variables into the generator type is an additional programmer burden.
     642(This restriction is removed by the coroutine in Section~\ref{s:Coroutine}.)
     643This requirement follows from the generality of variable-size local-state, \eg local state with a variable-length array requires dynamic allocation because the array size is unknown at compile time.
     644However, dynamic allocation significantly increases the cost of generator creation/destruction and is a showstopper for embedded real-time programming.
     645But more importantly, the size of the generator type is tied to the local state in the generator main, which precludes separate compilation of the generator main, \ie a generator must be inlined or local state must be dynamically allocated.
     646With respect to safety, we believe static analysis can discriminate local state from temporary variables in a generator, \ie variable usage spanning @suspend@, and generate a compile-time error.
     647Finally, our current experience is that most generator problems have simple data state, including local state, but complex execution state, so the burden of creating the generator type is small.
     648As well, C programmers are not afraid of this kind of semantic programming requirement, if it results in very small, fast generators.
     649
     650Figure~\ref{f:CFAFormatGen} shows an asymmetric \newterm{input generator}, @Fmt@, for restructuring text into groups of characters of fixed-size blocks, \ie the input on the left is reformatted into the output on the right, where newlines are ignored.
     651\begin{center}
    747652\tt
    748653\begin{tabular}{@{}l|l@{}}
    749654\multicolumn{1}{c|}{\textbf{\textrm{input}}} & \multicolumn{1}{c}{\textbf{\textrm{output}}} \\
    750 abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
     655\begin{tabular}[t]{@{}ll@{}}
     656abcdefghijklmnopqrstuvwxyz \\
     657abcdefghijklmnopqrstuvwxyz
     658\end{tabular}
    751659&
    752660\begin{tabular}[t]{@{}lllll@{}}
     
    756664\end{tabular}
    757665\end{tabular}
    758 \end{quote}
    759 The example takes advantage of resuming a coroutine in the constructor to prime the loops so the first character sent for formatting appears inside the nested loops.
    760 The destruction provides a newline if formatted text ends with a full line.
    761 Figure~\ref{f:CFmt} shows the C equivalent formatter, where the loops of the coroutine are flatten (linearized) and rechecked on each call because execution location is not retained between calls.
     666\end{center}
     667The example takes advantage of resuming a generator in the constructor to prime the loops so the first character sent for formatting appears inside the nested loops.
     668The destructor provides a newline, if formatted text ends with a full line.
     669Figure~\ref{f:CFormatSim} shows the C implementation of the \CFA input generator with one additional field and the computed @goto@.
     670For contrast, Figure~\ref{f:PythonFormatter} shows the equivalent Python format generator with the same properties as the Fibonacci generator.
     671
     672Figure~\ref{f:DeviceDriverGen} shows a \emph{killer} asymmetric generator, a device-driver, because device drivers caused 70\%-85\% of failures in Windows/Linux~\cite{Swift05}.
     673Device drives follow the pattern of simple data state but complex execution state, \ie finite state-machine (FSM) parsing a protocol.
     674For example, the following protocol:
     675\begin{center}
     676\ldots\, STX \ldots\, message \ldots\, ESC ETX \ldots\, message \ldots\, ETX 2-byte crc \ldots
     677\end{center}
     678is a network message beginning with the control character STX, ending with an ETX, and followed by a 2-byte cyclic-redundancy check.
     679Control characters may appear in a message if preceded by an ESC.
     680When a message byte arrives, it triggers an interrupt, and the operating system services the interrupt by calling the device driver with the byte read from a hardware register.
     681The device driver returns a status code of its current state, and when a complete message is obtained, the operating system knows the message is in the message buffer.
     682Hence, the device driver is an input/output generator.
     683
     684Note, the cost of creating and resuming the device-driver generator, @Driver@, is virtually identical to call/return, so performance in an operating-system kernel is excellent.
     685As well, the data state is small, where variables @byte@ and @msg@ are communication variables for passing in message bytes and returning the message, and variables @lnth@, @crc@, and @sum@ are local variable that must be retained between calls and are manually hoisted into the generator type.
     686% Manually, detecting and hoisting local-state variables is easy when the number is small.
     687In contrast, the execution state is large, with one @resume@ and seven @suspend@s.
     688Hence, the key benefits of the generator are correctness, safety, and maintenance because the execution states are transcribed directly into the programming language rather than using a table-driven approach.
     689Because FSMs can be complex and frequently occur in important domains, direct generator support is important in a system programming language.
    762690
    763691\begin{figure}
     
    765693\newbox\myboxA
    766694\begin{lrbox}{\myboxA}
     695\begin{python}[aboveskip=0pt,belowskip=0pt]
     696def Fib():
     697        fn1, fn = 0, 1
     698        while True:
     699                `yield fn1`
     700                fn1, fn = fn, fn1 + fn
     701f1 = Fib()
     702f2 = Fib()
     703for i in range( 10 ):
     704        print( next( f1 ), next( f2 ) )
     705
     706
     707
     708
     709
     710
     711\end{python}
     712\end{lrbox}
     713
     714\newbox\myboxB
     715\begin{lrbox}{\myboxB}
     716\begin{python}[aboveskip=0pt,belowskip=0pt]
     717def Fmt():
     718        try:
     719                while True:
     720                        for g in range( 5 ):
     721                                for b in range( 4 ):
     722                                        print( `(yield)`, end='' )
     723                                print( '  ', end='' )
     724                        print()
     725        except GeneratorExit:
     726                if g != 0 | b != 0:
     727                        print()
     728fmt = Fmt()
     729`next( fmt )`                    # prime, next prewritten
     730for i in range( 41 ):
     731        `fmt.send( 'a' );`      # send to yield
     732\end{python}
     733\end{lrbox}
     734\subfloat[Fibonacci]{\label{f:PythonFibonacci}\usebox\myboxA}
     735\hspace{3pt}
     736\vrule
     737\hspace{3pt}
     738\subfloat[Formatter]{\label{f:PythonFormatter}\usebox\myboxB}
     739\caption{Python generator}
     740\label{f:PythonGenerator}
     741
     742\bigskip
     743
     744\begin{tabular}{@{}l|l@{}}
    767745\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    768 `coroutine` Format {
    769         char ch;   // used for communication
    770         int g, b;  // global because used in destructor
     746enum Status { CONT, MSG, ESTX,
     747                                ELNTH, ECRC };
     748`generator` Driver {
     749        Status status;
     750        unsigned char byte, * msg; // communication
     751        unsigned int lnth, sum;      // local state
     752        unsigned short int crc;
    771753};
    772 void main( Format & fmt ) with( fmt ) {
    773         for ( ;; ) {   
    774                 for ( g = 0; g < 5; g += 1 ) {      // group
    775                         for ( b = 0; b < 4; b += 1 ) { // block
    776                                 `suspend();`
    777                                 sout | ch;              // separator
     754void ?{}( Driver & d, char * m ) { d.msg = m; }
     755Status next( Driver & d, char b ) with( d ) {
     756        byte = b; `resume( d );` return status;
     757}
     758void main( Driver & d ) with( d ) {
     759        enum { STX = '\002', ESC = '\033',
     760                        ETX = '\003', MaxMsg = 64 };
     761  msg: for () { // parse message
     762                status = CONT;
     763                lnth = 0; sum = 0;
     764                while ( byte != STX ) `suspend;`
     765          emsg: for () {
     766                        `suspend;` // process byte
     767\end{cfa}
     768&
     769\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     770                        choose ( byte ) { // switch with implicit break
     771                          case STX:
     772                                status = ESTX; `suspend;` continue msg;
     773                          case ETX:
     774                                break emsg;
     775                          case ESC:
     776                                `suspend;`
    778777                        }
    779                         sout | "  ";               // separator
     778                        if ( lnth >= MaxMsg ) { // buffer full ?
     779                                status = ELNTH; `suspend;` continue msg; }
     780                        msg[lnth++] = byte;
     781                        sum += byte;
    780782                }
    781                 sout | endl;
     783                msg[lnth] = '\0'; // terminate string
     784                `suspend;`
     785                crc = byte << 8;
     786                `suspend;`
     787                status = (crc | byte) == sum ? MSG : ECRC;
     788                `suspend;`
    782789        }
    783790}
    784 void ?{}( Format & fmt ) { `resume( fmt );` }
    785 void ^?{}( Format & fmt ) with( fmt ) {
    786         if ( g != 0 || b != 0 ) sout | endl;
    787 }
    788 void format( Format & fmt ) {
    789         `resume( fmt );`
     791\end{cfa}
     792\end{tabular}
     793\caption{Device-driver generator for communication protocol}
     794\label{f:DeviceDriverGen}
     795\end{figure}
     796
     797Figure~\ref{f:CFAPingPongGen} shows a symmetric generator, where the generator resumes another generator, forming a resume/resume cycle.
     798(The trivial cycle is a generator resuming itself.)
     799This control flow is similar to recursion for functions but without stack growth.
     800The steps for symmetric control-flow are creating, executing, and terminating the cycle.
     801Constructing the cycle must deal with definition-before-use to close the cycle, \ie, the first generator must know about the last generator, which is not within scope.
     802(This issue occurs for any cyclic data structure.)
     803% The example creates all the generators and then assigns the partners that form the cycle.
     804% Alternatively, the constructor can assign the partners as they are declared, except the first, and the first-generator partner is set after the last generator declaration to close the cycle.
     805Once the cycle is formed, the program main resumes one of the generators, and the generators can then traverse an arbitrary cycle using @resume@ to activate partner generator(s).
     806Terminating the cycle is accomplished by @suspend@ or @return@, both of which go back to the stack frame that started the cycle (program main in the example).
     807The starting stack-frame is below the last active generator because the resume/resume cycle does not grow the stack.
     808Also, since local variables are not retained in the generator function, it does not contain any objects with destructors that must be called, so the  cost is the same as a function return.
     809Destructor cost occurs when the generator instance is deallocated, which is easily controlled by the programmer.
     810
     811Figure~\ref{f:CPingPongSim} shows the implementation of the symmetric generator, where the complexity is the @resume@, which needs an extension to the calling convention to perform a forward rather than backward jump.
     812This jump-starts at the top of the next generator main to re-execute the normal calling convention to make space on the stack for its local variables.
     813However, before the jump, the caller must reset its stack (and any registers) equivalent to a @return@, but subsequently jump forward.
     814This semantics is basically a tail-call optimization, which compilers already perform.
     815The example shows the assembly code to undo the generator's entry code before the direct jump.
     816This assembly code depends on what entry code is generated, specifically if there are local variables and the level of optimization.
     817To provide this new calling convention requires a mechanism built into the compiler, which is beyond the scope of \CFA at this time.
     818Nevertheless, it is possible to hand generate any symmetric generators for proof of concept and performance testing.
     819A compiler could also eliminate other artifacts in the generator simulation to further increase performance, \eg LLVM has various coroutine support~\cite{CoroutineTS}, and \CFA can leverage this support should it fork @clang@.
     820
     821\begin{figure}
     822\centering
     823\begin{lrbox}{\myboxA}
     824\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     825`generator PingPong` {
     826        const char * name;
     827        int N;
     828        int i;                          // local state
     829        PingPong & partner; // rebindable reference
     830};
     831
     832void `main( PingPong & pp )` with(pp) {
     833        for ( ; i < N; i += 1 ) {
     834                sout | name | i;
     835                `resume( partner );`
     836        }
    790837}
    791838int main() {
    792         Format fmt;
    793         eof: for ( ;; ) {
    794                 sin | fmt.ch;
    795           if ( eof( sin ) ) break eof;
    796                 format( fmt );
     839        enum { N = 5 };
     840        PingPong ping = {"ping",N,0}, pong = {"pong",N,0};
     841        &ping.partner = &pong;  &pong.partner = &ping;
     842        `resume( ping );`
     843}
     844\end{cfa}
     845\end{lrbox}
     846
     847\begin{lrbox}{\myboxB}
     848\begin{cfa}[escapechar={},aboveskip=0pt,belowskip=0pt]
     849typedef struct PingPong {
     850        const char * name;
     851        int N, i;
     852        struct PingPong * partner;
     853        void * next;
     854} PingPong;
     855#define PPCtor(name, N) {name,N,0,NULL,NULL}
     856void comain( PingPong * pp ) {
     857        if ( pp->next ) goto *pp->next;
     858        pp->next = &&cycle;
     859        for ( ; pp->i < pp->N; pp->i += 1 ) {
     860                printf( "%s %d\n", pp->name, pp->i );
     861                asm( "mov  %0,%%rdi" : "=m" (pp->partner) );
     862                asm( "mov  %rdi,%rax" );
     863                asm( "popq %rbx" );
     864                asm( "jmp  comain" );
     865          cycle: ;
     866        }
     867}
     868\end{cfa}
     869\end{lrbox}
     870
     871\subfloat[\CFA symmetric generator]{\label{f:CFAPingPongGen}\usebox\myboxA}
     872\hspace{3pt}
     873\vrule
     874\hspace{3pt}
     875\subfloat[C generator simulation]{\label{f:CPingPongSim}\usebox\myboxB}
     876\hspace{3pt}
     877\caption{Ping-Pong symmetric generator}
     878\label{f:PingPongSymmetricGenerator}
     879\end{figure}
     880
     881Finally, part of this generator work was inspired by the recent \CCtwenty generator proposal~\cite{C++20Coroutine19} (which they call coroutines).
     882Our work provides the same high-performance asymmetric generators as \CCtwenty, and extends their work with symmetric generators.
     883An additional \CCtwenty generator feature allows @suspend@ and @resume@ to be followed by a restricted compound statement that is executed after the current generator has reset its stack but before calling the next generator, specified with \CFA syntax:
     884\begin{cfa}
     885... suspend`{ ... }`;
     886... resume( C )`{ ... }` ...
     887\end{cfa}
     888Since the current generator's stack is released before calling the compound statement, the compound statement can only reference variables in the generator's type.
     889This feature is useful when a generator is used in a concurrent context to ensure it is stopped before releasing a lock in the compound statement, which might immediately allow another thread to resume the generator.
     890Hence, this mechanism provides a general and safe handoff of the generator among competing threads.
     891
     892
     893\subsection{Coroutine}
     894\label{s:Coroutine}
     895
     896Stackful coroutines extend generator semantics, \ie there is an implicit closure and @suspend@ may appear in a helper function called from the coroutine main.
     897A coroutine is specified by replacing @generator@ with @coroutine@ for the type.
     898Coroutine generality results in higher cost for creation, due to dynamic stack allocation, execution, due to context switching among stacks, and terminating, due to possible stack unwinding and dynamic stack deallocation.
     899A series of different kinds of coroutines and their implementations demonstrate how coroutines extend generators.
     900
     901First, the previous generator examples are converted to their coroutine counterparts, allowing local-state variables to be moved from the generator type into the coroutine main.
     902\begin{description}
     903\item[Fibonacci]
     904Move the declaration of @fn1@ to the start of coroutine main.
     905\begin{cfa}[xleftmargin=0pt]
     906void main( Fib & fib ) with(fib) {
     907        `int fn1;`
     908\end{cfa}
     909\item[Formatter]
     910Move the declaration of @g@ and @b@ to the for loops in the coroutine main.
     911\begin{cfa}[xleftmargin=0pt]
     912for ( `g`; 5 ) {
     913        for ( `b`; 4 ) {
     914\end{cfa}
     915\item[Device Driver]
     916Move the declaration of @lnth@ and @sum@ to their points of initialization.
     917\begin{cfa}[xleftmargin=0pt]
     918        status = CONT;
     919        `unsigned int lnth = 0, sum = 0;`
     920        ...
     921        `unsigned short int crc = byte << 8;`
     922\end{cfa}
     923\item[PingPong]
     924Move the declaration of @i@ to the for loop in the coroutine main.
     925\begin{cfa}[xleftmargin=0pt]
     926void main( PingPong & pp ) with(pp) {
     927        for ( `i`; N ) {
     928\end{cfa}
     929\end{description}
     930It is also possible to refactor code containing local-state and @suspend@ statements into a helper function, like the computation of the CRC for the device driver.
     931\begin{cfa}
     932unsigned int Crc() {
     933        `suspend;`
     934        unsigned short int crc = byte << 8;
     935        `suspend;`
     936        status = (crc | byte) == sum ? MSG : ECRC;
     937        return crc;
     938}
     939\end{cfa}
     940A call to this function is placed at the end of the driver's coroutine-main.
     941For complex finite-state machines, refactoring is part of normal program abstraction, especially when code is used in multiple places.
     942Again, this complexity is usually associated with execution state rather than data state.
     943
     944\begin{comment}
     945Figure~\ref{f:Coroutine3States} creates a @coroutine@ type, @`coroutine` Fib { int fn; }@, which provides communication, @fn@, for the \newterm{coroutine main}, @main@, which runs on the coroutine stack, and possibly multiple interface functions, \eg @next@.
     946Like the structure in Figure~\ref{f:ExternalState}, the coroutine type allows multiple instances, where instances of this type are passed to the (overloaded) coroutine main.
     947The coroutine main's stack holds the state for the next generation, @f1@ and @f2@, and the code represents the three states in the Fibonacci formula via the three suspend points, to context switch back to the caller's @resume@.
     948The interface function @next@, takes a Fibonacci instance and context switches to it using @resume@;
     949on restart, the Fibonacci field, @fn@, contains the next value in the sequence, which is returned.
     950The first @resume@ is special because it allocates the coroutine stack and cocalls its coroutine main on that stack;
     951when the coroutine main returns, its stack is deallocated.
     952Hence, @Fib@ is an object at creation, transitions to a coroutine on its first resume, and transitions back to an object when the coroutine main finishes.
     953Figure~\ref{f:Coroutine1State} shows the coroutine version of the C version in Figure~\ref{f:ExternalState}.
     954Coroutine generators are called \newterm{output coroutines} because values are only returned.
     955
     956\begin{figure}
     957\centering
     958\newbox\myboxA
     959% \begin{lrbox}{\myboxA}
     960% \begin{cfa}[aboveskip=0pt,belowskip=0pt]
     961% `int fn1, fn2, state = 1;`   // single global variables
     962% int fib() {
     963%       int fn;
     964%       `switch ( state )` {  // explicit execution state
     965%         case 1: fn = 0;  fn1 = fn;  state = 2;  break;
     966%         case 2: fn = 1;  fn2 = fn1;  fn1 = fn;  state = 3;  break;
     967%         case 3: fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn;  break;
     968%       }
     969%       return fn;
     970% }
     971% int main() {
     972%
     973%       for ( int i = 0; i < 10; i += 1 ) {
     974%               printf( "%d\n", fib() );
     975%       }
     976% }
     977% \end{cfa}
     978% \end{lrbox}
     979\begin{lrbox}{\myboxA}
     980\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     981#define FibCtor { 0, 1 }
     982typedef struct { int fn1, fn; } Fib;
     983int fib( Fib * f ) {
     984
     985        int ret = f->fn1;
     986        f->fn1 = f->fn;
     987        f->fn = ret + f->fn;
     988        return ret;
     989}
     990
     991
     992
     993int main() {
     994        Fib f1 = FibCtor, f2 = FibCtor;
     995        for ( int i = 0; i < 10; i += 1 ) {
     996                printf( "%d %d\n",
     997                                fib( &f1 ), fib( &f2 ) );
    797998        }
    798999}
     
    8031004\begin{lrbox}{\myboxB}
    8041005\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    805 struct Format {
    806         char ch;
    807         int g, b;
    808 };
    809 void format( struct Format * fmt ) {
    810         if ( fmt->ch != -1 ) {      // not EOF ?
    811                 printf( "%c", fmt->ch );
    812                 fmt->b += 1;
    813                 if ( fmt->b == 4 ) {  // block
    814                         printf( "  " );      // separator
    815                         fmt->b = 0;
    816                         fmt->g += 1;
    817                 }
    818                 if ( fmt->g == 5 ) {  // group
    819                         printf( "\n" );     // separator
    820                         fmt->g = 0;
    821                 }
    822         } else {
    823                 if ( fmt->g != 0 || fmt->b != 0 ) printf( "\n" );
     1006`coroutine` Fib { int fn1; };
     1007void main( Fib & fib ) with( fib ) {
     1008        int fn;
     1009        [fn1, fn] = [0, 1];
     1010        for () {
     1011                `suspend;`
     1012                [fn1, fn] = [fn, fn1 + fn];
    8241013        }
    8251014}
     1015int ?()( Fib & fib ) with( fib ) {
     1016        return `resume( fib )`.fn1;
     1017}
    8261018int main() {
    827         struct Format fmt = { 0, 0, 0 };
    828         for ( ;; ) {
    829                 scanf( "%c", &fmt.ch );
    830           if ( feof( stdin ) ) break;
    831                 format( &fmt );
    832         }
    833         fmt.ch = -1;
    834         format( &fmt );
    835 }
     1019        Fib f1, f2;
     1020        for ( 10 ) {
     1021                sout | f1() | f2();
     1022}
     1023
     1024
    8361025\end{cfa}
    8371026\end{lrbox}
    838 \subfloat[\CFA Coroutine]{\label{f:CFAFmt}\usebox\myboxA}
     1027
     1028\newbox\myboxC
     1029\begin{lrbox}{\myboxC}
     1030\begin{python}[aboveskip=0pt,belowskip=0pt]
     1031
     1032def Fib():
     1033
     1034        fn1, fn = 0, 1
     1035        while True:
     1036                `yield fn1`
     1037                fn1, fn = fn, fn1 + fn
     1038
     1039
     1040// next prewritten
     1041
     1042
     1043f1 = Fib()
     1044f2 = Fib()
     1045for i in range( 10 ):
     1046        print( next( f1 ), next( f2 ) )
     1047
     1048
     1049
     1050\end{python}
     1051\end{lrbox}
     1052
     1053\subfloat[C]{\label{f:GlobalVariables}\usebox\myboxA}
     1054\hspace{3pt}
     1055\vrule
     1056\hspace{3pt}
     1057\subfloat[\CFA]{\label{f:ExternalState}\usebox\myboxB}
     1058\hspace{3pt}
     1059\vrule
     1060\hspace{3pt}
     1061\subfloat[Python]{\label{f:ExternalState}\usebox\myboxC}
     1062\caption{Fibonacci generator}
     1063\label{f:C-fibonacci}
     1064\end{figure}
     1065
     1066\bigskip
     1067
     1068\newbox\myboxA
     1069\begin{lrbox}{\myboxA}
     1070\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     1071`coroutine` Fib { int fn; };
     1072void main( Fib & fib ) with( fib ) {
     1073        fn = 0;  int fn1 = fn; `suspend`;
     1074        fn = 1;  int fn2 = fn1;  fn1 = fn; `suspend`;
     1075        for () {
     1076                fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `suspend`; }
     1077}
     1078int next( Fib & fib ) with( fib ) { `resume( fib );` return fn; }
     1079int main() {
     1080        Fib f1, f2;
     1081        for ( 10 )
     1082                sout | next( f1 ) | next( f2 );
     1083}
     1084\end{cfa}
     1085\end{lrbox}
     1086\newbox\myboxB
     1087\begin{lrbox}{\myboxB}
     1088\begin{python}[aboveskip=0pt,belowskip=0pt]
     1089
     1090def Fibonacci():
     1091        fn = 0; fn1 = fn; `yield fn`  # suspend
     1092        fn = 1; fn2 = fn1; fn1 = fn; `yield fn`
     1093        while True:
     1094                fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `yield fn`
     1095
     1096
     1097f1 = Fibonacci()
     1098f2 = Fibonacci()
     1099for i in range( 10 ):
     1100        print( `next( f1 )`, `next( f2 )` ) # resume
     1101
     1102\end{python}
     1103\end{lrbox}
     1104\subfloat[\CFA]{\label{f:Coroutine3States}\usebox\myboxA}
    8391105\qquad
    840 \subfloat[C Linearized]{\label{f:CFmt}\usebox\myboxB}
    841 \caption{Formatting text into lines of 5 blocks of 4 characters.}
    842 \label{f:fmt-line}
     1106\subfloat[Python]{\label{f:Coroutine1State}\usebox\myboxB}
     1107\caption{Fibonacci input coroutine, 3 states, internal variables}
     1108\label{f:cfa-fibonacci}
    8431109\end{figure}
    844 
    845 The previous examples are \newterm{asymmetric (semi) coroutine}s because one coroutine always calls a resuming routine for another coroutine, and the resumed coroutine always suspends back to its last resumer, similar to call/return for normal routines
    846 However, there is no stack growth because @resume@/@suspend@ context switch to existing stack-frames rather than create new ones.
    847 \newterm{Symmetric (full) coroutine}s have a coroutine call a resuming routine for another coroutine, which eventually forms a resuming-call cycle.
    848 (The trivial cycle is a coroutine resuming itself.)
    849 This control flow is similar to recursion for normal routines, but again there is no stack growth from the context switch.
     1110\end{comment}
    8501111
    8511112\begin{figure}
     
    8551116\begin{cfa}
    8561117`coroutine` Prod {
    857         Cons & c;
     1118        Cons & c;                       // communication
    8581119        int N, money, receipt;
    8591120};
    8601121void main( Prod & prod ) with( prod ) {
    8611122        // 1st resume starts here
    862         for ( int i = 0; i < N; i += 1 ) {
     1123        for ( i; N ) {
    8631124                int p1 = random( 100 ), p2 = random( 100 );
    864                 sout | p1 | " " | p2 | endl;
     1125                sout | p1 | " " | p2;
    8651126                int status = delivery( c, p1, p2 );
    866                 sout | " $" | money | endl | status | endl;
     1127                sout | " $" | money | nl | status;
    8671128                receipt += 1;
    8681129        }
    8691130        stop( c );
    870         sout | "prod stops" | endl;
     1131        sout | "prod stops";
    8711132}
    8721133int payment( Prod & prod, int money ) {
     
    8891150\begin{cfa}
    8901151`coroutine` Cons {
    891         Prod & p;
     1152        Prod & p;                       // communication
    8921153        int p1, p2, status;
    893         _Bool done;
     1154        bool done;
    8941155};
    8951156void ?{}( Cons & cons, Prod & p ) {
    896         &cons.p = &p;
     1157        &cons.p = &p; // reassignable reference
    8971158        cons.[status, done ] = [0, false];
    8981159}
    899 void ^?{}( Cons & cons ) {}
    9001160void main( Cons & cons ) with( cons ) {
    9011161        // 1st resume starts here
    9021162        int money = 1, receipt;
    9031163        for ( ; ! done; ) {
    904                 sout | p1 | " " | p2 | endl | " $" | money | endl;
     1164                sout | p1 | " " | p2 | nl | " $" | money;
    9051165                status += 1;
    9061166                receipt = payment( p, money );
    907                 sout | " #" | receipt | endl;
     1167                sout | " #" | receipt;
    9081168                money += 1;
    9091169        }
    910         sout | "cons stops" | endl;
     1170        sout | "cons stops";
    9111171}
    9121172int delivery( Cons & cons, int p1, int p2 ) {
     
    9191179        `resume( cons );`
    9201180}
     1181
    9211182\end{cfa}
    9221183\end{tabular}
    923 \caption{Producer / consumer: resume-resume cycle, bi-directional communication}
     1184\caption{Producer / consumer: resume-resume cycle, bidirectional communication}
    9241185\label{f:ProdCons}
    9251186\end{figure}
    9261187
    927 Figure~\ref{f:ProdCons} shows a producer/consumer symmetric-coroutine performing bi-directional communication.
    928 Since the solution involves a full-coroutining cycle, the program main creates one coroutine in isolation, passes this coroutine to its partner, and closes the cycle at the call to @start@.
    929 The @start@ routine communicates both the number of elements to be produced and the consumer into the producer's coroutine structure.
    930 Then the @resume@ to @prod@ creates @prod@'s stack with a frame for @prod@'s coroutine main at the top, and context switches to it.
    931 @prod@'s coroutine main starts, creates local variables that are retained between coroutine activations, and executes $N$ iterations, each generating two random values, calling the consumer to deliver the values, and printing the status returned from the consumer.
     1188Figure~\ref{f:ProdCons} shows the ping-pong example in Figure~\ref{f:CFAPingPongGen} extended into a producer/consumer symmetric-coroutine performing bidirectional communication.
     1189This example is illustrative because both producer/consumer have two interface functions with @resume@s that suspend execution in these interface (helper) functions.
     1190The program main creates the producer coroutine, passes it to the consumer coroutine in its initialization, and closes the cycle at the call to @start@ along with the number of items to be produced.
     1191The first @resume@ of @prod@ creates @prod@'s stack with a frame for @prod@'s coroutine main at the top, and context switches to it.
     1192@prod@'s coroutine main starts, creates local-state variables that are retained between coroutine activations, and executes $N$ iterations, each generating two random values, calling the consumer to deliver the values, and printing the status returned from the consumer.
    9321193
    9331194The producer call to @delivery@ transfers values into the consumer's communication variables, resumes the consumer, and returns the consumer status.
    934 For the first resume, @cons@'s stack is initialized, creating local variables retained between subsequent activations of the coroutine.
    935 The consumer iterates until the @done@ flag is set, prints, increments status, and calls back to the producer via @payment@, and on return from @payment@, prints the receipt from the producer and increments @money@ (inflation).
    936 The call from the consumer to the @payment@ introduces the cycle between producer and consumer.
     1195On the first resume, @cons@'s stack is created and initialized, holding local-state variables retained between subsequent activations of the coroutine.
     1196The consumer iterates until the @done@ flag is set, prints the values delivered by the producer, increments status, and calls back to the producer via @payment@, and on return from @payment@, prints the receipt from the producer and increments @money@ (inflation).
     1197The call from the consumer to @payment@ introduces the cycle between producer and consumer.
    9371198When @payment@ is called, the consumer copies values into the producer's communication variable and a resume is executed.
    938 The context switch restarts the producer at the point where it was last context switched, so it continues in @delivery@ after the resume.
    939 
     1199The context switch restarts the producer at the point where it last context switched, so it continues in @delivery@ after the resume.
    9401200@delivery@ returns the status value in @prod@'s coroutine main, where the status is printed.
    9411201The loop then repeats calling @delivery@, where each call resumes the consumer coroutine.
     
    9431203The consumer increments and returns the receipt to the call in @cons@'s coroutine main.
    9441204The loop then repeats calling @payment@, where each call resumes the producer coroutine.
    945 
    946 After iterating $N$ times, the producer calls @stop@.
    947 The @done@ flag is set to stop the consumer's execution and a resume is executed.
    948 The context switch restarts @cons@ in @payment@ and it returns with the last receipt.
    949 The consumer terminates its loops because @done@ is true, its @main@ terminates, so @cons@ transitions from a coroutine back to an object, and @prod@ reactivates after the resume in @stop@.
    950 @stop@ returns and @prod@'s coroutine main terminates.
    951 The program main restarts after the resume in @start@.
    952 @start@ returns and the program main terminates.
    953 
    954 
    955 \subsection{Coroutine Implementation}
    956 
    957 A significant implementation challenge for coroutines (and threads, see section \ref{threads}) is adding extra fields and executing code after/before the coroutine constructor/destructor and coroutine main to create/initialize/de-initialize/destroy extra fields and the stack.
    958 There are several solutions to this problem and the chosen option forced the \CFA coroutine design.
    959 
    960 Object-oriented inheritance provides extra fields and code in a restricted context, but it requires programmers to explicitly perform the inheritance:
    961 \begin{cfa}
    962 struct mycoroutine $\textbf{\textsf{inherits}}$ baseCoroutine { ... }
    963 \end{cfa}
    964 and the programming language (and possibly its tool set, \eg debugger) may need to understand @baseCoroutine@ because of the stack.
    965 Furthermore, the execution of constructs/destructors is in the wrong order for certain operations, \eg for threads;
    966 \eg, if the thread is implicitly started, it must start \emph{after} all constructors, because the thread relies on a completely initialized object, but the inherited constructor runs \emph{before} the derived.
    967 
    968 An alternatively is composition:
    969 \begin{cfa}
    970 struct mycoroutine {
    971         ... // declarations
     1205Figure~\ref{f:ProdConsRuntimeStacks} shows the runtime stacks of the program main, and the coroutine mains for @prod@ and @cons@ during the cycling.
     1206
     1207\begin{figure}
     1208\begin{center}
     1209\input{FullProdConsStack.pstex_t}
     1210\end{center}
     1211\vspace*{-10pt}
     1212\caption{Producer / consumer runtime stacks}
     1213\label{f:ProdConsRuntimeStacks}
     1214
     1215\medskip
     1216
     1217\begin{center}
     1218\input{FullCoroutinePhases.pstex_t}
     1219\end{center}
     1220\vspace*{-10pt}
     1221\caption{Ping / Pong coroutine steps}
     1222\label{f:PingPongFullCoroutineSteps}
     1223\end{figure}
     1224
     1225Terminating a coroutine cycle is more complex than a generator cycle, because it requires context switching to the program main's \emph{stack} to shutdown the program, whereas generators started by the program main run on its stack.
     1226Furthermore, each deallocated coroutine must guarantee all destructors are run for object allocated in the coroutine type \emph{and} allocated on the coroutine's stack at the point of suspension, which can be arbitrarily deep.
     1227When a coroutine's main ends, its stack is already unwound so any stack allocated objects with destructors have been finalized.
     1228The na\"{i}ve semantics for coroutine-cycle termination is to context switch to the last resumer, like executing a @suspend@/@return@ in a generator.
     1229However, for coroutines, the last resumer is \emph{not} implicitly below the current stack frame, as for generators, because each coroutine's stack is independent.
     1230Unfortunately, it is impossible to determine statically if a coroutine is in a cycle and unrealistic to check dynamically (graph-cycle problem).
     1231Hence, a compromise solution is necessary that works for asymmetric (acyclic) and symmetric (cyclic) coroutines.
     1232
     1233Our solution is to context switch back to the first resumer (starter) once the coroutine ends.
     1234This semantics works well for the most common asymmetric and symmetric coroutine usage patterns.
     1235For asymmetric coroutines, it is common for the first resumer (starter) coroutine to be the only resumer.
     1236All previous generators converted to coroutines have this property.
     1237For symmetric coroutines, it is common for the cycle creator to persist for the lifetime of the cycle.
     1238Hence, the starter coroutine is remembered on the first resume and ending the coroutine resumes the starter.
     1239Figure~\ref{f:ProdConsRuntimeStacks} shows this semantic by the dashed lines from the end of the coroutine mains: @prod@ starts @cons@ so @cons@ resumes @prod@ at the end, and the program main starts @prod@ so @prod@ resumes the program main at the end.
     1240For other scenarios, it is always possible to devise a solution with additional programming effort, such as forcing the cycle forward (backward) to a safe point before starting termination.
     1241
     1242The producer/consumer example does not illustrate the full power of the starter semantics because @cons@ always ends first.
     1243Assume generator @PingPong@ is converted to a coroutine.
     1244Figure~\ref{f:PingPongFullCoroutineSteps} shows the creation, starter, and cyclic execution steps of the coroutine version.
     1245The program main creates (declares) coroutine instances @ping@ and @pong@.
     1246Next, program main resumes @ping@, making it @ping@'s starter, and @ping@'s main resumes @pong@'s main, making it @pong@'s starter.
     1247Execution forms a cycle when @pong@ resumes @ping@, and cycles $N$ times.
     1248By adjusting $N$ for either @ping@/@pong@, it is possible to have either one finish first, instead of @pong@ always ending first.
     1249If @pong@ ends first, it resumes its starter @ping@ in its coroutine main, then @ping@ ends and resumes its starter the program main in function @start@.
     1250If @ping@ ends first, it resumes its starter the program main in function @start@.
     1251Regardless of the cycle complexity, the starter stack always leads back to the program main, but the stack can be entered at an arbitrary point.
     1252Once back at the program main, coroutines @ping@ and @pong@ are deallocated.
     1253For generators, deallocation runs the destructors for all objects in the generator type.
     1254For coroutines, deallocation deals with objects in the coroutine type and must also run the destructors for any objects pending on the coroutine's stack for any unterminated coroutine.
     1255Hence, if a coroutine's destructor detects the coroutine is not ended, it implicitly raises a cancellation exception (uncatchable exception) at the coroutine and resumes it so the cancellation exception can propagate to the root of the coroutine's stack destroying all local variable on the stack.
     1256So the \CFA semantics for the generator and coroutine, ensure both can be safely deallocated at any time, regardless of their current state, like any other aggregate object.
     1257Explicitly raising normal exceptions at another coroutine can replace flag variables, like @stop@, \eg @prod@ raises a @stop@ exception at @cons@ after it finishes generating values and resumes @cons@, which catches the @stop@ exception to terminate its loop.
     1258
     1259Finally, there is an interesting effect for @suspend@ with symmetric coroutines.
     1260A coroutine must retain its last resumer to suspend back because the resumer is on a different stack.
     1261These reverse pointers allow @suspend@ to cycle \emph{backwards}, which may be useful in certain cases.
     1262However, there is an anomaly if a coroutine resumes itself, because it overwrites its last resumer with itself, losing the ability to resume the last external resumer.
     1263To prevent losing this information, a self-resume does not overwrite the last resumer.
     1264
     1265
     1266\subsection{Generator / Coroutine Implementation}
     1267
     1268A significant implementation challenge for generators/coroutines (and threads in Section~\ref{s:threads}) is adding extra fields to the custom types and related functions, \eg inserting code after/before the coroutine constructor/destructor and @main@ to create/initialize/de-initialize/destroy any extra fields, \eg stack.
     1269There are several solutions to these problem, which follow from the object-oriented flavour of adopting custom types.
     1270
     1271For object-oriented languages, inheritance is used to provide extra fields and code via explicit inheritance:
     1272\begin{cfa}[morekeywords={class,inherits}]
     1273class myCoroutine inherits baseCoroutine { ... }
     1274\end{cfa}
     1275% The problem is that the programming language and its tool chain, \eg debugger, @valgrind@, need to understand @baseCoroutine@ because it infers special property, so type @baseCoroutine@ becomes a de facto keyword and all types inheriting from it are implicitly custom types.
     1276The problem is that some special properties are not handled by existing language semantics, \eg the execution of constructors/destructors is in the wrong order to implicitly start threads because the thread must start \emph{after} all constructors as it relies on a completely initialized object, but the inherited constructor runs \emph{before} the derived.
     1277Alternatives, such as explicitly starting threads as in Java, are repetitive and forgetting to call start is a common source of errors.
     1278An alternative is composition:
     1279\begin{cfa}
     1280struct myCoroutine {
     1281        ... // declaration/communication variables
    9721282        baseCoroutine dummy; // composition, last declaration
    9731283}
    9741284\end{cfa}
    975 which also requires an explicit declaration that must be the last one to ensure correct initialization order.
     1285which also requires an explicit declaration that must be last to ensure correct initialization order.
    9761286However, there is nothing preventing wrong placement or multiple declarations.
    9771287
    978 For coroutines as for threads, many implementations are based on routine pointers or routine objects~\cite{Butenhof97, C++14, MS:VisualC++, BoostCoroutines15}.
    979 For example, Boost implements coroutines in terms of four functor object-types:
    980 \begin{cfa}
    981 asymmetric_coroutine<>::pull_type
    982 asymmetric_coroutine<>::push_type
    983 symmetric_coroutine<>::call_type
    984 symmetric_coroutine<>::yield_type
    985 \end{cfa}
    986 Similarly, the canonical threading paradigm is often based on routine pointers, \eg @pthread@~\cite{pthreads}, \Csharp~\cite{Csharp}, Go~\cite{Go}, and Scala~\cite{Scala}.
    987 However, the generic thread-handle (identifier) is limited (few operations), unless it is wrapped in a custom type.
    988 \begin{cfa}
    989 void mycor( coroutine_t cid, void * arg ) {
    990         int * value = (int *)arg;                               $\C{// type unsafe, pointer-size only}$
    991         // Coroutine body
    992 }
    993 int main() {
    994         int input = 0, output;
    995         coroutine_t cid = coroutine_create( &mycor, (void *)&input ); $\C{// type unsafe, pointer-size only}$
    996         coroutine_resume( cid, (void *)input, (void **)&output ); $\C{// type unsafe, pointer-size only}$
    997 }
    998 \end{cfa}
    999 Since the custom type is simple to write in \CFA and solves several issues, added support for routine/lambda-based coroutines adds very little.
    1000 
    1001 Note, the type @coroutine_t@ must be an abstract handle to the coroutine, because the coroutine descriptor and its stack are non-copyable.
    1002 Copying the coroutine descriptor results in copies being out of date with the current state of the stack.
    1003 Correspondingly, copying the stack results is copies being out of date with coroutine descriptor, and pointers in the stack being out of date to data on the stack.
    1004 (There is no mechanism in C to find all stack-specific pointers and update them as part of a copy.)
    1005 
    1006 The selected approach is to use language support by introducing a new kind of aggregate (structure):
    1007 \begin{cfa}
    1008 coroutine Fibonacci {
    1009         int fn; // communication variables
    1010 };
    1011 \end{cfa}
    1012 The @coroutine@ keyword means the compiler (and tool set) can find and inject code where needed.
    1013 The downside of this approach is that it makes coroutine a special case in the language.
    1014 Users wanting to extend coroutines or build their own for various reasons can only do so in ways offered by the language.
    1015 Furthermore, implementing coroutines without language supports also displays the power of a programming language.
    1016 While this is ultimately the option used for idiomatic \CFA code, coroutines and threads can still be constructed without using the language support.
    1017 The reserved keyword eases use for the common cases.
    1018 
    1019 Part of the mechanism to generalize coroutines is using a \CFA trait, which defines a coroutine as anything satisfying the trait @is_coroutine@, and this trait is used to restrict coroutine-manipulation routines:
     1288\CFA custom types make any special properties explicit to the language and its tool chain, \eg the language code-generator knows where to inject code
     1289% and when it is unsafe to perform certain optimizations,
     1290and IDEs using simple parsing can find and manipulate types with special properties.
     1291The downside of this approach is that it makes custom types a special case in the language.
     1292Users wanting to extend custom types or build their own can only do so in ways offered by the language.
     1293Furthermore, implementing custom types without language support may display the power of a programming language.
     1294\CFA blends the two approaches, providing custom type for idiomatic \CFA code, while extending and building new custom types is still possible, similar to Java concurrency with builtin and library.
     1295
     1296Part of the mechanism to generalize custom types is the \CFA trait~\cite[\S~2.3]{Moss18}, \eg the definition for custom-type @coroutine@ is anything satisfying the trait @is_coroutine@, and this trait both enforces and restricts the coroutine-interface functions.
    10201297\begin{cfa}
    10211298trait is_coroutine( `dtype` T ) {
     
    10231300        coroutine_desc * get_coroutine( T & );
    10241301};
    1025 forall( `dtype` T | is_coroutine(T) ) void suspend( T & );
    1026 forall( `dtype` T | is_coroutine(T) ) void resume( T & );
    1027 \end{cfa}
    1028 The @dtype@ property of the trait ensures the coroutine descriptor is non-copyable, so all coroutines must be passed by reference (pointer).
    1029 The routine definitions ensures there is a statically-typed @main@ routine that is the starting point (first stack frame) of a coroutine, and a mechanism to get (read) the currently executing coroutine handle.
    1030 The @main@ routine has no return value or additional parameters because the coroutine type allows an arbitrary number of interface routines with corresponding arbitrary typed input/output values versus fixed ones.
    1031 The generic routines @suspend@ and @resume@ can be redefined, but any object passed to them is a coroutine since it must satisfy the @is_coroutine@ trait to compile.
    1032 The advantage of this approach is that users can easily create different types of coroutines, for example, changing the memory layout of a coroutine is trivial when implementing the @get_coroutine@ routine, and possibly redefining @suspend@ and @resume@.
    1033 The \CFA keyword @coroutine@ implicitly implements the getter and forward declarations required for implementing the coroutine main:
     1302forall( `dtype` T | is_coroutine(T) ) void $suspend$( T & ), resume( T & );
     1303\end{cfa}
     1304Note, copying generators/coroutines/threads is not meaningful.
     1305For example, both the resumer and suspender descriptors can have bidirectional pointers;
     1306copying these coroutines does not update the internal pointers so behaviour of both copies would be difficult to understand.
     1307Furthermore, two coroutines cannot logically execute on the same stack.
     1308A deep coroutine copy, which copies the stack, is also meaningless in an unmanaged language (no garbage collection), like C, because the stack may contain pointers to object within it that require updating for the copy.
     1309The \CFA @dtype@ property provides no \emph{implicit} copying operations and the @is_coroutine@ trait provides no \emph{explicit} copying operations, so all coroutines must be passed by reference (pointer).
     1310The function definitions ensure there is a statically typed @main@ function that is the starting point (first stack frame) of a coroutine, and a mechanism to get (read) the coroutine descriptor from its handle.
     1311The @main@ function has no return value or additional parameters because the coroutine type allows an arbitrary number of interface functions with corresponding arbitrary typed input/output values versus fixed ones.
     1312The advantage of this approach is that users can easily create different types of coroutines, \eg changing the memory layout of a coroutine is trivial when implementing the @get_coroutine@ function, and possibly redefining \textsf{suspend} and @resume@.
     1313
     1314The \CFA custom-type @coroutine@ implicitly implements the getter and forward declarations for the coroutine main.
    10341315\begin{cquote}
    10351316\begin{tabular}{@{}ccc@{}}
     
    10671348\end{tabular}
    10681349\end{cquote}
    1069 The combination of these two approaches allows an easy and concise specification to coroutining (and concurrency) for normal users, while more advanced users have tighter control on memory layout and initialization.
    1070 
    1071 
    1072 \subsection{Thread Interface}
    1073 \label{threads}
    1074 
    1075 Both user and kernel threads are supported, where user threads provide concurrency and kernel threads provide parallelism.
    1076 Like coroutines and for the same design reasons, the selected approach for user threads is to use language support by introducing a new kind of aggregate (structure) and a \CFA trait:
     1350The combination of custom types and fundamental @trait@ description of these types allows a concise specification for programmers and tools, while more advanced programmers can have tighter control over memory layout and initialization.
     1351
     1352Figure~\ref{f:CoroutineMemoryLayout} shows different memory-layout options for a coroutine (where a task is similar).
     1353The coroutine handle is the @coroutine@ instance containing programmer specified type global/communication variables across interface functions.
     1354The coroutine descriptor contains all implicit declarations needed by the runtime, \eg @suspend@/@resume@, and can be part of the coroutine handle or separate.
     1355The coroutine stack can appear in a number of locations and be fixed or variable sized.
     1356Hence, the coroutine's stack could be a VLS\footnote{
     1357We are examining variable-sized structures (VLS), where fields can be variable-sized structures or arrays.
     1358Once allocated, a VLS is fixed sized.}
     1359on the allocating stack, provided the allocating stack is large enough.
     1360For a VLS stack allocation/deallocation is an inexpensive adjustment of the stack pointer, modulo any stack constructor costs (\eg initial frame setup).
     1361For heap stack allocation, allocation/deallocation is an expensive heap allocation (where the heap can be a shared resource), modulo any stack constructor costs.
     1362With heap stack allocation, it is also possible to use a split (segmented) stack calling convention, available with gcc and clang, so the stack is variable sized.
     1363Currently, \CFA supports stack/heap allocated descriptors but only fixed-sized heap allocated stacks.
     1364In \CFA debug-mode, the fixed-sized stack is terminated with a write-only page, which catches most stack overflows.
     1365Experience teaching concurrency with \uC~\cite{CS343} shows fixed-sized stacks are rarely an issue for students.
     1366Split-stack allocation is under development but requires recompilation of legacy code, which may be impossible.
     1367
     1368\begin{figure}
     1369\centering
     1370\input{corlayout.pstex_t}
     1371\caption{Coroutine memory layout}
     1372\label{f:CoroutineMemoryLayout}
     1373\end{figure}
     1374
     1375
     1376\section{Concurrency}
     1377\label{s:Concurrency}
     1378
     1379Concurrency is nondeterministic scheduling of independent sequential execution paths (threads), where each thread has its own stack.
     1380A single thread with multiple call stacks, \newterm{coroutining}~\cite{Conway63,Marlin80}, does \emph{not} imply concurrency~\cite[\S~2]{Buhr05a}.
     1381In coroutining, coroutines self-schedule the thread across stacks so execution is deterministic.
     1382(It is \emph{impossible} to generate a concurrency error when coroutining.)
     1383However, coroutines are a stepping stone towards concurrency.
     1384
     1385The transition to concurrency, even for a single thread with multiple stacks, occurs when coroutines context switch to a \newterm{scheduling coroutine}, introducing non-determinism from the coroutine perspective~\cite[\S~3,]{Buhr05a}.
     1386Therefore, a minimal concurrency system requires coroutines \emph{in conjunction with a nondeterministic scheduler}.
     1387The resulting execution system now follows a cooperative threading model~\cite{Adya02,libdill}, called \newterm{non-preemptive scheduling}.
     1388Adding \newterm{preemption} introduces non-cooperative scheduling, where context switching occurs randomly between any two instructions often based on a timer interrupt, called \newterm{preemptive scheduling}.
     1389While a scheduler introduces uncertain execution among explicit context switches, preemption introduces uncertainty by introducing implicit context switches.
     1390Uncertainty gives the illusion of parallelism on a single processor and provides a mechanism to access and increase performance on multiple processors.
     1391The reason is that the scheduler/runtime have complete knowledge about resources and how to best utilized them.
     1392However, the introduction of unrestricted nondeterminism results in the need for \newterm{mutual exclusion} and \newterm{synchronization}, which restrict nondeterminism for correctness;
     1393otherwise, it is impossible to write meaningful concurrent programs.
     1394Optimal concurrent performance is often obtained by having as much nondeterminism as mutual exclusion and synchronization correctness allow.
     1395
     1396A scheduler can either be a stackless or stackful.
     1397For stackless, the scheduler performs scheduling on the stack of the current coroutine and switches directly to the next coroutine, so there is one context switch.
     1398For stackful, the current coroutine switches to the scheduler, which performs scheduling, and it then switches to the next coroutine, so there are two context switches.
     1399The \CFA runtime uses a stackful scheduler for uniformity and security.
     1400
     1401
     1402\subsection{Thread}
     1403\label{s:threads}
     1404
     1405Threading needs the ability to start a thread and wait for its completion.
     1406A common API for this ability is @fork@ and @join@.
     1407\begin{cquote}
     1408\begin{tabular}{@{}lll@{}}
     1409\multicolumn{1}{c}{\textbf{Java}} & \multicolumn{1}{c}{\textbf{\Celeven}} & \multicolumn{1}{c}{\textbf{pthreads}} \\
     1410\begin{cfa}
     1411class MyTask extends Thread {...}
     1412mytask t = new MyTask(...);
     1413`t.start();` // start
     1414// concurrency
     1415`t.join();` // wait
     1416\end{cfa}
     1417&
     1418\begin{cfa}
     1419class MyTask { ... } // functor
     1420MyTask mytask;
     1421`thread t( mytask, ... );` // start
     1422// concurrency
     1423`t.join();` // wait
     1424\end{cfa}
     1425&
     1426\begin{cfa}
     1427void * rtn( void * arg ) {...}
     1428pthread_t t;  int i = 3;
     1429`pthread_create( &t, rtn, (void *)i );` // start
     1430// concurrency
     1431`pthread_join( t, NULL );` // wait
     1432\end{cfa}
     1433\end{tabular}
     1434\end{cquote}
     1435\CFA has a simpler approach using a custom @thread@ type and leveraging declaration semantics (allocation/deallocation), where threads implicitly @fork@ after construction and @join@ before destruction.
     1436\begin{cfa}
     1437thread MyTask {};
     1438void main( MyTask & this ) { ... }
     1439int main() {
     1440        MyTask team`[10]`; $\C[2.5in]{// allocate stack-based threads, implicit start after construction}$
     1441        // concurrency
     1442} $\C{// deallocate stack-based threads, implicit joins before destruction}$
     1443\end{cfa}
     1444This semantic ensures a thread is started and stopped exactly once, eliminating some programming error, and scales to multiple threads for basic (termination) synchronization.
     1445For block allocation to arbitrary depth, including recursion, threads are created/destroyed in a lattice structure (tree with top and bottom).
     1446Arbitrary topologies are possible using dynamic allocation, allowing threads to outlive their declaration scope, identical to normal dynamic allocation.
     1447\begin{cfa}
     1448MyTask * factory( int N ) { ... return `anew( N )`; } $\C{// allocate heap-based threads, implicit start after construction}$
     1449int main() {
     1450        MyTask * team = factory( 10 );
     1451        // concurrency
     1452        `delete( team );` $\C{// deallocate heap-based threads, implicit joins before destruction}\CRT$
     1453}
     1454\end{cfa}
     1455
     1456Figure~\ref{s:ConcurrentMatrixSummation} shows concurrently adding the rows of a matrix and then totalling the subtotals sequentially, after all the row threads have terminated.
     1457The program uses heap-based threads because each thread needs different constructor values.
     1458(Python provides a simple iteration mechanism to initialize array elements to different values allowing stack allocation.)
     1459The allocation/deallocation pattern appears unusual because allocated objects are immediately deallocated without any intervening code.
     1460However, for threads, the deletion provides implicit synchronization, which is the intervening code.
     1461% While the subtotals are added in linear order rather than completion order, which slightly inhibits concurrency, the computation is restricted by the critical-path thread (\ie the thread that takes the longest), and so any inhibited concurrency is very small as totalling the subtotals is trivial.
     1462
     1463\begin{figure}
     1464\begin{cfa}
     1465`thread` Adder { int * row, cols, & subtotal; } $\C{// communication variables}$
     1466void ?{}( Adder & adder, int row[], int cols, int & subtotal ) {
     1467        adder.[ row, cols, &subtotal ] = [ row, cols, &subtotal ];
     1468}
     1469void main( Adder & adder ) with( adder ) {
     1470        subtotal = 0;
     1471        for ( c; cols ) { subtotal += row[c]; }
     1472}
     1473int main() {
     1474        const int rows = 10, cols = 1000;
     1475        int matrix[rows][cols], subtotals[rows], total = 0;
     1476        // read matrix
     1477        Adder * adders[rows];
     1478        for ( r; rows; ) { $\C{// start threads to sum rows}$
     1479                adders[r] = `new( matrix[r], cols, &subtotals[r] );`
     1480        }
     1481        for ( r; rows ) { $\C{// wait for threads to finish}$
     1482                `delete( adders[r] );` $\C{// termination join}$
     1483                total += subtotals[r]; $\C{// total subtotal}$
     1484        }
     1485        sout | total;
     1486}
     1487\end{cfa}
     1488\caption{Concurrent matrix summation}
     1489\label{s:ConcurrentMatrixSummation}
     1490\end{figure}
     1491
     1492
     1493\subsection{Thread Implementation}
     1494
     1495Threads in \CFA are user level run by runtime kernel threads (see Section~\ref{s:CFARuntimeStructure}), where user threads provide concurrency and kernel threads provide parallelism.
     1496Like coroutines, and for the same design reasons, \CFA provides a custom @thread@ type and a @trait@ to enforce and restrict the task-interface functions.
    10771497\begin{cquote}
    10781498\begin{tabular}{@{}c@{\hspace{3\parindentlnth}}c@{}}
    10791499\begin{cfa}
    10801500thread myThread {
    1081         // communication variables
     1501        ... // declaration/communication variables
    10821502};
    10831503
     
    10871507\begin{cfa}
    10881508trait is_thread( `dtype` T ) {
    1089       void main( T & );
    1090       thread_desc * get_thread( T & );
    1091       void ^?{}( T & `mutex` );
     1509        void main( T & );
     1510        thread_desc * get_thread( T & );
     1511        void ^?{}( T & `mutex` );
    10921512};
    10931513\end{cfa}
    10941514\end{tabular}
    10951515\end{cquote}
    1096 (The qualifier @mutex@ for the destructor parameter is discussed in Section~\ref{s:Monitors}.)
    1097 Like a coroutine, the statically-typed @main@ routine is the starting point (first stack frame) of a user thread.
    1098 The difference is that a coroutine borrows a thread from its caller, so the first thread resuming a coroutine creates an instance of @main@;
    1099 whereas, a user thread receives its own thread from the runtime system, which starts in @main@ as some point after the thread constructor is run.\footnote{
    1100 The \lstinline@main@ routine is already a special routine in C (where the program begins), so it is a natural extension of the semantics to use overloading to declare mains for different coroutines/threads (the normal main being the main of the initial thread).}
    1101 No return value or additional parameters are necessary for this routine because the task type allows an arbitrary number of interface routines with corresponding arbitrary typed input/output values.
    1102 
    1103 \begin{comment} % put in appendix with coroutine version ???
    1104 As such the @main@ routine of a thread can be defined as
    1105 \begin{cfa}
    1106 thread foo {};
    1107 
    1108 void main(foo & this) {
    1109         sout | "Hello World!" | endl;
    1110 }
    1111 \end{cfa}
    1112 
    1113 In this example, threads of type @foo@ start execution in the @void main(foo &)@ routine, which prints @"Hello World!".@ While this paper encourages this approach to enforce strongly typed programming, users may prefer to use the routine-based thread semantics for the sake of simplicity.
    1114 With the static semantics it is trivial to write a thread type that takes a routine pointer as a parameter and executes it on its stack asynchronously.
    1115 \begin{cfa}
    1116 typedef void (*voidRtn)(int);
    1117 
    1118 thread RtnRunner {
    1119         voidRtn func;
    1120         int arg;
    1121 };
    1122 
    1123 void ?{}(RtnRunner & this, voidRtn inRtn, int arg) {
    1124         this.func = inRtn;
    1125         this.arg  = arg;
    1126 }
    1127 
    1128 void main(RtnRunner & this) {
    1129         // thread starts here and runs the routine
    1130         this.func( this.arg );
    1131 }
    1132 
    1133 void hello(/*unused*/ int) {
    1134         sout | "Hello World!" | endl;
    1135 }
    1136 
    1137 int main() {
    1138         RtnRunner f = {hello, 42};
    1139         return 0?
    1140 }
    1141 \end{cfa}
    1142 A consequence of the strongly typed approach to main is that memory layout of parameters and return values to/from a thread are now explicitly specified in the \textbf{api}.
    1143 \end{comment}
    1144 
    1145 For user threads to be useful, it must be possible to start and stop the underlying thread, and wait for it to complete execution.
    1146 While using an API such as @fork@ and @join@ is relatively common, such an interface is awkward and unnecessary.
    1147 A simple approach is to use allocation/deallocation principles, and have threads implicitly @fork@ after construction and @join@ before destruction.
    1148 \begin{cfa}
    1149 thread World {};
    1150 void main( World & this ) {
    1151         sout | "World!" | endl;
    1152 }
    1153 int main() {
    1154         World w`[10]`;                                                  $\C{// implicit forks after creation}$
    1155         sout | "Hello " | endl;                                 $\C{// "Hello " and 10 "World!" printed concurrently}$
    1156 }                                                                                       $\C{// implicit joins before destruction}$
    1157 \end{cfa}
    1158 This semantics ensures a thread is started and stopped exactly once, eliminating some programming error, and scales to multiple threads for basic (termination) synchronization.
    1159 This tree-structure (lattice) create/delete from C block-structure is generalized by using dynamic allocation, so threads can outlive the scope in which they are created, much like dynamically allocating memory lets objects outlive the scope in which they are created.
    1160 \begin{cfa}
    1161 int main() {
    1162         MyThread * heapLived;
    1163         {
    1164                 MyThread blockLived;                            $\C{// fork block-based thread}$
    1165                 heapLived = `new`( MyThread );          $\C{// fork heap-based thread}$
    1166                 ...
    1167         }                                                                               $\C{// join block-based thread}$
    1168         ...
    1169         `delete`( heapLived );                                  $\C{// join heap-based thread}$
    1170 }
    1171 \end{cfa}
    1172 The heap-based approach allows arbitrary thread-creation topologies, with respect to fork/join-style concurrency.
    1173 
    1174 Figure~\ref{s:ConcurrentMatrixSummation} shows concurrently adding the rows of a matrix and then totalling the subtotals sequential, after all the row threads have terminated.
    1175 The program uses heap-based threads because each thread needs different constructor values.
    1176 (Python provides a simple iteration mechanism to initialize array elements to different values allowing stack allocation.)
    1177 The allocation/deallocation pattern appears unusual because allocated objects are immediately deleted without any intervening code.
    1178 However, for threads, the deletion provides implicit synchronization, which is the intervening code.
    1179 While the subtotals are added in linear order rather than completion order, which slight inhibits concurrency, the computation is restricted by the critical-path thread (\ie the thread that takes the longest), and so any inhibited concurrency is very small as totalling the subtotals is trivial.
    1180 
    1181 \begin{figure}
    1182 \begin{cfa}
    1183 thread Adder {
    1184     int * row, cols, & subtotal;                        $\C{// communication}$
    1185 };
    1186 void ?{}( Adder & adder, int row[], int cols, int & subtotal ) {
    1187     adder.[ row, cols, &subtotal ] = [ row, cols, &subtotal ];
    1188 }
    1189 void main( Adder & adder ) with( adder ) {
    1190     subtotal = 0;
    1191     for ( int c = 0; c < cols; c += 1 ) {
    1192                 subtotal += row[c];
    1193     }
    1194 }
    1195 int main() {
    1196     const int rows = 10, cols = 1000;
    1197     int matrix[rows][cols], subtotals[rows], total = 0;
    1198     // read matrix
    1199     Adder * adders[rows];
    1200     for ( int r = 0; r < rows; r += 1 ) {       $\C{// start threads to sum rows}$
    1201                 adders[r] = new( matrix[r], cols, &subtotals[r] );
    1202     }
    1203     for ( int r = 0; r < rows; r += 1 ) {       $\C{// wait for threads to finish}$
    1204                 delete( adders[r] );                            $\C{// termination join}$
    1205                 total += subtotals[r];                          $\C{// total subtotal}$
    1206     }
    1207     sout | total | endl;
    1208 }
    1209 \end{cfa}
    1210 \caption{Concurrent Matrix Summation}
    1211 \label{s:ConcurrentMatrixSummation}
    1212 \end{figure}
     1516Like coroutines, the @dtype@ property prevents \emph{implicit} copy operations and the @is_thread@ trait provides no \emph{explicit} copy operations, so threads must be passed by reference (pointer).
     1517Similarly, the function definitions ensure there is a statically typed @main@ function that is the thread starting point (first stack frame), a mechanism to get (read) the thread descriptor from its handle, and a special destructor to prevent deallocation while the thread is executing.
     1518(The qualifier @mutex@ for the destructor parameter is discussed in Section~\ref{s:Monitor}.)
     1519The difference between the coroutine and thread is that a coroutine borrows a thread from its caller, so the first thread resuming a coroutine creates the coroutine's stack and starts running the coroutine main on the stack;
     1520whereas, a thread is scheduling for execution in @main@ immediately after its constructor is run.
     1521No return value or additional parameters are necessary for this function because the @thread@ type allows an arbitrary number of interface functions with corresponding arbitrary typed input/output values.
    12131522
    12141523
    12151524\section{Mutual Exclusion / Synchronization}
    1216 
    1217 Uncontrolled non-deterministic execution is meaningless.
    1218 To reestablish meaningful execution requires mechanisms to reintroduce determinism (\ie restrict non-determinism), called mutual exclusion and synchronization, where mutual exclusion is an access-control mechanism on data shared by threads, and synchronization is a timing relationship among threads~\cite[\S~4]{Buhr05a}.
    1219 Since many deterministic challenges appear with the use of mutable shared state, some languages/libraries disallow it, \eg Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka~\cite{Akka} (Scala).
    1220 In these paradigms, interaction among concurrent objects is performed by stateless message-passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms closely relate to networking concepts (\eg channels~\cite{CSP,Go}).
    1221 However, in call/return-based languages, these approaches force a clear distinction (\ie introduce a new programming paradigm) between regular and concurrent computation (\ie routine call versus message passing).
    1222 Hence, a programmer must learn and manipulate two sets of design patterns.
     1525\label{s:MutualExclusionSynchronization}
     1526
     1527Unrestricted nondeterminism is meaningless as there is no way to know when the result is completed without synchronization.
     1528To produce meaningful execution requires clawing back some determinism using mutual exclusion and synchronization, where mutual exclusion provides access control for threads using shared data, and synchronization is a timing relationship among threads~\cite[\S~4]{Buhr05a}.
     1529Some concurrent systems eliminate mutable shared-state by switching to stateless communication like message passing~\cite{Thoth,Harmony,V-Kernel,MPI} (Erlang, MPI), channels~\cite{CSP} (CSP,Go), actors~\cite{Akka} (Akka, Scala), or functional techniques (Haskell).
     1530However, these approaches introduce a new communication mechanism for concurrency different from the standard communication using function call/return.
     1531Hence, a programmer must learn and manipulate two sets of design/programming patterns.
    12231532While this distinction can be hidden away in library code, effective use of the library still has to take both paradigms into account.
    1224 In contrast, approaches based on statefull models more closely resemble the standard call/return programming-model, resulting in a single programming paradigm.
    1225 
    1226 At the lowest level, concurrent control is implemented by atomic operations, upon which different kinds of locks mechanism are constructed, \eg semaphores~\cite{Dijkstra68b}, barriers, and path expressions~\cite{Campbell74}.
     1533In contrast, approaches based on stateful models more closely resemble the standard call/return programming model, resulting in a single programming paradigm.
     1534
     1535At the lowest level, concurrent control is implemented by atomic operations, upon which different kinds of locking mechanisms are constructed, \eg semaphores~\cite{Dijkstra68b}, barriers, and path expressions~\cite{Campbell74}.
    12271536However, for productivity it is always desirable to use the highest-level construct that provides the necessary efficiency~\cite{Hochstein05}.
    12281537A newer approach for restricting non-determinism is transactional memory~\cite{Herlihy93}.
    1229 While this approach is pursued in hardware~\cite{Nakaike15} and system languages, like \CC~\cite{Cpp-Transactions}, the performance and feature set is still too restrictive to be the main concurrency paradigm for system languages, which is why it was rejected as the core paradigm for concurrency in \CFA.
     1538While this approach is pursued in hardware~\cite{Nakaike15} and system languages, like \CC~\cite{Cpp-Transactions}, the performance and feature set is still too restrictive to be the main concurrency paradigm for system languages, which is why it is rejected as the core paradigm for concurrency in \CFA.
    12301539
    12311540One of the most natural, elegant, and efficient mechanisms for mutual exclusion and synchronization for shared-memory systems is the \emph{monitor}.
    1232 First proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}, many concurrent programming-languages provide monitors as an explicit language construct: \eg Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}.
     1541First proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}, many concurrent programming languages provide monitors as an explicit language construct: \eg Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}.
    12331542In addition, operating-system kernels and device drivers have a monitor-like structure, although they often use lower-level primitives such as mutex locks or semaphores to simulate monitors.
    1234 For these reasons, \CFA selected monitors as the core high-level concurrency-construct, upon which higher-level approaches can be easily constructed.
     1543For these reasons, \CFA selected monitors as the core high-level concurrency construct, upon which higher-level approaches can be easily constructed.
    12351544
    12361545
    12371546\subsection{Mutual Exclusion}
    12381547
    1239 A group of instructions manipulating a specific instance of shared data that must be performed atomically is called an (individual) \newterm{critical-section}~\cite{Dijkstra65}.
    1240 The generalization is called a \newterm{group critical-section}~\cite{Joung00}, where multiple tasks with the same session may use the resource simultaneously, but different sessions may not use the resource simultaneously.
    1241 The readers/writer problem~\cite{Courtois71} is an instance of a group critical-section, where readers have the same session and all writers have a unique session.
    1242 \newterm{Mutual exclusion} enforces that the correct kind and number of threads are using a critical section.
     1548A group of instructions manipulating a specific instance of shared data that must be performed atomically is called a \newterm{critical section}~\cite{Dijkstra65}, which is enforced by \newterm{simple mutual-exclusion}.
     1549The generalization is called a \newterm{group critical-section}~\cite{Joung00}, where multiple tasks with the same session use the resource simultaneously and different sessions are segregated, which is enforced by \newterm{complex mutual-exclusion} providing the correct kind and number of threads using a group critical-section.
     1550The readers/writer problem~\cite{Courtois71} is an instance of a group critical-section, where readers share a session but writers have a unique session.
    12431551
    12441552However, many solutions exist for mutual exclusion, which vary in terms of performance, flexibility and ease of use.
    12451553Methods range from low-level locks, which are fast and flexible but require significant attention for correctness, to higher-level concurrency techniques, which sacrifice some performance to improve ease of use.
    1246 Ease of use comes by either guaranteeing some problems cannot occur (\eg deadlock free), or by offering a more explicit coupling between shared data and critical section.
    1247 For example, the \CC @std::atomic<T>@ offers an easy way to express mutual-exclusion on a restricted set of operations (\eg reading/writing) for numerical types.
     1554Ease of use comes by either guaranteeing some problems cannot occur, \eg deadlock free, or by offering a more explicit coupling between shared data and critical section.
     1555For example, the \CC @std::atomic<T>@ offers an easy way to express mutual-exclusion on a restricted set of operations, \eg reading/writing, for numerical types.
    12481556However, a significant challenge with locks is composability because it takes careful organization for multiple locks to be used while preventing deadlock.
    12491557Easing composability is another feature higher-level mutual-exclusion mechanisms can offer.
     
    12541562Synchronization enforces relative ordering of execution, and synchronization tools provide numerous mechanisms to establish these timing relationships.
    12551563Low-level synchronization primitives offer good performance and flexibility at the cost of ease of use;
    1256 higher-level mechanisms often simplify usage by adding better coupling between synchronization and data (\eg message passing), or offering a simpler solution to otherwise involved challenges, \eg barrier lock.
    1257 Often synchronization is used to order access to a critical section, \eg ensuring a reader thread is the next kind of thread to enter a critical section.
    1258 If a writer thread is scheduled for next access, but another reader thread acquires the critical section first, that reader has \newterm{barged}.
     1564higher-level mechanisms often simplify usage by adding better coupling between synchronization and data, \eg receive-specific versus receive-any thread in message passing or offering specialized solutions, \eg barrier lock.
     1565Often synchronization is used to order access to a critical section, \eg ensuring a waiting writer thread enters the critical section before a calling reader thread.
     1566If the calling reader is scheduled before the waiting writer, the reader has barged.
    12591567Barging can result in staleness/freshness problems, where a reader barges ahead of a writer and reads temporally stale data, or a writer barges ahead of another writer overwriting data with a fresh value preventing the previous value from ever being read (lost computation).
    1260 Preventing or detecting barging is an involved challenge with low-level locks, which can be made much easier by higher-level constructs.
    1261 This challenge is often split into two different approaches: barging avoidance and barging prevention.
    1262 Algorithms that allow a barger, but divert it until later using current synchronization state (flags), are avoiding the barger;
    1263 algorithms that preclude a barger from entering during synchronization in the critical section prevent barging completely.
    1264 Techniques like baton-pass locks~\cite{Andrews89} between threads instead of unconditionally releasing locks is an example of barging prevention.
    1265 
    1266 
    1267 \section{Monitors}
    1268 \label{s:Monitors}
    1269 
    1270 A \textbf{monitor} is a set of routines that ensure mutual exclusion when accessing shared state.
    1271 More precisely, a monitor is a programming technique that binds mutual exclusion to routine scope, as opposed to locks, where mutual-exclusion is defined by acquire/release calls, independent of lexical context (analogous to block and heap storage allocation).
    1272 The strong association with the call/return paradigm eases programmability, readability and maintainability, at a slight cost in flexibility and efficiency.
    1273 
    1274 Note, like coroutines/threads, both locks and monitors require an abstract handle to reference them, because at their core, both mechanisms are manipulating non-copyable shared state.
    1275 Copying a lock is insecure because it is possible to copy an open lock and then use the open copy when the original lock is closed to simultaneously access the shared data.
    1276 Copying a monitor is secure because both the lock and shared data are copies, but copying the shared data is meaningless because it no longer represents a unique entity.
    1277 As for coroutines/tasks, a non-copyable (@dtype@) trait is used to capture this requirement, so all locks/monitors must be passed by reference (pointer).
     1568Preventing or detecting barging is an involved challenge with low-level locks, which is made easier through higher-level constructs.
     1569This challenge is often split into two different approaches: barging avoidance and prevention.
     1570Algorithms that unconditionally releasing a lock for competing threads to acquire use barging avoidance during synchronization to force a barging thread to wait;
     1571algorithms that conditionally hold locks during synchronization, \eg baton-passing~\cite{Andrews89}, prevent barging completely.
     1572
     1573
     1574\section{Monitor}
     1575\label{s:Monitor}
     1576
     1577A \textbf{monitor} is a set of functions that ensure mutual exclusion when accessing shared state.
     1578More precisely, a monitor is a programming technique that implicitly binds mutual exclusion to static function scope, as opposed to locks, where mutual-exclusion is defined by acquire/release calls, independent of lexical context (analogous to block and heap storage allocation).
     1579Restricting acquire/release points eases programming, comprehension, and maintenance, at a slight cost in flexibility and efficiency.
     1580\CFA uses a custom @monitor@ type and leverages declaration semantics (deallocation) to protect active or waiting threads in a monitor.
     1581
     1582The following is a \CFA monitor implementation of an atomic counter.
     1583\begin{cfa}[morekeywords=nomutex]
     1584`monitor` Aint { int cnt; }; $\C[4.25in]{// atomic integer counter}$
     1585int ++?( Aint & `mutex`$\(_{opt}\)$ this ) with( this ) { return ++cnt; } $\C{// increment}$
     1586int ?=?( Aint & `mutex`$\(_{opt}\)$ lhs, int rhs ) with( lhs ) { cnt = rhs; } $\C{// conversions with int}\CRT$
     1587int ?=?( int & lhs, Aint & `mutex`$\(_{opt}\)$ rhs ) with( rhs ) { lhs = cnt; }
     1588\end{cfa}
     1589% The @Aint@ constructor, @?{}@, uses the \lstinline[morekeywords=nomutex]@nomutex@ qualifier indicating mutual exclusion is unnecessary during construction because an object is inaccessible (private) until after it is initialized.
     1590% (While a constructor may publish its address into a global variable, doing so generates a race-condition.)
     1591The prefix increment operation, @++?@, is normally @mutex@, indicating mutual exclusion is necessary during function execution, to protect the incrementing from race conditions, unless there is an atomic increment instruction for the implementation type.
     1592The assignment operators provide bidirectional conversion between an atomic and normal integer without accessing field @cnt@;
     1593these operations only need @mutex@, if reading/writing the implementation type is not atomic.
     1594The atomic counter is used without any explicit mutual-exclusion and provides thread-safe semantics, which is similar to the \CC template @std::atomic@.
     1595\begin{cfa}
     1596int i = 0, j = 0, k = 5;
     1597Aint x = { 0 }, y = { 0 }, z = { 5 }; $\C{// no mutex required}$
     1598++x; ++y; ++z; $\C{// safe increment by multiple threads}$
     1599x = 2; y = i; z = k; $\C{// conversions}$
     1600i = x; j = y; k = z;
     1601\end{cfa}
     1602
     1603\CFA monitors have \newterm{multi-acquire} semantics so the thread in the monitor may acquire it multiple times without deadlock, allowing recursion and calling other interface functions.
     1604\begin{cfa}
     1605monitor M { ... } m;
     1606void foo( M & mutex m ) { ... } $\C{// acquire mutual exclusion}$
     1607void bar( M & mutex m ) { $\C{// acquire mutual exclusion}$
     1608        ... `bar( m );` ... `foo( m );` ... $\C{// reacquire mutual exclusion}$
     1609}
     1610\end{cfa}
     1611\CFA monitors also ensure the monitor lock is released regardless of how an acquiring function ends (normal or exceptional), and returning a shared variable is safe via copying before the lock is released.
     1612Similar safety is offered by \emph{explicit} mechanisms like \CC RAII;
     1613monitor \emph{implicit} safety ensures no programmer usage errors.
     1614Furthermore, RAII mechanisms cannot handle complex synchronization within a monitor, where the monitor lock may not be released on function exit because it is passed to an unblocking thread;
     1615RAII is purely a mutual-exclusion mechanism (see Section~\ref{s:Scheduling}).
     1616
     1617
     1618\subsection{Monitor Implementation}
     1619
     1620For the same design reasons, \CFA provides a custom @monitor@ type and a @trait@ to enforce and restrict the monitor-interface functions.
     1621\begin{cquote}
     1622\begin{tabular}{@{}c@{\hspace{3\parindentlnth}}c@{}}
     1623\begin{cfa}
     1624monitor M {
     1625        ... // shared data
     1626};
     1627
     1628\end{cfa}
     1629&
    12781630\begin{cfa}
    12791631trait is_monitor( `dtype` T ) {
     
    12821634};
    12831635\end{cfa}
     1636\end{tabular}
     1637\end{cquote}
     1638The @dtype@ property prevents \emph{implicit} copy operations and the @is_monitor@ trait provides no \emph{explicit} copy operations, so monitors must be passed by reference (pointer).
     1639% Copying a lock is insecure because it is possible to copy an open lock and then use the open copy when the original lock is closed to simultaneously access the shared data.
     1640% Copying a monitor is secure because both the lock and shared data are copies, but copying the shared data is meaningless because it no longer represents a unique entity.
     1641Similarly, the function definitions ensures there is a mechanism to get (read) the monitor descriptor from its handle, and a special destructor to prevent deallocation if a thread using the shared data.
     1642The custom monitor type also inserts any locks needed to implement the mutual exclusion semantics.
    12841643
    12851644
     
    12871646\label{s:MutexAcquisition}
    12881647
    1289 While correctness implicitly implies a monitor's mutual exclusion is acquired and released, there are implementation options about when and where the locking/unlocking occurs.
     1648While the monitor lock provides mutual exclusion for shared data, there are implementation options for when and where the locking/unlocking occurs.
    12901649(Much of this discussion also applies to basic locks.)
    1291 For example, a monitor may need to be passed through multiple helper routines before it becomes necessary to acquire the monitor mutual-exclusion.
    1292 \begin{cfa}[morekeywords=nomutex]
    1293 monitor Aint { int cnt; };                                      $\C{// atomic integer counter}$
    1294 void ?{}( Aint & `nomutex` this ) with( this ) { cnt = 0; } $\C{// constructor}$
    1295 int ?=?( Aint & `mutex`$\(_{opt}\)$ lhs, int rhs ) with( lhs ) { cnt = rhs; } $\C{// conversions}$
    1296 void ?{}( int & this, Aint & `mutex`$\(_{opt}\)$ v ) { this = v.cnt; }
    1297 int ?=?( int & lhs, Aint & `mutex`$\(_{opt}\)$ rhs ) with( rhs ) { lhs = cnt; }
    1298 int ++?( Aint & `mutex`$\(_{opt}\)$ this ) with( this ) { return ++cnt; } $\C{// increment}$
    1299 \end{cfa}
    1300 The @Aint@ constructor, @?{}@, uses the \lstinline[morekeywords=nomutex]@nomutex@ qualifier indicating mutual exclusion is unnecessary during construction because an object is inaccessible (private) until after it is initialized.
    1301 (While a constructor may publish its address into a global variable, doing so generates a race-condition.)
    1302 The conversion operators for initializing and assigning with a normal integer only need @mutex@, if reading/writing the implementation type is not atomic.
    1303 Finally, the prefix increment operato, @++?@, is normally @mutex@ to protect the incrementing from race conditions, unless there is an atomic increment instruction for the implementation type.
    1304 
    1305 The atomic counter is used without any explicit mutual-exclusion and provides thread-safe semantics, which is similar to the \CC template @std::atomic@.
    1306 \begin{cfa}
    1307 Aint x, y, z;
    1308 ++x; ++y; ++z;                                                          $\C{// safe increment by multiple threads}$
    1309 x = 2; y = 2; z = 2;                                            $\C{// conversions}$
    1310 int i = x, j = y, k = z;
    1311 i = x; j = y; k = z;
    1312 \end{cfa}
    1313 
    1314 For maximum usability, monitors have \newterm{multi-acquire} semantics allowing a thread to acquire it multiple times without deadlock.
    1315 For example, atomically printing the contents of a binary tree:
    1316 \begin{cfa}
    1317 monitor Tree {
    1318         Tree * left, right;
    1319         // value
    1320 };
    1321 void print( Tree & mutex tree ) {                       $\C{// prefix traversal}$
    1322         // write value
    1323         print( tree->left );                                    $\C{// multiply acquire monitor lock on each recursion}$
    1324         print( tree->right );
    1325 }
    1326 \end{cfa}
    1327 
    1328 Mandatory monitor qualifiers have the benefit of being self-documented, but requiring both @mutex@ and \lstinline[morekeywords=nomutex]@nomutex@ for all monitor parameter is redundant.
    1329 Instead, one of qualifier semantics can be the default, and the other required.
    1330 For example, assume the safe @mutex@ option for a monitor parameter because assuming \lstinline[morekeywords=nomutex]@nomutex@ may cause subtle errors.
    1331 On the other hand, assuming \lstinline[morekeywords=nomutex]@nomutex@ is the \emph{normal} parameter behaviour, stating explicitly ``this parameter is not special''.
     1650For example, a monitor may be passed through multiple helper functions before it is necessary to acquire the monitor's mutual exclusion.
     1651
     1652The benefit of mandatory monitor qualifiers is self-documentation, but requiring both @mutex@ and \lstinline[morekeywords=nomutex]@nomutex@ for all monitor parameters is redundant.
     1653Instead, the semantics has one qualifier as the default and the other required.
     1654For example, make the safe @mutex@ qualifier the default because assuming \lstinline[morekeywords=nomutex]@nomutex@ may cause subtle errors.
     1655Alternatively, make the unsafe \lstinline[morekeywords=nomutex]@nomutex@ qualifier the default because it is the \emph{normal} parameter semantics while @mutex@ parameters are rare.
    13321656Providing a default qualifier implies knowing whether a parameter is a monitor.
    1333 Since \CFA relies heavily on traits as an abstraction mechanism, the distinction between a type that is a monitor and a type that looks like a monitor can become blurred.
     1657Since \CFA relies heavily on traits as an abstraction mechanism, types can coincidentally match the monitor trait but not be a monitor, similar to inheritance where a shape and playing card can both be drawable.
    13341658For this reason, \CFA requires programmers to identify the kind of parameter with the @mutex@ keyword and uses no keyword to mean \lstinline[morekeywords=nomutex]@nomutex@.
    13351659
    13361660The next semantic decision is establishing which parameter \emph{types} may be qualified with @mutex@.
    1337 Given:
     1661The following has monitor parameter types that are composed of multiple objects.
    13381662\begin{cfa}
    13391663monitor M { ... }
    1340 int f1( M & mutex m );
    1341 int f2( M * mutex m );
    1342 int f3( M * mutex m[] );
    1343 int f4( stack( M * ) & mutex m );
    1344 \end{cfa}
    1345 the issue is that some of these parameter types are composed of multiple objects.
    1346 For @f1@, there is only a single parameter object.
    1347 Adding indirection in @f2@ still identifies a single object.
    1348 However, the matrix in @f3@ introduces multiple objects.
    1349 While shown shortly, multiple acquisition is possible;
    1350 however array lengths are often unknown in C.
    1351 This issue is exacerbated in @f4@, where the data structure must be safely traversed to acquire all of its elements.
    1352 
    1353 To make the issue tractable, \CFA only acquires one monitor per parameter with at most one level of indirection.
    1354 However, the C type-system has an ambiguity with respects to arrays.
    1355 Is the argument for @f2@ a single object or an array of objects?
    1356 If it is an array, only the first element of the array is acquired, which seems unsafe;
    1357 hence, @mutex@ is disallowed for array parameters.
    1358 \begin{cfa}
    1359 int f1( M & mutex m );                                          $\C{// allowed: recommended case}$
    1360 int f2( M * mutex m );                                          $\C{// disallowed: could be an array}$
    1361 int f3( M mutex m[$\,$] );                                      $\C{// disallowed: array length unknown}$
    1362 int f4( M ** mutex m );                                         $\C{// disallowed: could be an array}$
    1363 int f5( M * mutex m[$\,$] );                            $\C{// disallowed: array length unknown}$
    1364 \end{cfa}
    1365 % Note, not all array routines have distinct types: @f2@ and @f3@ have the same type, as do @f4@ and @f5@.
    1366 % However, even if the code generation could tell the difference, the extra information is still not sufficient to extend meaningfully the monitor call semantic.
    1367 
    1368 For object-oriented monitors, calling a mutex member \emph{implicitly} acquires mutual exclusion of the receiver object, @`rec`.foo(...)@.
    1369 \CFA has no receiver, and hence, must use an explicit mechanism to specify which object has mutual exclusion acquired.
    1370 A positive consequence of this design decision is the ability to support multi-monitor routines.
    1371 \begin{cfa}
    1372 int f( M & mutex x, M & mutex y );              $\C{// multiple monitor parameter of any type}$
    1373 M m1, m2;
    1374 f( m1, m2 );
    1375 \end{cfa}
    1376 (While object-oriented monitors can be extended with a mutex qualifier for multiple-monitor members, no prior example of this feature could be found.)
    1377 In practice, writing multi-locking routines that do not deadlocks is tricky.
    1378 Having language support for such a feature is therefore a significant asset for \CFA.
    1379 
    1380 The capability to acquire multiple locks before entering a critical section is called \newterm{bulk acquire}.
    1381 In previous example, \CFA guarantees the order of acquisition is consistent across calls to different routines using the same monitors as arguments.
    1382 This consistent ordering means acquiring multiple monitors is safe from deadlock.
    1383 However, users can force the acquiring order.
    1384 For example, notice the use of @mutex@/\lstinline[morekeywords=nomutex]@nomutex@ and how this affects the acquiring order:
    1385 \begin{cfa}
    1386 void foo( M & mutex m1, M & mutex m2 );         $\C{// acquire m1 and m2}$
     1664int f1( M & mutex m ); $\C{// single parameter object}$
     1665int f2( M * mutex m ); $\C{// single or multiple parameter object}$
     1666int f3( M * mutex m[$\,$] ); $\C{// multiple parameter object}$
     1667int f4( stack( M * ) & mutex m ); $\C{// multiple parameters object}$
     1668\end{cfa}
     1669Function @f1@ has a single parameter object, while @f2@'s indirection could be a single or multi-element array, where static array size is often unknown in C.
     1670Function @f3@ has a multiple object matrix, and @f4@ a multiple object data structure.
     1671While shown shortly, multiple object acquisition is possible, but the number of objects must be statically known.
     1672Therefore, \CFA only acquires one monitor per parameter with at most one level of indirection, excluding pointers as it is impossible to statically determine the size.
     1673
     1674For object-oriented monitors, \eg Java, calling a mutex member \emph{implicitly} acquires mutual exclusion of the receiver object, @`rec`.foo(...)@.
     1675\CFA has no receiver, and hence, the explicit @mutex@ qualifier is used to specify which objects acquire mutual exclusion.
     1676A positive consequence of this design decision is the ability to support multi-monitor functions,\footnote{
     1677While object-oriented monitors can be extended with a mutex qualifier for multiple-monitor members, no prior example of this feature could be found.}
     1678called \newterm{bulk acquire}.
     1679\CFA guarantees acquisition order is consistent across calls to @mutex@ functions using the same monitors as arguments, so acquiring multiple monitors is safe from deadlock.
     1680Figure~\ref{f:BankTransfer} shows a trivial solution to the bank transfer problem~\cite{BankTransfer}, where two resources must be locked simultaneously, using \CFA monitors with implicit locking and \CC with explicit locking.
     1681A \CFA programmer only has to manage when to acquire mutual exclusion;
     1682a \CC programmer must select the correct lock and acquisition mechanism from a panoply of locking options.
     1683Making good choices for common cases in \CFA simplifies the programming experience and enhances safety.
     1684
     1685\begin{figure}
     1686\centering
     1687\begin{lrbox}{\myboxA}
     1688\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     1689monitor BankAccount {
     1690
     1691        int balance;
     1692} b1 = { 0 }, b2 = { 0 };
     1693void deposit( BankAccount & `mutex` b,
     1694                        int deposit ) with(b) {
     1695        balance += deposit;
     1696}
     1697void transfer( BankAccount & `mutex` my,
     1698        BankAccount & `mutex` your, int me2you ) {
     1699
     1700        deposit( my, -me2you ); // debit
     1701        deposit( your, me2you ); // credit
     1702}
     1703`thread` Person { BankAccount & b1, & b2; };
     1704void main( Person & person ) with(person) {
     1705        for ( 10_000_000 ) {
     1706                if ( random() % 3 ) deposit( b1, 3 );
     1707                if ( random() % 3 ) transfer( b1, b2, 7 );
     1708        }
     1709}   
     1710int main() {
     1711        `Person p1 = { b1, b2 }, p2 = { b2, b1 };`
     1712
     1713} // wait for threads to complete
     1714\end{cfa}
     1715\end{lrbox}
     1716
     1717\begin{lrbox}{\myboxB}
     1718\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     1719struct BankAccount {
     1720        `recursive_mutex m;`
     1721        int balance = 0;
     1722} b1, b2;
     1723void deposit( BankAccount & b, int deposit ) {
     1724        `scoped_lock lock( b.m );`
     1725        b.balance += deposit;
     1726}
     1727void transfer( BankAccount & my,
     1728                        BankAccount & your, int me2you ) {
     1729        `scoped_lock lock( my.m, your.m );`
     1730        deposit( my, -me2you ); // debit
     1731        deposit( your, me2you ); // credit
     1732}
     1733
     1734void person( BankAccount & b1, BankAccount & b2 ) {
     1735        for ( int i = 0; i < 10$'$000$'$000; i += 1 ) {
     1736                if ( random() % 3 ) deposit( b1, 3 );
     1737                if ( random() % 3 ) transfer( b1, b2, 7 );
     1738        }
     1739}   
     1740int main() {
     1741        `thread p1(person, ref(b1), ref(b2)), p2(person, ref(b2), ref(b1));`
     1742        `p1.join(); p2.join();`
     1743}
     1744\end{cfa}
     1745\end{lrbox}
     1746
     1747\subfloat[\CFA]{\label{f:CFABank}\usebox\myboxA}
     1748\hspace{3pt}
     1749\vrule
     1750\hspace{3pt}
     1751\subfloat[\CC]{\label{f:C++Bank}\usebox\myboxB}
     1752\hspace{3pt}
     1753\caption{Bank transfer problem}
     1754\label{f:BankTransfer}
     1755\end{figure}
     1756
     1757Users can still force the acquiring order by using @mutex@/\lstinline[morekeywords=nomutex]@nomutex@.
     1758\begin{cfa}
     1759void foo( M & mutex m1, M & mutex m2 ); $\C{// acquire m1 and m2}$
    13871760void bar( M & mutex m1, M & /* nomutex */ m2 ) { $\C{// acquire m1}$
    1388         ... foo( m1, m2 ); ...                                  $\C{// acquire m2}$
     1761        ... foo( m1, m2 ); ... $\C{// acquire m2}$
    13891762}
    13901763void baz( M & /* nomutex */ m1, M & mutex m2 ) { $\C{// acquire m2}$
    1391         ... foo( m1, m2 ); ...                                  $\C{// acquire m1}$
    1392 }
    1393 \end{cfa}
    1394 The multi-acquire semantics allows @bar@ or @baz@ to acquire a monitor lock and reacquire it in @foo@.
    1395 In the calls to @bar@ and @baz@, the monitors are acquired in opposite order.
    1396 
    1397 However, such use leads to lock acquiring order problems resulting in deadlock~\cite{Lister77}, where detecting it requires dynamically tracking of monitor calls, and dealing with it requires implement rollback semantics~\cite{Dice10}.
    1398 In \CFA, safety is guaranteed by using bulk acquire of all monitors to shared objects, whereas other monitor systems provide no aid.
    1399 While \CFA provides only a partial solution, the \CFA partial solution handles many useful cases.
    1400 \begin{cfa}
    1401 monitor Bank { ... };
    1402 void deposit( Bank & `mutex` b, int deposit );
    1403 void transfer( Bank & `mutex` mybank, Bank & `mutex` yourbank, int me2you) {
    1404         deposit( mybank, `-`me2you );                   $\C{// debit}$
    1405         deposit( yourbank, me2you );                    $\C{// credit}$
    1406 }
    1407 \end{cfa}
    1408 This example shows a trivial solution to the bank-account transfer problem~\cite{BankTransfer}.
    1409 Without multi- and bulk acquire, the solution to this problem requires careful engineering.
    1410 
    1411 
    1412 \subsection{\protect\lstinline|mutex| statement} \label{mutex-stmt}
    1413 
    1414 The monitor call-semantics associate all locking semantics to routines.
    1415 Like Java, \CFA offers an alternative @mutex@ statement to reduce refactoring and naming.
     1764        ... foo( m1, m2 ); ... $\C{// acquire m1}$
     1765}
     1766\end{cfa}
     1767The bulk-acquire semantics allow @bar@ or @baz@ to acquire a monitor lock and reacquire it in @foo@.
     1768The calls to @bar@ and @baz@ acquired the monitors in opposite order, possibly resulting in deadlock.
     1769However, this case is the simplest instance of the \emph{nested-monitor problem}~\cite{Lister77}, where monitors are acquired in sequence versus bulk.
     1770Detecting the nested-monitor problem requires dynamic tracking of monitor calls, and dealing with it requires rollback semantics~\cite{Dice10}.
     1771\CFA does not deal with this fundamental problem.
     1772
     1773Finally, like Java, \CFA offers an alternative @mutex@ statement to reduce refactoring and naming.
    14161774\begin{cquote}
    1417 \begin{tabular}{@{}c|@{\hspace{\parindentlnth}}c@{}}
    1418 routine call & @mutex@ statement \\
    1419 \begin{cfa}
    1420 monitor M {};
     1775\renewcommand{\arraystretch}{0.0}
     1776\begin{tabular}{@{}l@{\hspace{3\parindentlnth}}l@{}}
     1777\multicolumn{1}{c}{\textbf{\lstinline@mutex@ call}} & \multicolumn{1}{c}{\lstinline@mutex@ \textbf{statement}} \\
     1778\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     1779monitor M { ... };
    14211780void foo( M & mutex m1, M & mutex m2 ) {
    14221781        // critical section
     
    14271786\end{cfa}
    14281787&
    1429 \begin{cfa}
     1788\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    14301789
    14311790void bar( M & m1, M & m2 ) {
     
    14401799
    14411800
    1442 \section{Internal Scheduling}
    1443 \label{s:InternalScheduling}
    1444 
    1445 While monitor mutual-exclusion provides safe access to shared data, the monitor data may indicate that a thread accessing it cannot proceed, \eg a bounded buffer, Figure~\ref{f:GenericBoundedBuffer}, may be full/empty so produce/consumer threads must block.
     1801\subsection{Scheduling}
     1802\label{s:Scheduling}
     1803
     1804% There are many aspects of scheduling in a concurrency system, all related to resource utilization by waiting threads, \ie which thread gets the resource next.
     1805% Different forms of scheduling include access to processors by threads (see Section~\ref{s:RuntimeStructureCluster}), another is access to a shared resource by a lock or monitor.
     1806This section discusses monitor scheduling for waiting threads eligible for entry, \ie which thread gets the shared resource next. (See Section~\ref{s:RuntimeStructureCluster} for scheduling threads on virtual processors.)
     1807While monitor mutual-exclusion provides safe access to shared data, the monitor data may indicate that a thread accessing it cannot proceed, \eg a bounded buffer may be full/empty so produce/consumer threads must block.
    14461808Leaving the monitor and trying again (busy waiting) is impractical for high-level programming.
    1447 Monitors eliminate busy waiting by providing internal synchronization to schedule threads needing access to the shared data, where the synchronization is blocking (threads are parked) versus spinning.
    1448 The synchronization is generally achieved with internal~\cite{Hoare74} or external~\cite[\S~2.9.2]{uC++} scheduling, where \newterm{scheduling} is defined as indicating which thread acquires the critical section next.
     1809Monitors eliminate busy waiting by providing synchronization to schedule threads needing access to the shared data, where threads block versus spinning.
     1810Synchronization is generally achieved with internal~\cite{Hoare74} or external~\cite[\S~2.9.2]{uC++} scheduling.
    14491811\newterm{Internal scheduling} is characterized by each thread entering the monitor and making an individual decision about proceeding or blocking, while \newterm{external scheduling} is characterized by an entering thread making a decision about proceeding for itself and on behalf of other threads attempting entry.
    1450 
    1451 Figure~\ref{f:BBInt} shows a \CFA bounded-buffer with internal scheduling, where producers/consumers enter the monitor, see the buffer is full/empty, and block on an appropriate condition lock, @full@/@empty@.
    1452 The @wait@ routine atomically blocks the calling thread and implicitly releases the monitor lock(s) for all monitors in the routine's parameter list.
    1453 The appropriate condition lock is signalled to unblock an opposite kind of thread after an element is inserted/removed from the buffer.
    1454 Signalling is unconditional, because signalling an empty condition lock does nothing.
    1455 Signalling semantics cannot have the signaller and signalled thread in the monitor simultaneously, which means:
    1456 \begin{enumerate}
    1457 \item
    1458 The signalling thread returns immediately, and the signalled thread continues.
    1459 \item
    1460 The signalling thread continues and the signalled thread is marked for urgent unblocking at the next scheduling point (exit/wait).
    1461 \item
    1462 The signalling thread blocks but is marked for urgrent unblocking at the next scheduling point and the signalled thread continues.
    1463 \end{enumerate}
    1464 The first approach is too restrictive, as it precludes solving a reasonable class of problems (\eg dating service).
    1465 \CFA supports the next two semantics as both are useful.
    1466 Finally, while it is common to store a @condition@ as a field of the monitor, in \CFA, a @condition@ variable can be created/stored independently.
    1467 Furthermore, a condition variable is tied to a \emph{group} of monitors on first use (called \newterm{branding}), which means that using internal scheduling with distinct sets of monitors requires one condition variable per set of monitors.
     1812Finally, \CFA monitors do not allow calling threads to barge ahead of signalled threads, which simplifies synchronization among threads in the monitor and increases correctness.
     1813If barging is allowed, synchronization between a signaller and signallee is difficult, often requiring additional flags and multiple unblock/block cycles.
     1814In fact, signals-as-hints is completely opposite from that proposed by Hoare in the seminal paper on monitors~\cite[p.~550]{Hoare74}.
     1815% \begin{cquote}
     1816% However, we decree that a signal operation be followed immediately by resumption of a waiting program, without possibility of an intervening procedure call from yet a third program.
     1817% It is only in this way that a waiting program has an absolute guarantee that it can acquire the resource just released by the signalling program without any danger that a third program will interpose a monitor entry and seize the resource instead.~\cite[p.~550]{Hoare74}
     1818% \end{cquote}
     1819Furthermore, \CFA concurrency has no spurious wakeup~\cite[\S~9]{Buhr05a}, which eliminates an implicit form of self barging.
     1820Hence, a \CFA @wait@ statement is not enclosed in a @while@ loop retesting a blocking predicate, which can cause thread starvation due to barging.
     1821
     1822Figure~\ref{f:MonitorScheduling} shows general internal/external scheduling (for the bounded-buffer example in Figure~\ref{f:InternalExternalScheduling}).
     1823External calling threads block on the calling queue, if the monitor is occupied, otherwise they enter in FIFO order.
     1824Internal threads block on condition queues via @wait@ and reenter from the condition in FIFO order.
     1825Alternatively, internal threads block on urgent from the @signal_block@ or @waitfor@, and reenter implicitly when the monitor becomes empty, \ie, the thread in the monitor exits or waits.
     1826
     1827There are three signalling mechanisms to unblock waiting threads to enter the monitor.
     1828Note, signalling cannot have the signaller and signalled thread in the monitor simultaneously because of the mutual exclusion, so either the signaller or signallee can proceed.
     1829For internal scheduling, threads are unblocked from condition queues using @signal@, where the signallee is moved to urgent and the signaller continues (solid line).
     1830Multiple signals move multiple signallees to urgent until the condition is empty.
     1831When the signaller exits or waits, a thread blocked on urgent is processed before calling threads to prevent barging.
     1832(Java conceptually moves the signalled thread to the calling queue, and hence, allows barging.)
     1833The alternative unblock is in the opposite order using @signal_block@, where the signaller is moved to urgent and the signallee continues (dashed line), and is implicitly unblocked from urgent when the signallee exits or waits.
     1834
     1835For external scheduling, the condition queues are not used;
     1836instead threads are unblocked directly from the calling queue using @waitfor@ based on function names requesting mutual exclusion.
     1837(The linear search through the calling queue to locate a particular call can be reduced to $O(1)$.)
     1838The @waitfor@ has the same semantics as @signal_block@, where the signalled thread executes before the signallee, which waits on urgent.
     1839Executing multiple @waitfor@s from different signalled functions causes the calling threads to move to urgent.
     1840External scheduling requires urgent to be a stack, because the signaller expects to execute immediately after the specified monitor call has exited or waited.
     1841Internal scheduling behaves the same for an urgent stack or queue, except for multiple signalling, where the threads unblock from urgent in reverse order from signalling.
     1842If the restart order is important, multiple signalling by a signal thread can be transformed into daisy-chain signalling among threads, where each thread signals the next thread.
     1843We tried both a stack for @waitfor@ and queue for signalling, but that resulted in complex semantics about which thread enters next.
     1844Hence, \CFA uses a single urgent stack to correctly handle @waitfor@ and adequately support both forms of signalling.
     1845
     1846\begin{figure}
     1847\centering
     1848% \subfloat[Scheduling Statements] {
     1849% \label{fig:SchedulingStatements}
     1850% {\resizebox{0.45\textwidth}{!}{\input{CondSigWait.pstex_t}}}
     1851\input{CondSigWait.pstex_t}
     1852% }% subfloat
     1853% \quad
     1854% \subfloat[Bulk acquire monitor] {
     1855% \label{fig:BulkMonitor}
     1856% {\resizebox{0.45\textwidth}{!}{\input{ext_monitor.pstex_t}}}
     1857% }% subfloat
     1858\caption{Monitor Scheduling}
     1859\label{f:MonitorScheduling}
     1860\end{figure}
     1861
     1862Figure~\ref{f:BBInt} shows a \CFA generic bounded-buffer with internal scheduling, where producers/consumers enter the monitor, detect the buffer is full/empty, and block on an appropriate condition variable, @full@/@empty@.
     1863The @wait@ function atomically blocks the calling thread and implicitly releases the monitor lock(s) for all monitors in the function's parameter list.
     1864The appropriate condition variable is signalled to unblock an opposite kind of thread after an element is inserted/removed from the buffer.
     1865Signalling is unconditional, because signalling an empty condition variable does nothing.
     1866It is common to declare condition variables as monitor fields to prevent shared access, hence no locking is required for access as the conditions are protected by the monitor lock.
     1867In \CFA, a condition variable can be created/stored independently.
     1868% To still prevent expensive locking on access, a condition variable is tied to a \emph{group} of monitors on first use, called \newterm{branding}, resulting in a low-cost boolean test to detect sharing from other monitors.
     1869
     1870% Signalling semantics cannot have the signaller and signalled thread in the monitor simultaneously, which means:
     1871% \begin{enumerate}
     1872% \item
     1873% The signalling thread returns immediately and the signalled thread continues.
     1874% \item
     1875% The signalling thread continues and the signalled thread is marked for urgent unblocking at the next scheduling point (exit/wait).
     1876% \item
     1877% The signalling thread blocks but is marked for urgent unblocking at the next scheduling point and the signalled thread continues.
     1878% \end{enumerate}
     1879% The first approach is too restrictive, as it precludes solving a reasonable class of problems, \eg dating service (see Figure~\ref{f:DatingService}).
     1880% \CFA supports the next two semantics as both are useful.
    14681881
    14691882\begin{figure}
     
    14791892        };
    14801893        void ?{}( Buffer(T) & buffer ) with(buffer) {
    1481                 [front, back, count] = 0;
     1894                front = back = count = 0;
    14821895        }
    1483 
    14841896        void insert( Buffer(T) & mutex buffer, T elem )
    14851897                                with(buffer) {
     
    14981910\end{lrbox}
    14991911
     1912% \newbox\myboxB
     1913% \begin{lrbox}{\myboxB}
     1914% \begin{cfa}[aboveskip=0pt,belowskip=0pt]
     1915% forall( otype T ) { // distribute forall
     1916%       monitor Buffer {
     1917%
     1918%               int front, back, count;
     1919%               T elements[10];
     1920%       };
     1921%       void ?{}( Buffer(T) & buffer ) with(buffer) {
     1922%               [front, back, count] = 0;
     1923%       }
     1924%       T remove( Buffer(T) & mutex buffer ); // forward
     1925%       void insert( Buffer(T) & mutex buffer, T elem )
     1926%                               with(buffer) {
     1927%               if ( count == 10 ) `waitfor( remove, buffer )`;
     1928%               // insert elem into buffer
     1929%
     1930%       }
     1931%       T remove( Buffer(T) & mutex buffer ) with(buffer) {
     1932%               if ( count == 0 ) `waitfor( insert, buffer )`;
     1933%               // remove elem from buffer
     1934%
     1935%               return elem;
     1936%       }
     1937% }
     1938% \end{cfa}
     1939% \end{lrbox}
     1940
    15001941\newbox\myboxB
    15011942\begin{lrbox}{\myboxB}
    15021943\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    1503 forall( otype T ) { // distribute forall
    1504         monitor Buffer {
    1505 
    1506                 int front, back, count;
    1507                 T elements[10];
    1508         };
    1509         void ?{}( Buffer(T) & buffer ) with(buffer) {
    1510                 [front, back, count] = 0;
    1511         }
    1512         T remove( Buffer(T) & mutex buffer ); // forward
    1513         void insert( Buffer(T) & mutex buffer, T elem )
    1514                                 with(buffer) {
    1515                 if ( count == 10 ) `waitfor( remove, buffer )`;
    1516                 // insert elem into buffer
    1517 
    1518         }
    1519         T remove( Buffer(T) & mutex buffer ) with(buffer) {
    1520                 if ( count == 0 ) `waitfor( insert, buffer )`;
    1521                 // remove elem from buffer
    1522 
    1523                 return elem;
    1524         }
    1525 }
     1944monitor ReadersWriter {
     1945        int rcnt, wcnt; // readers/writer using resource
     1946};
     1947void ?{}( ReadersWriter & rw ) with(rw) {
     1948        rcnt = wcnt = 0;
     1949}
     1950void EndRead( ReadersWriter & mutex rw ) with(rw) {
     1951        rcnt -= 1;
     1952}
     1953void EndWrite( ReadersWriter & mutex rw ) with(rw) {
     1954        wcnt = 0;
     1955}
     1956void StartRead( ReadersWriter & mutex rw ) with(rw) {
     1957        if ( wcnt > 0 ) `waitfor( EndWrite, rw );`
     1958        rcnt += 1;
     1959}
     1960void StartWrite( ReadersWriter & mutex rw ) with(rw) {
     1961        if ( wcnt > 0 ) `waitfor( EndWrite, rw );`
     1962        else while ( rcnt > 0 ) `waitfor( EndRead, rw );`
     1963        wcnt = 1;
     1964}
     1965
    15261966\end{cfa}
    15271967\end{lrbox}
    15281968
    1529 \subfloat[Internal Scheduling]{\label{f:BBInt}\usebox\myboxA}
    1530 %\qquad
    1531 \subfloat[External Scheduling]{\label{f:BBExt}\usebox\myboxB}
    1532 \caption{Generic Bounded-Buffer}
    1533 \label{f:GenericBoundedBuffer}
     1969\subfloat[Generic bounded buffer, internal scheduling]{\label{f:BBInt}\usebox\myboxA}
     1970\hspace{3pt}
     1971\vrule
     1972\hspace{3pt}
     1973\subfloat[Readers / writer lock, external scheduling]{\label{f:RWExt}\usebox\myboxB}
     1974
     1975\caption{Internal / external scheduling}
     1976\label{f:InternalExternalScheduling}
    15341977\end{figure}
    15351978
    1536 Figure~\ref{f:BBExt} shows a \CFA bounded-buffer with external scheduling, where producers/consumers detecting a full/empty buffer block and prevent more producers/consumers from entering the monitor until the buffer has a free/empty slot.
    1537 External scheduling is controlled by the @waitfor@ statement, which atomically blocks the calling thread, releases the monitor lock, and restricts the routine calls that can next acquire mutual exclusion.
     1979Figure~\ref{f:BBInt} can be transformed into external scheduling by removing the condition variables and signals/waits, and adding the following lines at the locations of the current @wait@s in @insert@/@remove@, respectively.
     1980\begin{cfa}[aboveskip=2pt,belowskip=1pt]
     1981if ( count == 10 ) `waitfor( remove, buffer )`;       |      if ( count == 0 ) `waitfor( insert, buffer )`;
     1982\end{cfa}
     1983Here, the producers/consumers detects a full/\-empty buffer and prevents more producers/consumers from entering the monitor until there is a free/empty slot in the buffer.
     1984External scheduling is controlled by the @waitfor@ statement, which atomically blocks the calling thread, releases the monitor lock, and restricts the function calls that can next acquire mutual exclusion.
    15381985If the buffer is full, only calls to @remove@ can acquire the buffer, and if the buffer is empty, only calls to @insert@ can acquire the buffer.
    1539 Threads making calls to routines that are currently excluded block outside (externally) of the monitor on a calling queue, versus blocking on condition queues inside the monitor.
    1540 
    1541 Both internal and external scheduling extend to multiple monitors in a natural way.
    1542 \begin{cfa}
    1543 monitor M { `condition e`; ... };
    1544 void foo( M & mutex m1, M & mutex m2 ) {
    1545         ... wait( `e` ); ...                                    $\C{// wait( e, m1, m2 )}$
    1546         ... wait( `e, m1` ); ...
    1547         ... wait( `e, m2` ); ...
    1548 }
    1549 
    1550 void rtn$\(_1\)$( M & mutex m1, M & mutex m2 );
    1551 void rtn$\(_2\)$( M & mutex m1 );
    1552 void bar( M & mutex m1, M & mutex m2 ) {
    1553         ... waitfor( `rtn` ); ...                               $\C{// waitfor( rtn\(_1\), m1, m2 )}$
    1554         ... waitfor( `rtn, m1` ); ...                   $\C{// waitfor( rtn\(_2\), m1 )}$
    1555 }
    1556 \end{cfa}
    1557 For @wait( e )@, the default semantics is to atomically block the signaller and release all acquired mutex types in the parameter list, \ie @wait( e, m1, m2 )@.
    1558 To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @wait( e, m1 )@.
    1559 Wait statically verifies the released monitors are the acquired mutex-parameters so unconditional release is safe.
    1560 Similarly, for @waitfor( rtn, ... )@, the default semantics is to atomically block the acceptor and release all acquired mutex types in the parameter list, \ie @waitfor( rtn, m1, m2 )@.
    1561 To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @waitfor( rtn, m1 )@.
    1562 Waitfor statically verifies the released monitors are the same as the acquired mutex-parameters of the given routine or routine pointer.
    1563 To statically verify the released monitors match with the accepted routine's mutex parameters, the routine (pointer) prototype must be accessible.
    1564 
    1565 Given the ability to release a subset of acquired monitors can result in a \newterm{nested monitor}~\cite{Lister77} deadlock.
    1566 \begin{cfa}
    1567 void foo( M & mutex m1, M & mutex m2 ) {
    1568         ... wait( `e, m1` ); ...                                $\C{// release m1, keeping m2 acquired )}$
    1569 void baz( M & mutex m1, M & mutex m2 ) {        $\C{// must acquire m1 and m2 )}$
    1570         ... signal( `e` ); ...
    1571 \end{cfa}
    1572 The @wait@ only releases @m1@ so the signalling thread cannot acquire both @m1@ and @m2@ to  enter @baz@ to get to the @signal@.
    1573 While deadlock issues can occur with multiple/nesting acquisition, this issue results from the fact that locks, and by extension monitors, are not perfectly composable.
    1574 
    1575 Finally, an important aspect of monitor implementation is barging, \ie can calling threads barge ahead of signalled threads?
    1576 If barging is allowed, synchronization between a singller and signallee is difficult, often requiring multiple unblock/block cycles (looping around a wait rechecking if a condition is met).
    1577 \begin{quote}
    1578 However, we decree that a signal operation be followed immediately by resumption of a waiting program, without possibility of an intervening procedure call from yet a third program.
    1579 It is only in this way that a waiting program has an absolute guarantee that it can acquire the resource just released by the signalling program without any danger that a third program will interpose a monitor entry and seize the resource instead.~\cite[p.~550]{Hoare74}
    1580 \end{quote}
    1581 \CFA scheduling \emph{precludes} barging, which simplifies synchronization among threads in the monitor and increases correctness.
    1582 For example, there are no loops in either bounded buffer solution in Figure~\ref{f:GenericBoundedBuffer}.
    1583 Supporting barging prevention as well as extending internal scheduling to multiple monitors is the main source of complexity in the design and implementation of \CFA concurrency.
    1584 
    1585 
    1586 \subsection{Barging Prevention}
    1587 
    1588 Figure~\ref{f:BargingPrevention} shows \CFA code where bulk acquire adds complexity to the internal-signalling semantics.
    1589 The complexity begins at the end of the inner @mutex@ statement, where the semantics of internal scheduling need to be extended for multiple monitors.
    1590 The problem is that bulk acquire is used in the inner @mutex@ statement where one of the monitors is already acquired.
    1591 When the signalling thread reaches the end of the inner @mutex@ statement, it should transfer ownership of @m1@ and @m2@ to the waiting thread to prevent barging into the outer @mutex@ statement by another thread.
    1592 However, both the signalling and signalled threads still need monitor @m1@.
    1593 
    1594 \begin{figure}
    1595 \newbox\myboxA
    1596 \begin{lrbox}{\myboxA}
    1597 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
    1598 monitor M m1, m2;
    1599 condition c;
    1600 mutex( m1 ) {
    1601         ...
    1602         mutex( m1, m2 ) {
    1603                 ... `wait( c )`; // block and release m1, m2
    1604                 // m1, m2 acquired
    1605         } // $\LstCommentStyle{\color{red}release m2}$
    1606         // m1 acquired
    1607 } // release m1
    1608 \end{cfa}
    1609 \end{lrbox}
    1610 
    1611 \newbox\myboxB
    1612 \begin{lrbox}{\myboxB}
    1613 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
    1614 
    1615 
    1616 mutex( m1 ) {
    1617         ...
    1618         mutex( m1, m2 ) {
    1619                 ... `signal( c )`; ...
    1620                 // m1, m2 acquired
    1621         } // $\LstCommentStyle{\color{red}release m2}$
    1622         // m1 acquired
    1623 } // release m1
    1624 \end{cfa}
    1625 \end{lrbox}
    1626 
    1627 \newbox\myboxC
    1628 \begin{lrbox}{\myboxC}
    1629 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
    1630 
    1631 
    1632 mutex( m1 ) {
    1633         ... `wait( c )`; ...
    1634         // m1 acquired
    1635 } // $\LstCommentStyle{\color{red}release m1}$
    1636 
    1637 
    1638 
    1639 
    1640 \end{cfa}
    1641 \end{lrbox}
    1642 
    1643 \begin{cquote}
    1644 \subfloat[Waiting Thread]{\label{f:WaitingThread}\usebox\myboxA}
    1645 \hspace{2\parindentlnth}
    1646 \subfloat[Signalling Thread]{\label{f:SignallingThread}\usebox\myboxB}
    1647 \hspace{2\parindentlnth}
    1648 \subfloat[Other Waiting Thread]{\label{f:SignallingThread}\usebox\myboxC}
    1649 \end{cquote}
    1650 \caption{Barging Prevention}
    1651 \label{f:BargingPrevention}
    1652 \end{figure}
    1653 
    1654 The obvious solution to the problem of multi-monitor scheduling is to keep ownership of all locks until the last lock is ready to be transferred.
    1655 It can be argued that that moment is when the last lock is no longer needed, because this semantics fits most closely to the behaviour of single-monitor scheduling.
    1656 This solution has the main benefit of transferring ownership of groups of monitors, which simplifies the semantics from multiple objects to a single group of objects, effectively making the existing single-monitor semantic viable by simply changing monitors to monitor groups.
    1657 This solution releases the monitors once every monitor in a group can be released.
    1658 However, since some monitors are never released (\eg the monitor of a thread), this interpretation means a group might never be released.
    1659 A more interesting interpretation is to transfer the group until all its monitors are released, which means the group is not passed further and a thread can retain its locks.
    1660 
    1661 However, listing \ref{f:int-secret} shows this solution can become much more complicated depending on what is executed while secretly holding B at line \ref{line:secret}, while avoiding the need to transfer ownership of a subset of the condition monitors.
    1662 Figure~\ref{f:dependency} shows a slightly different example where a third thread is waiting on monitor @A@, using a different condition variable.
    1663 Because the third thread is signalled when secretly holding @B@, the goal  becomes unreachable.
    1664 Depending on the order of signals (listing \ref{f:dependency} line \ref{line:signal-ab} and \ref{line:signal-a}) two cases can happen:
    1665 
    1666 \begin{comment}
    1667 \paragraph{Case 1: thread $\alpha$ goes first.} In this case, the problem is that monitor @A@ needs to be passed to thread $\beta$ when thread $\alpha$ is done with it.
    1668 \paragraph{Case 2: thread $\beta$ goes first.} In this case, the problem is that monitor @B@ needs to be retained and passed to thread $\alpha$ along with monitor @A@, which can be done directly or possibly using thread $\beta$ as an intermediate.
    1669 \\
    1670 
    1671 Note that ordering is not determined by a race condition but by whether signalled threads are enqueued in FIFO or FILO order.
    1672 However, regardless of the answer, users can move line \ref{line:signal-a} before line \ref{line:signal-ab} and get the reverse effect for listing \ref{f:dependency}.
    1673 
    1674 In both cases, the threads need to be able to distinguish, on a per monitor basis, which ones need to be released and which ones need to be transferred, which means knowing when to release a group becomes complex and inefficient (see next section) and therefore effectively precludes this approach.
    1675 
    1676 
    1677 \subsubsection{Dependency graphs}
    1678 
    1679 \begin{figure}
    1680 \begin{multicols}{3}
    1681 Thread $\alpha$
    1682 \begin{cfa}[numbers=left, firstnumber=1]
    1683 acquire A
    1684         acquire A & B
    1685                 wait A & B
    1686         release A & B
    1687 release A
    1688 \end{cfa}
    1689 \columnbreak
    1690 Thread $\gamma$
    1691 \begin{cfa}[numbers=left, firstnumber=6, escapechar=|]
    1692 acquire A
    1693         acquire A & B
    1694                 |\label{line:signal-ab}|signal A & B
    1695         |\label{line:release-ab}|release A & B
    1696         |\label{line:signal-a}|signal A
    1697 |\label{line:release-a}|release A
    1698 \end{cfa}
    1699 \columnbreak
    1700 Thread $\beta$
    1701 \begin{cfa}[numbers=left, firstnumber=12, escapechar=|]
    1702 acquire A
    1703         wait A
    1704 |\label{line:release-aa}|release A
    1705 \end{cfa}
    1706 \end{multicols}
    1707 \begin{cfa}[caption={Pseudo-code for the three thread example.},label={f:dependency}]
    1708 \end{cfa}
    1709 \begin{center}
    1710 \input{dependency}
    1711 \end{center}
    1712 \caption{Dependency graph of the statements in listing \ref{f:dependency}}
    1713 \label{fig:dependency}
    1714 \end{figure}
    1715 
    1716 In listing \ref{f:int-bulk-cfa}, there is a solution that satisfies both barging prevention and mutual exclusion.
    1717 If ownership of both monitors is transferred to the waiter when the signaller releases @A & B@ and then the waiter transfers back ownership of @A@ back to the signaller when it releases it, then the problem is solved (@B@ is no longer in use at this point).
    1718 Dynamically finding the correct order is therefore the second possible solution.
    1719 The problem is effectively resolving a dependency graph of ownership requirements.
    1720 Here even the simplest of code snippets requires two transfers and has a super-linear complexity.
    1721 This complexity can be seen in listing \ref{f:explosion}, which is just a direct extension to three monitors, requires at least three ownership transfer and has multiple solutions.
    1722 Furthermore, the presence of multiple solutions for ownership transfer can cause deadlock problems if a specific solution is not consistently picked; In the same way that multiple lock acquiring order can cause deadlocks.
    1723 \begin{figure}
    1724 \begin{multicols}{2}
    1725 \begin{cfa}
    1726 acquire A
    1727         acquire B
    1728                 acquire C
    1729                         wait A & B & C
    1730                 release C
    1731         release B
    1732 release A
    1733 \end{cfa}
    1734 
    1735 \columnbreak
    1736 
    1737 \begin{cfa}
    1738 acquire A
    1739         acquire B
    1740                 acquire C
    1741                         signal A & B & C
    1742                 release C
    1743         release B
    1744 release A
    1745 \end{cfa}
    1746 \end{multicols}
    1747 \begin{cfa}[caption={Extension to three monitors of listing \ref{f:int-bulk-cfa}},label={f:explosion}]
    1748 \end{cfa}
    1749 \end{figure}
    1750 
    1751 Given the three threads example in listing \ref{f:dependency}, figure \ref{fig:dependency} shows the corresponding dependency graph that results, where every node is a statement of one of the three threads, and the arrows the dependency of that statement (\eg $\alpha1$ must happen before $\alpha2$).
    1752 The extra challenge is that this dependency graph is effectively post-mortem, but the runtime system needs to be able to build and solve these graphs as the dependencies unfold.
    1753 Resolving dependency graphs being a complex and expensive endeavour, this solution is not the preferred one.
    1754 
    1755 \subsubsection{Partial Signalling} \label{partial-sig}
    1756 \end{comment}
    1757 
    1758 Finally, the solution that is chosen for \CFA is to use partial signalling.
    1759 Again using listing \ref{f:int-bulk-cfa}, the partial signalling solution transfers ownership of monitor @B@ at lines \ref{line:signal1} to the waiter but does not wake the waiting thread since it is still using monitor @A@.
    1760 Only when it reaches line \ref{line:lastRelease} does it actually wake up the waiting thread.
    1761 This solution has the benefit that complexity is encapsulated into only two actions: passing monitors to the next owner when they should be released and conditionally waking threads if all conditions are met.
    1762 This solution has a much simpler implementation than a dependency graph solving algorithms, which is why it was chosen.
    1763 Furthermore, after being fully implemented, this solution does not appear to have any significant downsides.
    1764 
    1765 Using partial signalling, listing \ref{f:dependency} can be solved easily:
    1766 \begin{itemize}
    1767         \item When thread $\gamma$ reaches line \ref{line:release-ab} it transfers monitor @B@ to thread $\alpha$ and continues to hold monitor @A@.
    1768         \item When thread $\gamma$ reaches line \ref{line:release-a}  it transfers monitor @A@ to thread $\beta$  and wakes it up.
    1769         \item When thread $\beta$  reaches line \ref{line:release-aa} it transfers monitor @A@ to thread $\alpha$ and wakes it up.
    1770 \end{itemize}
    1771 
    1772 
    1773 \subsection{Signalling: Now or Later}
     1986Threads calling excluded functions block outside of (external to) the monitor on the calling queue, versus blocking on condition queues inside of (internal to) the monitor.
     1987Figure~\ref{f:RWExt} shows a readers/writer lock written using external scheduling, where a waiting reader detects a writer using the resource and restricts further calls until the writer exits by calling @EndWrite@.
     1988The writer does a similar action for each reader or writer using the resource.
     1989Note, no new calls to @StarRead@/@StartWrite@ may occur when waiting for the call to @EndRead@/@EndWrite@.
     1990External scheduling allows waiting for events from other threads while restricting unrelated events, that would otherwise have to wait on conditions in the monitor.
     1991The mechnaism can be done in terms of control flow, \eg Ada @accept@ or \uC @_Accept@, or in terms of data, \eg Go @select@ on channels.
     1992While both mechanisms have strengths and weaknesses, this project uses the control-flow mechanism to be consistent with other language features.
     1993% Two challenges specific to \CFA for external scheduling are loose object-definitions (see Section~\ref{s:LooseObjectDefinitions}) and multiple-monitor functions (see Section~\ref{s:Multi-MonitorScheduling}).
     1994
     1995Figure~\ref{f:DatingService} shows a dating service demonstrating non-blocking and blocking signalling.
     1996The dating service matches girl and boy threads with matching compatibility codes so they can exchange phone numbers.
     1997A thread blocks until an appropriate partner arrives.
     1998The complexity is exchanging phone numbers in the monitor because of the mutual-exclusion property.
     1999For signal scheduling, the @exchange@ condition is necessary to block the thread finding the match, while the matcher unblocks to take the opposite number, post its phone number, and unblock the partner.
     2000For signal-block scheduling, the implicit urgent-queue replaces the explict @exchange@-condition and @signal_block@ puts the finding thread on the urgent condition and unblocks the matcher.
     2001The dating service is an example of a monitor that cannot be written using external scheduling because it requires knowledge of calling parameters to make scheduling decisions, and parameters of waiting threads are unavailable;
     2002as well, an arriving thread may not find a partner and must wait, which requires a condition variable, and condition variables imply internal scheduling.
     2003Furthermore, barging corrupts the dating service during an exchange because a barger may also match and change the phone numbers, invalidating the previous exchange phone number.
     2004Putting loops around the @wait@s does not correct the problem;
     2005the simple solution must be restructured to account for barging.
    17742006
    17752007\begin{figure}
     
    17822014        int GirlPhNo, BoyPhNo;
    17832015        condition Girls[CCodes], Boys[CCodes];
    1784         condition exchange;
     2016        `condition exchange;`
    17852017};
    17862018int girl( DS & mutex ds, int phNo, int ccode ) {
     
    17882020                wait( Girls[ccode] );
    17892021                GirlPhNo = phNo;
    1790                 exchange.signal();
     2022                `signal( exchange );`
    17912023        } else {
    17922024                GirlPhNo = phNo;
    1793                 signal( Boys[ccode] );
    1794                 exchange.wait();
    1795         } // if
     2025                `signal( Boys[ccode] );`
     2026                `wait( exchange );`
     2027        }
    17962028        return BoyPhNo;
    17972029}
     
    18182050        } else {
    18192051                GirlPhNo = phNo; // make phone number available
    1820                 signal_block( Boys[ccode] ); // restart boy
     2052                `signal_block( Boys[ccode] );` // restart boy
    18212053
    18222054        } // if
     
    18322064\qquad
    18332065\subfloat[\lstinline@signal_block@]{\label{f:DatingSignalBlock}\usebox\myboxB}
    1834 \caption{Dating service. }
    1835 \label{f:Dating service}
     2066\caption{Dating service}
     2067\label{f:DatingService}
    18362068\end{figure}
    18372069
    1838 An important note is that, until now, signalling a monitor was a delayed operation.
    1839 The ownership of the monitor is transferred only when the monitor would have otherwise been released, not at the point of the @signal@ statement.
    1840 However, in some cases, it may be more convenient for users to immediately transfer ownership to the thread that is waiting for cooperation, which is achieved using the @signal_block@ routine.
    1841 
    1842 The example in table \ref{tbl:datingservice} highlights the difference in behaviour.
    1843 As mentioned, @signal@ only transfers ownership once the current critical section exits; this behaviour requires additional synchronization when a two-way handshake is needed.
    1844 To avoid this explicit synchronization, the @condition@ type offers the @signal_block@ routine, which handles the two-way handshake as shown in the example.
    1845 This feature removes the need for a second condition variables and simplifies programming.
    1846 Like every other monitor semantic, @signal_block@ uses barging prevention, which means mutual-exclusion is baton-passed both on the front end and the back end of the call to @signal_block@, meaning no other thread can acquire the monitor either before or after the call.
    1847 
    1848 % ======================================================================
    1849 % ======================================================================
    1850 \section{External scheduling} \label{extsched}
    1851 % ======================================================================
    1852 % ======================================================================
    1853 An alternative to internal scheduling is external scheduling (see Table~\ref{tbl:sched}).
    1854 
    1855 \begin{comment}
    1856 \begin{table}
    1857 \begin{tabular}{|c|c|c|}
    1858 Internal Scheduling & External Scheduling & Go\\
    1859 \hline
    1860 \begin{uC++}[tabsize=3]
    1861 _Monitor Semaphore {
    1862         condition c;
    1863         bool inUse;
    1864 public:
    1865         void P() {
    1866                 if(inUse)
    1867                         wait(c);
    1868                 inUse = true;
    1869         }
    1870         void V() {
    1871                 inUse = false;
    1872                 signal(c);
    1873         }
    1874 }
    1875 \end{uC++}&\begin{uC++}[tabsize=3]
    1876 _Monitor Semaphore {
    1877 
    1878         bool inUse;
    1879 public:
    1880         void P() {
    1881                 if(inUse)
    1882                         _Accept(V);
    1883                 inUse = true;
    1884         }
    1885         void V() {
    1886                 inUse = false;
    1887 
    1888         }
    1889 }
    1890 \end{uC++}&\begin{Go}[tabsize=3]
    1891 type MySem struct {
    1892         inUse bool
    1893         c     chan bool
    1894 }
    1895 
    1896 // acquire
    1897 func (s MySem) P() {
    1898         if s.inUse {
    1899                 select {
    1900                 case <-s.c:
    1901                 }
    1902         }
    1903         s.inUse = true
    1904 }
    1905 
    1906 // release
    1907 func (s MySem) V() {
    1908         s.inUse = false
    1909 
    1910         // This actually deadlocks
    1911         // when single thread
    1912         s.c <- false
    1913 }
    1914 \end{Go}
     2070In summation, for internal scheduling, non-blocking signalling (as in the producer/consumer example) is used when the signaller is providing the cooperation for a waiting thread;
     2071the signaller enters the monitor and changes state, detects a waiting threads that can use the state, performs a non-blocking signal on the condition queue for the waiting thread, and exits the monitor to run concurrently.
     2072The waiter unblocks next from the urgent queue, uses/takes the state, and exits the monitor.
     2073Blocking signal is the reverse, where the waiter is providing the cooperation for the signalling thread;
     2074the signaller enters the monitor, detects a waiting thread providing the necessary state, performs a blocking signal to place it on the urgent queue and unblock the waiter.
     2075The waiter changes state and exits the monitor, and the signaller unblocks next from the urgent queue to use/take the state.
     2076
     2077Both internal and external scheduling extend to multiple monitors in a natural way.
     2078\begin{cquote}
     2079\begin{tabular}{@{}l@{\hspace{3\parindentlnth}}l@{}}
     2080\begin{cfa}
     2081monitor M { `condition e`; ... };
     2082void foo( M & mutex m1, M & mutex m2 ) {
     2083        ... wait( `e` ); ...   // wait( e, m1, m2 )
     2084        ... wait( `e, m1` ); ...
     2085        ... wait( `e, m2` ); ...
     2086}
     2087\end{cfa}
     2088&
     2089\begin{cfa}
     2090void rtn$\(_1\)$( M & mutex m1, M & mutex m2 );
     2091void rtn$\(_2\)$( M & mutex m1 );
     2092void bar( M & mutex m1, M & mutex m2 ) {
     2093        ... waitfor( `rtn` ); ...       // $\LstCommentStyle{waitfor( rtn\(_1\), m1, m2 )}$
     2094        ... waitfor( `rtn, m1` ); ... // $\LstCommentStyle{waitfor( rtn\(_2\), m1 )}$
     2095}
     2096\end{cfa}
    19152097\end{tabular}
    1916 \caption{Different forms of scheduling.}
    1917 \label{tbl:sched}
    1918 \end{table}
    1919 \end{comment}
    1920 
    1921 This method is more constrained and explicit, which helps users reduce the non-deterministic nature of concurrency.
    1922 Indeed, as the following examples demonstrate, external scheduling allows users to wait for events from other threads without the concern of unrelated events occurring.
    1923 External scheduling can generally be done either in terms of control flow (\eg Ada with @accept@, \uC with @_Accept@) or in terms of data (\eg Go with channels).
    1924 Of course, both of these paradigms have their own strengths and weaknesses, but for this project, control-flow semantics was chosen to stay consistent with the rest of the languages semantics.
    1925 Two challenges specific to \CFA arise when trying to add external scheduling with loose object definitions and multiple-monitor routines.
    1926 The previous example shows a simple use @_Accept@ versus @wait@/@signal@ and its advantages.
    1927 Note that while other languages often use @accept@/@select@ as the core external scheduling keyword, \CFA uses @waitfor@ to prevent name collisions with existing socket \textbf{api}s.
    1928 
    1929 For the @P@ member above using internal scheduling, the call to @wait@ only guarantees that @V@ is the last routine to access the monitor, allowing a third routine, say @isInUse()@, acquire mutual exclusion several times while routine @P@ is waiting.
    1930 On the other hand, external scheduling guarantees that while routine @P@ is waiting, no other routine than @V@ can acquire the monitor.
    1931 
    1932 % ======================================================================
    1933 % ======================================================================
    1934 \subsection{Loose Object Definitions}
    1935 % ======================================================================
    1936 % ======================================================================
    1937 In \uC, a monitor class declaration includes an exhaustive list of monitor operations.
    1938 Since \CFA is not object oriented, monitors become both more difficult to implement and less clear for a user:
    1939 
    1940 \begin{cfa}
    1941 monitor A {};
    1942 
    1943 void f(A & mutex a);
    1944 void g(A & mutex a) {
    1945         waitfor(f); // Obvious which f() to wait for
    1946 }
    1947 
    1948 void f(A & mutex a, int); // New different F added in scope
    1949 void h(A & mutex a) {
    1950         waitfor(f); // Less obvious which f() to wait for
    1951 }
    1952 \end{cfa}
    1953 
    1954 Furthermore, external scheduling is an example where implementation constraints become visible from the interface.
    1955 Here is the cfa-code for the entering phase of a monitor:
    1956 \begin{center}
    1957 \begin{tabular}{l}
    1958 \begin{cfa}
    1959         if monitor is free
    1960                 enter
    1961         elif already own the monitor
    1962                 continue
    1963         elif monitor accepts me
    1964                 enter
    1965         else
    1966                 block
    1967 \end{cfa}
    1968 \end{tabular}
    1969 \end{center}
    1970 For the first two conditions, it is easy to implement a check that can evaluate the condition in a few instructions.
    1971 However, a fast check for @monitor accepts me@ is much harder to implement depending on the constraints put on the monitors.
    1972 Indeed, monitors are often expressed as an entry queue and some acceptor queue as in Figure~\ref{fig:ClassicalMonitor}.
     2098\end{cquote}
     2099For @wait( e )@, the default semantics is to atomically block the signaller and release all acquired mutex parameters, \ie @wait( e, m1, m2 )@.
     2100To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @wait( e, m1 )@.
     2101Wait cannot statically verifies the released monitors are the acquired mutex-parameters without disallowing separately compiled helper functions calling @wait@.
     2102While \CC supports bulk locking, @wait@ only accepts a single lock for a condition variable, so bulk locking with condition variables is asymmetric.
     2103Finally, a signaller,
     2104\begin{cfa}
     2105void baz( M & mutex m1, M & mutex m2 ) {
     2106        ... signal( e ); ...
     2107}
     2108\end{cfa}
     2109must have acquired at least the same locks as the waiting thread signalled from a condition queue to allow the locks to be passed, and hence, prevent barging.
     2110
     2111Similarly, for @waitfor( rtn )@, the default semantics is to atomically block the acceptor and release all acquired mutex parameters, \ie @waitfor( rtn, m1, m2 )@.
     2112To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @waitfor( rtn, m1 )@.
     2113@waitfor@ does statically verify the monitor types passed are the same as the acquired mutex-parameters of the given function or function pointer, hence the function (pointer) prototype must be accessible.
     2114% When an overloaded function appears in an @waitfor@ statement, calls to any function with that name are accepted.
     2115% The rationale is that members with the same name should perform a similar function, and therefore, all should be eligible to accept a call.
     2116Overloaded functions can be disambiguated using a cast
     2117\begin{cfa}
     2118void rtn( M & mutex m );
     2119`int` rtn( M & mutex m );
     2120waitfor( (`int` (*)( M & mutex ))rtn, m );
     2121\end{cfa}
     2122
     2123The ability to release a subset of acquired monitors can result in a \newterm{nested monitor}~\cite{Lister77} deadlock.
     2124\begin{cfa}
     2125void foo( M & mutex m1, M & mutex m2 ) {
     2126        ... wait( `e, m1` ); ...                                $\C{// release m1, keeping m2 acquired )}$
     2127void bar( M & mutex m1, M & mutex m2 ) {        $\C{// must acquire m1 and m2 )}$
     2128        ... signal( `e` ); ...
     2129\end{cfa}
     2130The @wait@ only releases @m1@ so the signalling thread cannot acquire @m1@ and @m2@ to enter @bar@ and @signal@ the condition.
     2131While deadlock can occur with multiple/nesting acquisition, this is a consequence of locks, and by extension monitors, not being perfectly composable.
     2132
     2133
     2134
     2135\subsection{\texorpdfstring{Extended \protect\lstinline@waitfor@}{Extended waitfor}}
     2136
     2137Figure~\ref{f:ExtendedWaitfor} shows the extended form of the @waitfor@ statement to conditionally accept one of a group of mutex functions, with an optional statement to be performed \emph{after} the mutex function finishes.
     2138For a @waitfor@ clause to be executed, its @when@ must be true and an outstanding call to its corresponding member(s) must exist.
     2139The \emph{conditional-expression} of a @when@ may call a function, but the function must not block or context switch.
     2140If there are multiple acceptable mutex calls, selection occurs top-to-bottom (prioritized) among the @waitfor@ clauses, whereas some programming languages with similar mechanisms accept nondeterministically for this case, \eg Go \lstinline[morekeywords=select]@select@.
     2141If some accept guards are true and there are no outstanding calls to these members, the acceptor is blocked until a call to one of these members is made.
     2142If there is a @timeout@ clause, it provides an upper bound on waiting.
     2143If all the accept guards are false, the statement does nothing, unless there is a terminating @else@ clause with a true guard, which is executed instead.
     2144Hence, the terminating @else@ clause allows a conditional attempt to accept a call without blocking.
     2145If both @timeout@ and @else@ clause are present, the @else@ must be conditional, or the @timeout@ is never triggered.
     2146There is also a traditional future wait queue (not shown) (\eg Microsoft (@WaitForMultipleObjects@)), to wait for a specified number of future elements in the queue.
    19732147
    19742148\begin{figure}
    19752149\centering
    1976 \subfloat[Classical Monitor] {
    1977 \label{fig:ClassicalMonitor}
    1978 {\resizebox{0.45\textwidth}{!}{\input{monitor}}}
    1979 }% subfloat
    1980 \qquad
    1981 \subfloat[bulk acquire Monitor] {
    1982 \label{fig:BulkMonitor}
    1983 {\resizebox{0.45\textwidth}{!}{\input{ext_monitor}}}
    1984 }% subfloat
    1985 \caption{External Scheduling Monitor}
     2150\begin{cfa}
     2151`when` ( $\emph{conditional-expression}$ )      $\C{// optional guard}$
     2152        waitfor( $\emph{mutex-member-name}$ ) $\emph{statement}$ $\C{// action after call}$
     2153`or` `when` ( $\emph{conditional-expression}$ ) $\C{// any number of functions}$
     2154        waitfor( $\emph{mutex-member-name}$ ) $\emph{statement}$
     2155`or`    ...
     2156`when` ( $\emph{conditional-expression}$ ) $\C{// optional guard}$
     2157        `timeout` $\emph{statement}$ $\C{// optional terminating timeout clause}$
     2158`when` ( $\emph{conditional-expression}$ ) $\C{// optional guard}$
     2159        `else`  $\emph{statement}$ $\C{// optional terminating clause}$
     2160\end{cfa}
     2161\caption{Extended \protect\lstinline@waitfor@}
     2162\label{f:ExtendedWaitfor}
    19862163\end{figure}
    19872164
    1988 There are other alternatives to these pictures, but in the case of the left picture, implementing a fast accept check is relatively easy.
    1989 Restricted to a fixed number of mutex members, N, the accept check reduces to updating a bitmask when the acceptor queue changes, a check that executes in a single instruction even with a fairly large number (\eg 128) of mutex members.
    1990 This approach requires a unique dense ordering of routines with an upper-bound and that ordering must be consistent across translation units.
    1991 For OO languages these constraints are common, since objects only offer adding member routines consistently across translation units via inheritance.
    1992 However, in \CFA users can extend objects with mutex routines that are only visible in certain translation unit.
    1993 This means that establishing a program-wide dense-ordering among mutex routines can only be done in the program linking phase, and still could have issues when using dynamically shared objects.
    1994 
    1995 The alternative is to alter the implementation as in Figure~\ref{fig:BulkMonitor}.
    1996 Here, the mutex routine called is associated with a thread on the entry queue while a list of acceptable routines is kept separate.
    1997 Generating a mask dynamically means that the storage for the mask information can vary between calls to @waitfor@, allowing for more flexibility and extensions.
    1998 Storing an array of accepted routine pointers replaces the single instruction bitmask comparison with dereferencing a pointer followed by a linear search.
    1999 Furthermore, supporting nested external scheduling (\eg listing \ref{f:nest-ext}) may now require additional searches for the @waitfor@ statement to check if a routine is already queued.
     2165Note, a group of conditional @waitfor@ clauses is \emph{not} the same as a group of @if@ statements, \eg:
     2166\begin{cfa}
     2167if ( C1 ) waitfor( mem1 );                       when ( C1 ) waitfor( mem1 );
     2168else if ( C2 ) waitfor( mem2 );         or when ( C2 ) waitfor( mem2 );
     2169\end{cfa}
     2170The left example only accepts @mem1@ if @C1@ is true or only @mem2@ if @C2@ is true.
     2171The right example accepts either @mem1@ or @mem2@ if @C1@ and @C2@ are true.
     2172
     2173An interesting use of @waitfor@ is accepting the @mutex@ destructor to know when an object is deallocated, \eg assume the bounded buffer is restructred from a monitor to a thread with the following @main@.
     2174\begin{cfa}
     2175void main( Buffer(T) & buffer ) with(buffer) {
     2176        for () {
     2177                `waitfor( ^?{}, buffer )` break;
     2178                or when ( count != 20 ) waitfor( insert, buffer ) { ... }
     2179                or when ( count != 0 ) waitfor( remove, buffer ) { ... }
     2180        }
     2181        // clean up
     2182}
     2183\end{cfa}
     2184When the program main deallocates the buffer, it first calls the buffer's destructor, which is accepted, the destructor runs, and the buffer is deallocated.
     2185However, the buffer thread cannot continue after the destructor call because the object is gone;
     2186hence, clean up in @main@ cannot occur, which means destructors for local objects are not run.
     2187To make this useful capability work, the semantics for accepting the destructor is the same as @signal@, \ie the destructor call is placed on urgent and the acceptor continues execution, which ends the loop, cleans up, and the thread terminates.
     2188Then, the destructor caller unblocks from urgent to deallocate the object.
     2189Accepting the destructor is the idiomatic way in \CFA to terminate a thread performing direct communication.
     2190
     2191
     2192\subsection{Bulk Barging Prevention}
     2193
     2194Figure~\ref{f:BulkBargingPrevention} shows \CFA code where bulk acquire adds complexity to the internal-signalling semantics.
     2195The complexity begins at the end of the inner @mutex@ statement, where the semantics of internal scheduling need to be extended for multiple monitors.
     2196The problem is that bulk acquire is used in the inner @mutex@ statement where one of the monitors is already acquired.
     2197When the signalling thread reaches the end of the inner @mutex@ statement, it should transfer ownership of @m1@ and @m2@ to the waiting threads to prevent barging into the outer @mutex@ statement by another thread.
     2198However, both the signalling and waiting threads W1 and W2 need some subset of monitors @m1@ and @m2@.
     2199\begin{cquote}
     2200condition c: (order 1) W2(@m2@), W1(@m1@,@m2@)\ \ \ or\ \ \ (order 2) W1(@m1@,@m2@), W2(@m2@) \\
     2201S: acq. @m1@ $\rightarrow$ acq. @m1,m2@ $\rightarrow$ @signal(c)@ $\rightarrow$ rel. @m2@ $\rightarrow$ pass @m2@ unblock W2 (order 2) $\rightarrow$ rel. @m1@ $\rightarrow$ pass @m1,m2@ unblock W1 \\
     2202\hspace*{2.75in}$\rightarrow$ rel. @m1@ $\rightarrow$ pass @m1,m2@ unblock W1 (order 1)
     2203\end{cquote}
    20002204
    20012205\begin{figure}
    2002 \begin{cfa}[caption={Example of nested external scheduling},label={f:nest-ext}]
    2003 monitor M {};
    2004 void foo( M & mutex a ) {}
    2005 void bar( M & mutex b ) {
    2006         // Nested in the waitfor(bar, c) call
    2007         waitfor(foo, b);
    2008 }
    2009 void baz( M & mutex c ) {
    2010         waitfor(bar, c);
    2011 }
    2012 
    2013 \end{cfa}
     2206\newbox\myboxA
     2207\begin{lrbox}{\myboxA}
     2208\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     2209monitor M m1, m2;
     2210condition c;
     2211mutex( m1 ) { // $\LstCommentStyle{\color{red}outer}$
     2212        ...
     2213        mutex( m1, m2 ) { // $\LstCommentStyle{\color{red}inner}$
     2214                ... `signal( c )`; ...
     2215                // m1, m2 still acquired
     2216        } // $\LstCommentStyle{\color{red}release m2}$
     2217        // m1 acquired
     2218} // release m1
     2219\end{cfa}
     2220\end{lrbox}
     2221
     2222\newbox\myboxB
     2223\begin{lrbox}{\myboxB}
     2224\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     2225
     2226
     2227mutex( m1 ) {
     2228        ...
     2229        mutex( m1, m2 ) {
     2230                ... `wait( c )`; // release m1, m2
     2231                // m1, m2 reacquired
     2232        } // $\LstCommentStyle{\color{red}release m2}$
     2233        // m1 acquired
     2234} // release m1
     2235\end{cfa}
     2236\end{lrbox}
     2237
     2238\newbox\myboxC
     2239\begin{lrbox}{\myboxC}
     2240\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     2241
     2242
     2243mutex( m2 ) {
     2244        ... `wait( c )`; // release m2
     2245        // m2 reacquired
     2246} // $\LstCommentStyle{\color{red}release m2}$
     2247
     2248
     2249
     2250
     2251\end{cfa}
     2252\end{lrbox}
     2253
     2254\begin{cquote}
     2255\subfloat[Signalling Thread (S)]{\label{f:SignallingThread}\usebox\myboxA}
     2256\hspace{3\parindentlnth}
     2257\subfloat[Waiting Thread (W1)]{\label{f:WaitingThread}\usebox\myboxB}
     2258\hspace{2\parindentlnth}
     2259\subfloat[Waiting Thread (W2)]{\label{f:OtherWaitingThread}\usebox\myboxC}
     2260\end{cquote}
     2261\caption{Bulk Barging Prevention}
     2262\label{f:BulkBargingPrevention}
    20142263\end{figure}
    20152264
    2016 Note that in the right picture, tasks need to always keep track of the monitors associated with mutex routines, and the routine mask needs to have both a routine pointer and a set of monitors, as is discussed in the next section.
    2017 These details are omitted from the picture for the sake of simplicity.
    2018 
    2019 At this point, a decision must be made between flexibility and performance.
    2020 Many design decisions in \CFA achieve both flexibility and performance, for example polymorphic routines add significant flexibility but inlining them means the optimizer can easily remove any runtime cost.
    2021 Here, however, the cost of flexibility cannot be trivially removed.
    2022 In the end, the most flexible approach has been chosen since it allows users to write programs that would otherwise be  hard to write.
    2023 This decision is based on the assumption that writing fast but inflexible locks is closer to a solved problem than writing locks that are as flexible as external scheduling in \CFA.
    2024 
    2025 % ======================================================================
    2026 % ======================================================================
     2265One scheduling solution is for the signaller S to keep ownership of all locks until the last lock is ready to be transferred, because this semantics fits most closely to the behaviour of single-monitor scheduling.
     2266However, this solution is inefficient if W2 waited first and can be immediate passed @m2@ when released, while S retains @m1@ until completion of the outer mutex statement.
     2267If W1 waited first, the signaller must retain @m1@ amd @m2@ until completion of the outer mutex statement and then pass both to W1.
     2268% Furthermore, there is an execution sequence where the signaller always finds waiter W2, and hence, waiter W1 starves.
     2269To support this efficient semantics (and prevent barging), the implementation maintains a list of monitors acquired for each blocked thread.
     2270When a signaller exits or waits in a monitor function/statement, the front waiter on urgent is unblocked if all its monitors are released.
     2271Implementing a fast subset check for the necessary released monitors is important.
     2272% The benefit is encapsulating complexity into only two actions: passing monitors to the next owner when they should be released and conditionally waking threads if all conditions are met.
     2273
     2274
     2275\subsection{Loose Object Definitions}
     2276\label{s:LooseObjectDefinitions}
     2277
     2278In an object-oriented programming language, a class includes an exhaustive list of operations.
     2279A new class can add members via static inheritance but the subclass still has an exhaustive list of operations.
     2280(Dynamic member adding, \eg JavaScript~\cite{JavaScript}, is not considered.)
     2281In the object-oriented scenario, the type and all its operators are always present at compilation (even separate compilation), so it is possible to number the operations in a bit mask and use an $O(1)$ compare with a similar bit mask created for the operations specified in a @waitfor@.
     2282
     2283However, in \CFA, monitor functions can be statically added/removed in translation units, making a fast subset check difficult.
     2284\begin{cfa}
     2285        monitor M { ... }; // common type, included in .h file
     2286translation unit 1
     2287        void `f`( M & mutex m );
     2288        void g( M & mutex m ) { waitfor( `f`, m ); }
     2289translation unit 2
     2290        void `f`( M & mutex m ); $\C{// replacing f and g for type M in this translation unit}$
     2291        void `g`( M & mutex m );
     2292        void h( M & mutex m ) { waitfor( `f`, m ) or waitfor( `g`, m ); } $\C{// extending type M in this translation unit}$
     2293\end{cfa}
     2294The @waitfor@ statements in each translation unit cannot form a unique bit-mask because the monitor type does not carry that information.
     2295Hence, function pointers are used to identify the functions listed in the @waitfor@ statement, stored in a variable-sized array.
     2296Then, the same implementation approach used for the urgent stack is used for the calling queue.
     2297Each caller has a list of monitors acquired, and the @waitfor@ statement performs a (usually short) linear search matching functions in the @waitfor@ list with called functions, and then verifying the associated mutex locks can be transfers.
     2298(A possible way to construct a dense mapping is at link or load-time.)
     2299
     2300
    20272301\subsection{Multi-Monitor Scheduling}
    2028 % ======================================================================
    2029 % ======================================================================
    2030 
    2031 External scheduling, like internal scheduling, becomes significantly more complex when introducing multi-monitor syntax.
    2032 Even in the simplest possible case, some new semantics needs to be established:
    2033 \begin{cfa}
    2034 monitor M {};
    2035 
    2036 void f(M & mutex a);
    2037 
    2038 void g(M & mutex b, M & mutex c) {
    2039         waitfor(f); // two monitors M => unknown which to pass to f(M & mutex)
    2040 }
    2041 \end{cfa}
    2042 The obvious solution is to specify the correct monitor as follows:
    2043 
    2044 \begin{cfa}
    2045 monitor M {};
    2046 
    2047 void f(M & mutex a);
    2048 
    2049 void g(M & mutex a, M & mutex b) {
    2050         // wait for call to f with argument b
    2051         waitfor(f, b);
    2052 }
    2053 \end{cfa}
    2054 This syntax is unambiguous.
    2055 Both locks are acquired and kept by @g@.
    2056 When routine @f@ is called, the lock for monitor @b@ is temporarily transferred from @g@ to @f@ (while @g@ still holds lock @a@).
    2057 This behaviour can be extended to the multi-monitor @waitfor@ statement as follows.
    2058 
    2059 \begin{cfa}
    2060 monitor M {};
    2061 
    2062 void f(M & mutex a, M & mutex b);
    2063 
    2064 void g(M & mutex a, M & mutex b) {
    2065         // wait for call to f with arguments a and b
    2066         waitfor(f, a, b);
    2067 }
    2068 \end{cfa}
    2069 
    2070 Note that the set of monitors passed to the @waitfor@ statement must be entirely contained in the set of monitors already acquired in the routine. @waitfor@ used in any other context is undefined behaviour.
    2071 
    2072 An important behaviour to note is when a set of monitors only match partially:
    2073 
    2074 \begin{cfa}
    2075 mutex struct A {};
    2076 
    2077 mutex struct B {};
    2078 
    2079 void g(A & mutex a, B & mutex b) {
    2080         waitfor(f, a, b);
    2081 }
    2082 
    2083 A a1, a2;
    2084 B b;
    2085 
    2086 void foo() {
    2087         g(a1, b); // block on accept
    2088 }
    2089 
    2090 void bar() {
    2091         f(a2, b); // fulfill cooperation
    2092 }
    2093 \end{cfa}
    2094 While the equivalent can happen when using internal scheduling, the fact that conditions are specific to a set of monitors means that users have to use two different condition variables.
    2095 In both cases, partially matching monitor sets does not wakeup the waiting thread.
    2096 It is also important to note that in the case of external scheduling the order of parameters is irrelevant; @waitfor(f,a,b)@ and @waitfor(f,b,a)@ are indistinguishable waiting condition.
    2097 
    2098 % ======================================================================
    2099 % ======================================================================
    2100 \subsection{\protect\lstinline|waitfor| Semantics}
    2101 % ======================================================================
    2102 % ======================================================================
    2103 
    2104 Syntactically, the @waitfor@ statement takes a routine identifier and a set of monitors.
    2105 While the set of monitors can be any list of expressions, the routine name is more restricted because the compiler validates at compile time the validity of the routine type and the parameters used with the @waitfor@ statement.
    2106 It checks that the set of monitors passed in matches the requirements for a routine call.
    2107 Figure~\ref{f:waitfor} shows various usages of the waitfor statement and which are acceptable.
    2108 The choice of the routine type is made ignoring any non-@mutex@ parameter.
    2109 One limitation of the current implementation is that it does not handle overloading, but overloading is possible.
     2302\label{s:Multi-MonitorScheduling}
     2303
     2304External scheduling, like internal scheduling, becomes significantly more complex for multi-monitor semantics.
     2305Even in the simplest case, new semantics need to be established.
     2306\begin{cfa}
     2307monitor M { ... };
     2308void f( M & mutex m1 );
     2309void g( M & mutex m1, M & mutex m2 ) { `waitfor( f );` } $\C{// pass m1 or m2 to f?}$
     2310\end{cfa}
     2311The solution is for the programmer to disambiguate:
     2312\begin{cfa}
     2313waitfor( f, `m2` ); $\C{// wait for call to f with argument m2}$
     2314\end{cfa}
     2315Both locks are acquired by function @g@, so when function @f@ is called, the lock for monitor @m2@ is passed from @g@ to @f@, while @g@ still holds lock @m1@.
     2316This behaviour can be extended to the multi-monitor @waitfor@ statement.
     2317\begin{cfa}
     2318monitor M { ... };
     2319void f( M & mutex m1, M & mutex m2 );
     2320void g( M & mutex m1, M & mutex m2 ) { waitfor( f, `m1, m2` ); $\C{// wait for call to f with arguments m1 and m2}$
     2321\end{cfa}
     2322Again, the set of monitors passed to the @waitfor@ statement must be entirely contained in the set of monitors already acquired by the accepting function.
     2323Also, the order of the monitors in a @waitfor@ statement is unimportant.
     2324
     2325Figure~\ref{f:UnmatchedMutexSets} shows an example where, for internal and external scheduling with multiple monitors, a signalling or accepting thread must match exactly, \ie partial matching results in waiting.
     2326For both examples, the set of monitors is disjoint so unblocking is impossible.
     2327
    21102328\begin{figure}
    2111 \begin{cfa}[caption={Various correct and incorrect uses of the waitfor statement},label={f:waitfor}]
    2112 monitor A{};
    2113 monitor B{};
    2114 
    2115 void f1( A & mutex );
    2116 void f2( A & mutex, B & mutex );
    2117 void f3( A & mutex, int );
    2118 void f4( A & mutex, int );
    2119 void f4( A & mutex, double );
    2120 
    2121 void foo( A & mutex a1, A & mutex a2, B & mutex b1, B & b2 ) {
    2122         A * ap = & a1;
    2123         void (*fp)( A & mutex ) = f1;
    2124 
    2125         waitfor(f1, a1);     // Correct : 1 monitor case
    2126         waitfor(f2, a1, b1); // Correct : 2 monitor case
    2127         waitfor(f3, a1);     // Correct : non-mutex arguments are ignored
    2128         waitfor(f1, *ap);    // Correct : expression as argument
    2129 
    2130         waitfor(f1, a1, b1); // Incorrect : Too many mutex arguments
    2131         waitfor(f2, a1);     // Incorrect : Too few mutex arguments
    2132         waitfor(f2, a1, a2); // Incorrect : Mutex arguments don't match
    2133         waitfor(f1, 1);      // Incorrect : 1 not a mutex argument
    2134         waitfor(f9, a1);     // Incorrect : f9 routine does not exist
    2135         waitfor(*fp, a1 );   // Incorrect : fp not an identifier
    2136         waitfor(f4, a1);     // Incorrect : f4 ambiguous
    2137 
    2138         waitfor(f2, a1, b2); // Undefined behaviour : b2 not mutex
    2139 }
    2140 \end{cfa}
     2329\centering
     2330\begin{lrbox}{\myboxA}
     2331\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     2332monitor M1 {} m11, m12;
     2333monitor M2 {} m2;
     2334condition c;
     2335void f( M1 & mutex m1, M2 & mutex m2 ) {
     2336        signal( c );
     2337}
     2338void g( M1 & mutex m1, M2 & mutex m2 ) {
     2339        wait( c );
     2340}
     2341g( `m11`, m2 ); // block on wait
     2342f( `m12`, m2 ); // cannot fulfil
     2343\end{cfa}
     2344\end{lrbox}
     2345
     2346\begin{lrbox}{\myboxB}
     2347\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     2348monitor M1 {} m11, m12;
     2349monitor M2 {} m2;
     2350
     2351void f( M1 & mutex m1, M2 & mutex m2 ) {
     2352
     2353}
     2354void g( M1 & mutex m1, M2 & mutex m2 ) {
     2355        waitfor( f, m1, m2 );
     2356}
     2357g( `m11`, m2 ); // block on accept
     2358f( `m12`, m2 ); // cannot fulfil
     2359\end{cfa}
     2360\end{lrbox}
     2361\subfloat[Internal scheduling]{\label{f:InternalScheduling}\usebox\myboxA}
     2362\hspace{3pt}
     2363\vrule
     2364\hspace{3pt}
     2365\subfloat[External scheduling]{\label{f:ExternalScheduling}\usebox\myboxB}
     2366\caption{Unmatched \protect\lstinline@mutex@ sets}
     2367\label{f:UnmatchedMutexSets}
    21412368\end{figure}
    21422369
    2143 Finally, for added flexibility, \CFA supports constructing a complex @waitfor@ statement using the @or@, @timeout@ and @else@.
    2144 Indeed, multiple @waitfor@ clauses can be chained together using @or@; this chain forms a single statement that uses baton pass to any routine that fits one of the routine+monitor set passed in.
    2145 To enable users to tell which accepted routine executed, @waitfor@s are followed by a statement (including the null statement @;@) or a compound statement, which is executed after the clause is triggered.
    2146 A @waitfor@ chain can also be followed by a @timeout@, to signify an upper bound on the wait, or an @else@, to signify that the call should be non-blocking, which checks for a matching routine call already arrived and otherwise continues.
    2147 Any and all of these clauses can be preceded by a @when@ condition to dynamically toggle the accept clauses on or off based on some current state.
    2148 Figure~\ref{f:waitfor2} demonstrates several complex masks and some incorrect ones.
     2370
     2371\subsection{\texorpdfstring{\protect\lstinline@mutex@ Threads}{mutex Threads}}
     2372
     2373Threads in \CFA can also be monitors to allow \emph{direct communication} among threads, \ie threads can have mutex functions that are called by other threads.
     2374Hence, all monitor features are available when using threads.
     2375Figure~\ref{f:DirectCommunication} shows a comparison of direct call communication in \CFA with direct channel communication in Go.
     2376(Ada provides a similar mechanism to the \CFA direct communication.)
     2377The program main in both programs communicates directly with the other thread versus indirect communication where two threads interact through a passive monitor.
     2378Both direct and indirection thread communication are valuable tools in structuring concurrent programs.
    21492379
    21502380\begin{figure}
    2151 \lstset{language=CFA,deletedelim=**[is][]{`}{`}}
    2152 \begin{cfa}
    2153 monitor A{};
    2154 
    2155 void f1( A & mutex );
    2156 void f2( A & mutex );
    2157 
    2158 void foo( A & mutex a, bool b, int t ) {
    2159         waitfor(f1, a);                                                 $\C{// Correct : blocking case}$
    2160 
    2161         waitfor(f1, a) {                                                $\C{// Correct : block with statement}$
    2162                 sout | "f1" | endl;
     2381\centering
     2382\begin{lrbox}{\myboxA}
     2383\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     2384
     2385struct Msg { int i, j; };
     2386thread GoRtn { int i;  float f;  Msg m; };
     2387void mem1( GoRtn & mutex gortn, int i ) { gortn.i = i; }
     2388void mem2( GoRtn & mutex gortn, float f ) { gortn.f = f; }
     2389void mem3( GoRtn & mutex gortn, Msg m ) { gortn.m = m; }
     2390void ^?{}( GoRtn & mutex ) {}
     2391
     2392void main( GoRtn & gortn ) with( gortn ) {  // thread starts
     2393
     2394        for () {
     2395
     2396                `waitfor( mem1, gortn )` sout | i;  // wait for calls
     2397                or `waitfor( mem2, gortn )` sout | f;
     2398                or `waitfor( mem3, gortn )` sout | m.i | m.j;
     2399                or `waitfor( ^?{}, gortn )` break;
     2400
    21632401        }
    2164         waitfor(f1, a) {                                                $\C{// Correct : block waiting for f1 or f2}$
    2165                 sout | "f1" | endl;
    2166         } or waitfor(f2, a) {
    2167                 sout | "f2" | endl;
     2402
     2403}
     2404int main() {
     2405        GoRtn gortn; $\C[2.0in]{// start thread}$
     2406        `mem1( gortn, 0 );` $\C{// different calls}\CRT$
     2407        `mem2( gortn, 2.5 );`
     2408        `mem3( gortn, (Msg){1, 2} );`
     2409
     2410
     2411} // wait for completion
     2412\end{cfa}
     2413\end{lrbox}
     2414
     2415\begin{lrbox}{\myboxB}
     2416\begin{Go}[aboveskip=0pt,belowskip=0pt]
     2417func main() {
     2418        type Msg struct{ i, j int }
     2419
     2420        ch1 := make( chan int )
     2421        ch2 := make( chan float32 )
     2422        ch3 := make( chan Msg )
     2423        hand := make( chan string )
     2424        shake := make( chan string )
     2425        gortn := func() { $\C[1.5in]{// thread starts}$
     2426                var i int;  var f float32;  var m Msg
     2427                L: for {
     2428                        select { $\C{// wait for messages}$
     2429                          case `i = <- ch1`: fmt.Println( i )
     2430                          case `f = <- ch2`: fmt.Println( f )
     2431                          case `m = <- ch3`: fmt.Println( m )
     2432                          case `<- hand`: break L $\C{// sentinel}$
     2433                        }
     2434                }
     2435                `shake <- "SHAKE"` $\C{// completion}$
    21682436        }
    2169         waitfor(f1, a); or else;                                $\C{// Correct : non-blocking case}$
    2170 
    2171         waitfor(f1, a) {                                                $\C{// Correct : non-blocking case}$
    2172                 sout | "blocked" | endl;
    2173         } or else {
    2174                 sout | "didn't block" | endl;
     2437
     2438        go gortn() $\C{// start thread}$
     2439        `ch1 <- 0` $\C{// different messages}$
     2440        `ch2 <- 2.5`
     2441        `ch3 <- Msg{1, 2}`
     2442        `hand <- "HAND"` $\C{// sentinel value}$
     2443        `<- shake` $\C{// wait for completion}\CRT$
     2444}
     2445\end{Go}
     2446\end{lrbox}
     2447
     2448\subfloat[\CFA]{\label{f:CFAwaitfor}\usebox\myboxA}
     2449\hspace{3pt}
     2450\vrule
     2451\hspace{3pt}
     2452\subfloat[Go]{\label{f:Gochannel}\usebox\myboxB}
     2453\caption{Direct communication}
     2454\label{f:DirectCommunication}
     2455\end{figure}
     2456
     2457\begin{comment}
     2458The following shows an example of two threads directly calling each other and accepting calls from each other in a cycle.
     2459\begin{cfa}
     2460\end{cfa}
     2461\vspace{-0.8\baselineskip}
     2462\begin{cquote}
     2463\begin{tabular}{@{}l@{\hspace{3\parindentlnth}}l@{}}
     2464\begin{cfa}
     2465thread Ping {} pi;
     2466void ping( Ping & mutex ) {}
     2467void main( Ping & pi ) {
     2468        for ( 10 ) {
     2469                `waitfor( ping, pi );`
     2470                `pong( po );`
    21752471        }
    2176         waitfor(f1, a) {                                                $\C{// Correct : block at most 10 seconds}$
    2177                 sout | "blocked" | endl;
    2178         } or timeout( 10`s) {
    2179                 sout | "didn't block" | endl;
     2472}
     2473int main() {}
     2474\end{cfa}
     2475&
     2476\begin{cfa}
     2477thread Pong {} po;
     2478void pong( Pong & mutex ) {}
     2479void main( Pong & po ) {
     2480        for ( 10 ) {
     2481                `ping( pi );`
     2482                `waitfor( pong, po );`
    21802483        }
    2181         // Correct : block only if b == true if b == false, don't even make the call
    2182         when(b) waitfor(f1, a);
    2183 
    2184         // Correct : block only if b == true if b == false, make non-blocking call
    2185         waitfor(f1, a); or when(!b) else;
    2186 
    2187         // Correct : block only of t > 1
    2188         waitfor(f1, a); or when(t > 1) timeout(t); or else;
    2189 
    2190         // Incorrect : timeout clause is dead code
    2191         waitfor(f1, a); or timeout(t); or else;
    2192 
    2193         // Incorrect : order must be waitfor [or waitfor... [or timeout] [or else]]
    2194         timeout(t); or waitfor(f1, a); or else;
    2195 }
    2196 \end{cfa}
    2197 \caption{Correct and incorrect uses of the or, else, and timeout clause around a waitfor statement}
    2198 \label{f:waitfor2}
    2199 \end{figure}
    2200 
    2201 % ======================================================================
    2202 % ======================================================================
    2203 \subsection{Waiting For The Destructor}
    2204 % ======================================================================
    2205 % ======================================================================
    2206 An interesting use for the @waitfor@ statement is destructor semantics.
    2207 Indeed, the @waitfor@ statement can accept any @mutex@ routine, which includes the destructor (see section \ref{data}).
    2208 However, with the semantics discussed until now, waiting for the destructor does not make any sense, since using an object after its destructor is called is undefined behaviour.
    2209 The simplest approach is to disallow @waitfor@ on a destructor.
    2210 However, a more expressive approach is to flip ordering of execution when waiting for the destructor, meaning that waiting for the destructor allows the destructor to run after the current @mutex@ routine, similarly to how a condition is signalled.
    2211 \begin{figure}
    2212 \begin{cfa}[caption={Example of an executor which executes action in series until the destructor is called.},label={f:dtor-order}]
    2213 monitor Executer {};
    2214 struct  Action;
    2215 
    2216 void ^?{}   (Executer & mutex this);
    2217 void execute(Executer & mutex this, const Action & );
    2218 void run    (Executer & mutex this) {
    2219         while(true) {
    2220                    waitfor(execute, this);
    2221                 or waitfor(^?{}   , this) {
    2222                         break;
    2223                 }
    2224         }
    2225 }
    2226 \end{cfa}
    2227 \end{figure}
    2228 For example, listing \ref{f:dtor-order} shows an example of an executor with an infinite loop, which waits for the destructor to break out of this loop.
    2229 Switching the semantic meaning introduces an idiomatic way to terminate a task and/or wait for its termination via destruction.
    2230 
    2231 
    2232 % ######     #    ######     #    #       #       ####### #       ###  #####  #     #
    2233 % #     #   # #   #     #   # #   #       #       #       #        #  #     # ##   ##
    2234 % #     #  #   #  #     #  #   #  #       #       #       #        #  #       # # # #
    2235 % ######  #     # ######  #     # #       #       #####   #        #   #####  #  #  #
    2236 % #       ####### #   #   ####### #       #       #       #        #        # #     #
    2237 % #       #     # #    #  #     # #       #       #       #        #  #     # #     #
    2238 % #       #     # #     # #     # ####### ####### ####### ####### ###  #####  #     #
    2239 \section{Parallelism}
    2240 Historically, computer performance was about processor speeds and instruction counts.
    2241 However, with heat dissipation being a direct consequence of speed increase, parallelism has become the new source for increased performance~\cite{Sutter05, Sutter05b}.
    2242 In this decade, it is no longer reasonable to create a high-performance application without caring about parallelism.
    2243 Indeed, parallelism is an important aspect of performance and more specifically throughput and hardware utilization.
    2244 The lowest-level approach of parallelism is to use \textbf{kthread} in combination with semantics like @fork@, @join@, \etc.
    2245 However, since these have significant costs and limitations, \textbf{kthread} are now mostly used as an implementation tool rather than a user oriented one.
    2246 There are several alternatives to solve these issues that all have strengths and weaknesses.
    2247 While there are many variations of the presented paradigms, most of these variations do not actually change the guarantees or the semantics, they simply move costs in order to achieve better performance for certain workloads.
    2248 
    2249 \section{Paradigms}
    2250 \subsection{User-Level Threads}
    2251 A direct improvement on the \textbf{kthread} approach is to use \textbf{uthread}.
    2252 These threads offer most of the same features that the operating system already provides but can be used on a much larger scale.
    2253 This approach is the most powerful solution as it allows all the features of multithreading, while removing several of the more expensive costs of kernel threads.
    2254 The downside is that almost none of the low-level threading problems are hidden; users still have to think about data races, deadlocks and synchronization issues.
    2255 These issues can be somewhat alleviated by a concurrency toolkit with strong guarantees, but the parallelism toolkit offers very little to reduce complexity in itself.
    2256 
    2257 Examples of languages that support \textbf{uthread} are Erlang~\cite{Erlang} and \uC~\cite{uC++book}.
    2258 
    2259 \subsection{Fibers : User-Level Threads Without Preemption} \label{fibers}
    2260 A popular variant of \textbf{uthread} is what is often referred to as \textbf{fiber}.
    2261 However, \textbf{fiber} do not present meaningful semantic differences with \textbf{uthread}.
    2262 The significant difference between \textbf{uthread} and \textbf{fiber} is the lack of \textbf{preemption} in the latter.
    2263 Advocates of \textbf{fiber} list their high performance and ease of implementation as major strengths, but the performance difference between \textbf{uthread} and \textbf{fiber} is controversial, and the ease of implementation, while true, is a weak argument in the context of language design.
    2264 Therefore this proposal largely ignores fibers.
    2265 
    2266 An example of a language that uses fibers is Go~\cite{Go}
    2267 
    2268 \subsection{Jobs and Thread Pools}
    2269 An approach on the opposite end of the spectrum is to base parallelism on \textbf{pool}.
    2270 Indeed, \textbf{pool} offer limited flexibility but at the benefit of a simpler user interface.
    2271 In \textbf{pool} based systems, users express parallelism as units of work, called jobs, and a dependency graph (either explicit or implicit) that ties them together.
    2272 This approach means users need not worry about concurrency but significantly limit the interaction that can occur among jobs.
    2273 Indeed, any \textbf{job} that blocks also block the underlying worker, which effectively means the CPU utilization, and therefore throughput, suffers noticeably.
    2274 It can be argued that a solution to this problem is to use more workers than available cores.
    2275 However, unless the number of jobs and the number of workers are comparable, having a significant number of blocked jobs always results in idles cores.
    2276 
    2277 The gold standard of this implementation is Intel's TBB library~\cite{TBB}.
    2278 
    2279 \subsection{Paradigm Performance}
    2280 While the choice between the three paradigms listed above may have significant performance implications, it is difficult to pin down the performance implications of choosing a model at the language level.
    2281 Indeed, in many situations one of these paradigms may show better performance but it all strongly depends on the workload.
    2282 Having a large amount of mostly independent units of work to execute almost guarantees equivalent performance across paradigms and that the \textbf{pool}-based system has the best efficiency thanks to the lower memory overhead (\ie no thread stack per job).
    2283 However, interactions among jobs can easily exacerbate contention.
    2284 User-level threads allow fine-grain context switching, which results in better resource utilization, but a context switch is more expensive and the extra control means users need to tweak more variables to get the desired performance.
    2285 Finally, if the units of uninterrupted work are large, enough the paradigm choice is largely amortized by the actual work done.
    2286 
    2287 \section{The \protect\CFA\ Kernel : Processors, Clusters and Threads}\label{kernel}
    2288 A \textbf{cfacluster} is a group of \textbf{kthread} executed in isolation. \textbf{uthread} are scheduled on the \textbf{kthread} of a given \textbf{cfacluster}, allowing organization between \textbf{uthread} and \textbf{kthread}.
    2289 It is important that \textbf{kthread} belonging to a same \textbf{cfacluster} have homogeneous settings, otherwise migrating a \textbf{uthread} from one \textbf{kthread} to the other can cause issues.
    2290 A \textbf{cfacluster} also offers a pluggable scheduler that can optimize the workload generated by the \textbf{uthread}.
    2291 
    2292 \textbf{cfacluster} have not been fully implemented in the context of this paper.
    2293 Currently \CFA only supports one \textbf{cfacluster}, the initial one.
    2294 
    2295 \subsection{Future Work: Machine Setup}\label{machine}
    2296 While this was not done in the context of this paper, another important aspect of clusters is affinity.
    2297 While many common desktop and laptop PCs have homogeneous CPUs, other devices often have more heterogeneous setups.
    2298 For example, a system using \textbf{numa} configurations may benefit from users being able to tie clusters and/or kernel threads to certain CPU cores.
    2299 OS support for CPU affinity is now common~\cite{affinityLinux, affinityWindows, affinityFreebsd, affinityNetbsd, affinityMacosx}, which means it is both possible and desirable for \CFA to offer an abstraction mechanism for portable CPU affinity.
    2300 
    2301 \subsection{Paradigms}\label{cfaparadigms}
    2302 Given these building blocks, it is possible to reproduce all three of the popular paradigms.
    2303 Indeed, \textbf{uthread} is the default paradigm in \CFA.
    2304 However, disabling \textbf{preemption} on a cluster means threads effectively become fibers.
    2305 Since several \textbf{cfacluster} with different scheduling policy can coexist in the same application, this allows \textbf{fiber} and \textbf{uthread} to coexist in the runtime of an application.
    2306 Finally, it is possible to build executors for thread pools from \textbf{uthread} or \textbf{fiber}, which includes specialized jobs like actors~\cite{Actors}.
    2307 
    2308 
    2309 
    2310 \section{Behind the Scenes}
    2311 There are several challenges specific to \CFA when implementing concurrency.
    2312 These challenges are a direct result of bulk acquire and loose object definitions.
    2313 These two constraints are the root cause of most design decisions in the implementation.
    2314 Furthermore, to avoid contention from dynamically allocating memory in a concurrent environment, the internal-scheduling design is (almost) entirely free of mallocs.
    2315 This approach avoids the chicken and egg problem~\cite{Chicken} of having a memory allocator that relies on the threading system and a threading system that relies on the runtime.
    2316 This extra goal means that memory management is a constant concern in the design of the system.
    2317 
    2318 The main memory concern for concurrency is queues.
    2319 All blocking operations are made by parking threads onto queues and all queues are designed with intrusive nodes, where each node has pre-allocated link fields for chaining, to avoid the need for memory allocation.
    2320 Since several concurrency operations can use an unbound amount of memory (depending on bulk acquire), statically defining information in the intrusive fields of threads is insufficient.The only way to use a variable amount of memory without requiring memory allocation is to pre-allocate large buffers of memory eagerly and store the information in these buffers.
    2321 Conveniently, the call stack fits that description and is easy to use, which is why it is used heavily in the implementation of internal scheduling, particularly variable-length arrays.
    2322 Since stack allocation is based on scopes, the first step of the implementation is to identify the scopes that are available to store the information, and which of these can have a variable-length array.
    2323 The threads and the condition both have a fixed amount of memory, while @mutex@ routines and blocking calls allow for an unbound amount, within the stack size.
    2324 
    2325 Note that since the major contributions of this paper are extending monitor semantics to bulk acquire and loose object definitions, any challenges that are not resulting of these characteristics of \CFA are considered as solved problems and therefore not discussed.
    2326 
    2327 % ======================================================================
    2328 % ======================================================================
    2329 \section{Mutex Routines}
    2330 % ======================================================================
    2331 % ======================================================================
    2332 
    2333 The first step towards the monitor implementation is simple @mutex@ routines.
    2334 In the single monitor case, mutual-exclusion is done using the entry/exit procedure in listing \ref{f:entry1}.
    2335 The entry/exit procedures do not have to be extended to support multiple monitors.
    2336 Indeed it is sufficient to enter/leave monitors one-by-one as long as the order is correct to prevent deadlock~\cite{Havender68}.
    2337 In \CFA, ordering of monitor acquisition relies on memory ordering.
    2338 This approach is sufficient because all objects are guaranteed to have distinct non-overlapping memory layouts and mutual-exclusion for a monitor is only defined for its lifetime, meaning that destroying a monitor while it is acquired is undefined behaviour.
    2339 When a mutex call is made, the concerned monitors are aggregated into a variable-length pointer array and sorted based on pointer values.
    2340 This array persists for the entire duration of the mutual-exclusion and its ordering reused extensively.
    2341 \begin{figure}
    2342 \begin{multicols}{2}
    2343 Entry
    2344 \begin{cfa}
    2345 if monitor is free
    2346         enter
    2347 elif already own the monitor
    2348         continue
    2349 else
    2350         block
    2351 increment recursions
    2352 \end{cfa}
    2353 \columnbreak
    2354 Exit
    2355 \begin{cfa}
    2356 decrement recursion
    2357 if recursion == 0
    2358         if entry queue not empty
    2359                 wake-up thread
    2360 \end{cfa}
    2361 \end{multicols}
    2362 \begin{cfa}[caption={Initial entry and exit routine for monitors},label={f:entry1}]
    2363 \end{cfa}
    2364 \end{figure}
    2365 
    2366 \subsection{Details: Interaction with polymorphism}
    2367 Depending on the choice of semantics for when monitor locks are acquired, interaction between monitors and \CFA's concept of polymorphism can be more complex to support.
    2368 However, it is shown that entry-point locking solves most of the issues.
    2369 
    2370 First of all, interaction between @otype@ polymorphism (see Section~\ref{s:ParametricPolymorphism}) and monitors is impossible since monitors do not support copying.
    2371 Therefore, the main question is how to support @dtype@ polymorphism.
    2372 It is important to present the difference between the two acquiring options: \textbf{callsite-locking} and entry-point locking, \ie acquiring the monitors before making a mutex routine-call or as the first operation of the mutex routine-call.
    2373 For example:
     2484}
     2485
     2486\end{cfa}
     2487\end{tabular}
     2488\end{cquote}
     2489% \lstMakeShortInline@%
     2490% \caption{Threads ping/pong using external scheduling}
     2491% \label{f:pingpong}
     2492% \end{figure}
     2493Note, the ping/pong threads are globally declared, @pi@/@po@, and hence, start (and possibly complete) before the program main starts.
     2494\end{comment}
     2495
     2496
     2497\subsection{Execution Properties}
     2498
     2499Table~\ref{t:ObjectPropertyComposition} shows how the \CFA high-level constructs cover 3 fundamental execution properties: thread, stateful function, and mutual exclusion.
     2500Case 1 is a basic object, with none of the new execution properties.
     2501Case 2 allows @mutex@ calls to Case 1 to protect shared data.
     2502Case 3 allows stateful functions to suspend/resume but restricts operations because the state is stackless.
     2503Case 4 allows @mutex@ calls to Case 3 to protect shared data.
     2504Cases 5 and 6 are the same as 3 and 4 without restriction because the state is stackful.
     2505Cases 7 and 8 are rejected because a thread cannot execute without a stackful state in a preemptive environment when context switching from the signal handler.
     2506Cases 9 and 10 have a stackful thread without and with @mutex@ calls.
     2507For situations where threads do not require direct communication, case 9 provides faster creation/destruction by eliminating @mutex@ setup.
     2508
    23742509\begin{table}
    2375 \begin{center}
    2376 \begin{tabular}{|c|c|c|}
    2377 Mutex & \textbf{callsite-locking} & \textbf{entry-point-locking} \\
    2378 call & cfa-code & cfa-code \\
     2510\caption{Object property composition}
     2511\centering
     2512\label{t:ObjectPropertyComposition}
     2513\renewcommand{\arraystretch}{1.25}
     2514%\setlength{\tabcolsep}{5pt}
     2515\begin{tabular}{c|c||l|l}
     2516\multicolumn{2}{c||}{object properties} & \multicolumn{2}{c}{mutual exclusion} \\
    23792517\hline
    2380 \begin{cfa}[tabsize=3]
    2381 void foo(monitor& mutex a){
    2382 
    2383         // Do Work
    2384         //...
    2385 
    2386 }
    2387 
    2388 void main() {
    2389         monitor a;
    2390 
    2391         foo(a);
    2392 
    2393 }
    2394 \end{cfa} & \begin{cfa}[tabsize=3]
    2395 foo(& a) {
    2396 
    2397         // Do Work
    2398         //...
    2399 
    2400 }
    2401 
    2402 main() {
    2403         monitor a;
    2404         acquire(a);
    2405         foo(a);
    2406         release(a);
    2407 }
    2408 \end{cfa} & \begin{cfa}[tabsize=3]
    2409 foo(& a) {
    2410         acquire(a);
    2411         // Do Work
    2412         //...
    2413         release(a);
    2414 }
    2415 
    2416 main() {
    2417         monitor a;
    2418 
    2419         foo(a);
    2420 
    2421 }
    2422 \end{cfa}
    2423 \end{tabular}
    2424 \end{center}
    2425 \caption{Call-site vs entry-point locking for mutex calls}
    2426 \label{tbl:locking-site}
    2427 \end{table}
    2428 
    2429 Note the @mutex@ keyword relies on the type system, which means that in cases where a generic monitor-routine is desired, writing the mutex routine is possible with the proper trait, \eg:
    2430 \begin{cfa}
    2431 // Incorrect: T may not be monitor
    2432 forall(dtype T)
    2433 void foo(T * mutex t);
    2434 
    2435 // Correct: this routine only works on monitors (any monitor)
    2436 forall(dtype T | is_monitor(T))
    2437 void bar(T * mutex t));
    2438 \end{cfa}
    2439 
    2440 Both entry point and \textbf{callsite-locking} are feasible implementations.
    2441 The current \CFA implementation uses entry-point locking because it requires less work when using \textbf{raii}, effectively transferring the burden of implementation to object construction/destruction.
    2442 It is harder to use \textbf{raii} for call-site locking, as it does not necessarily have an existing scope that matches exactly the scope of the mutual exclusion, \ie the routine body.
    2443 For example, the monitor call can appear in the middle of an expression.
    2444 Furthermore, entry-point locking requires less code generation since any useful routine is called multiple times but there is only one entry point for many call sites.
    2445 
    2446 % ======================================================================
    2447 % ======================================================================
    2448 \section{Threading} \label{impl:thread}
    2449 % ======================================================================
    2450 % ======================================================================
    2451 
    2452 Figure \ref{fig:system1} shows a high-level picture if the \CFA runtime system in regards to concurrency.
    2453 Each component of the picture is explained in detail in the flowing sections.
    2454 
    2455 \begin{figure}
    2456 \begin{center}
    2457 {\resizebox{\textwidth}{!}{\input{system.pstex_t}}}
    2458 \end{center}
    2459 \caption{Overview of the entire system}
    2460 \label{fig:system1}
    2461 \end{figure}
    2462 
    2463 \subsection{Processors}
    2464 Parallelism in \CFA is built around using processors to specify how much parallelism is desired. \CFA processors are object wrappers around kernel threads, specifically @pthread@s in the current implementation of \CFA.
    2465 Indeed, any parallelism must go through operating-system libraries.
    2466 However, \textbf{uthread} are still the main source of concurrency, processors are simply the underlying source of parallelism.
    2467 Indeed, processor \textbf{kthread} simply fetch a \textbf{uthread} from the scheduler and run it; they are effectively executers for user-threads.
    2468 The main benefit of this approach is that it offers a well-defined boundary between kernel code and user code, for example, kernel thread quiescing, scheduling and interrupt handling.
    2469 Processors internally use coroutines to take advantage of the existing context-switching semantics.
    2470 
    2471 \subsection{Stack Management}
    2472 One of the challenges of this system is to reduce the footprint as much as possible.
    2473 Specifically, all @pthread@s created also have a stack created with them, which should be used as much as possible.
    2474 Normally, coroutines also create their own stack to run on, however, in the case of the coroutines used for processors, these coroutines run directly on the \textbf{kthread} stack, effectively stealing the processor stack.
    2475 The exception to this rule is the Main Processor, \ie the initial \textbf{kthread} that is given to any program.
    2476 In order to respect C user expectations, the stack of the initial kernel thread, the main stack of the program, is used by the main user thread rather than the main processor, which can grow very large.
    2477 
    2478 \subsection{Context Switching}
    2479 As mentioned in section \ref{coroutine}, coroutines are a stepping stone for implementing threading, because they share the same mechanism for context-switching between different stacks.
    2480 To improve performance and simplicity, context-switching is implemented using the following assumption: all context-switches happen inside a specific routine call.
    2481 This assumption means that the context-switch only has to copy the callee-saved registers onto the stack and then switch the stack registers with the ones of the target coroutine/thread.
    2482 Note that the instruction pointer can be left untouched since the context-switch is always inside the same routine
    2483 Threads, however, do not context-switch between each other directly.
    2484 They context-switch to the scheduler.
    2485 This method is called a 2-step context-switch and has the advantage of having a clear distinction between user code and the kernel where scheduling and other system operations happen.
    2486 Obviously, this doubles the context-switch cost because threads must context-switch to an intermediate stack.
    2487 The alternative 1-step context-switch uses the stack of the ``from'' thread to schedule and then context-switches directly to the ``to'' thread.
    2488 However, the performance of the 2-step context-switch is still superior to a @pthread_yield@ (see section \ref{results}).
    2489 Additionally, for users in need for optimal performance, it is important to note that having a 2-step context-switch as the default does not prevent \CFA from offering a 1-step context-switch (akin to the Microsoft @SwitchToFiber@~\cite{switchToWindows} routine).
    2490 This option is not currently present in \CFA, but the changes required to add it are strictly additive.
    2491 
    2492 \subsection{Preemption} \label{preemption}
    2493 Finally, an important aspect for any complete threading system is preemption.
    2494 As mentioned in section \ref{basics}, preemption introduces an extra degree of uncertainty, which enables users to have multiple threads interleave transparently, rather than having to cooperate among threads for proper scheduling and CPU distribution.
    2495 Indeed, preemption is desirable because it adds a degree of isolation among threads.
    2496 In a fully cooperative system, any thread that runs a long loop can starve other threads, while in a preemptive system, starvation can still occur but it does not rely on every thread having to yield or block on a regular basis, which reduces significantly a programmer burden.
    2497 Obviously, preemption is not optimal for every workload.
    2498 However any preemptive system can become a cooperative system by making the time slices extremely large.
    2499 Therefore, \CFA uses a preemptive threading system.
    2500 
    2501 Preemption in \CFA\footnote{Note that the implementation of preemption is strongly tied with the underlying threading system.
    2502 For this reason, only the Linux implementation is cover, \CFA does not run on Windows at the time of writting} is based on kernel timers, which are used to run a discrete-event simulation.
    2503 Every processor keeps track of the current time and registers an expiration time with the preemption system.
    2504 When the preemption system receives a change in preemption, it inserts the time in a sorted order and sets a kernel timer for the closest one, effectively stepping through preemption events on each signal sent by the timer.
    2505 These timers use the Linux signal {\tt SIGALRM}, which is delivered to the process rather than the kernel-thread.
    2506 This results in an implementation problem, because when delivering signals to a process, the kernel can deliver the signal to any kernel thread for which the signal is not blocked, \ie:
    2507 \begin{quote}
    2508 A process-directed signal may be delivered to any one of the threads that does not currently have the signal blocked.
    2509 If more than one of the threads has the signal unblocked, then the kernel chooses an arbitrary thread to which to deliver the signal.
    2510 SIGNAL(7) - Linux Programmer's Manual
    2511 \end{quote}
    2512 For the sake of simplicity, and in order to prevent the case of having two threads receiving alarms simultaneously, \CFA programs block the {\tt SIGALRM} signal on every kernel thread except one.
    2513 
    2514 Now because of how involuntary context-switches are handled, the kernel thread handling {\tt SIGALRM} cannot also be a processor thread.
    2515 Hence, involuntary context-switching is done by sending signal {\tt SIGUSR1} to the corresponding proces\-sor and having the thread yield from inside the signal handler.
    2516 This approach effectively context-switches away from the signal handler back to the kernel and the signal handler frame is eventually unwound when the thread is scheduled again.
    2517 As a result, a signal handler can start on one kernel thread and terminate on a second kernel thread (but the same user thread).
    2518 It is important to note that signal handlers save and restore signal masks because user-thread migration can cause a signal mask to migrate from one kernel thread to another.
    2519 This behaviour is only a problem if all kernel threads, among which a user thread can migrate, differ in terms of signal masks\footnote{Sadly, official POSIX documentation is silent on what distinguishes ``async-signal-safe'' routines from other routines}.
    2520 However, since the kernel thread handling preemption requires a different signal mask, executing user threads on the kernel-alarm thread can cause deadlocks.
    2521 For this reason, the alarm thread is in a tight loop around a system call to @sigwaitinfo@, requiring very little CPU time for preemption.
    2522 One final detail about the alarm thread is how to wake it when additional communication is required (\eg on thread termination).
    2523 This unblocking is also done using {\tt SIGALRM}, but sent through the @pthread_sigqueue@.
    2524 Indeed, @sigwait@ can differentiate signals sent from @pthread_sigqueue@ from signals sent from alarms or the kernel.
    2525 
    2526 \subsection{Scheduler}
    2527 Finally, an aspect that was not mentioned yet is the scheduling algorithm.
    2528 Currently, the \CFA scheduler uses a single ready queue for all processors, which is the simplest approach to scheduling.
    2529 Further discussion on scheduling is present in section \ref{futur:sched}.
    2530 
    2531 % ======================================================================
    2532 % ======================================================================
    2533 \section{Internal Scheduling} \label{impl:intsched}
    2534 % ======================================================================
    2535 % ======================================================================
    2536 The following figure is the traditional illustration of a monitor (repeated from page~\pageref{fig:ClassicalMonitor} for convenience):
    2537 
    2538 \begin{figure}
    2539 \begin{center}
    2540 {\resizebox{0.4\textwidth}{!}{\input{monitor}}}
    2541 \end{center}
    2542 \caption{Traditional illustration of a monitor}
    2543 \end{figure}
    2544 
    2545 This picture has several components, the two most important being the entry queue and the AS-stack.
    2546 The entry queue is an (almost) FIFO list where threads waiting to enter are parked, while the acceptor/signaller (AS) stack is a FILO list used for threads that have been signalled or otherwise marked as running next.
    2547 
    2548 For \CFA, this picture does not have support for blocking multiple monitors on a single condition.
    2549 To support bulk acquire two changes to this picture are required.
    2550 First, it is no longer helpful to attach the condition to \emph{a single} monitor.
    2551 Secondly, the thread waiting on the condition has to be separated across multiple monitors, seen in figure \ref{fig:monitor_cfa}.
    2552 
    2553 \begin{figure}
    2554 \begin{center}
    2555 {\resizebox{0.8\textwidth}{!}{\input{int_monitor}}}
    2556 \end{center}
    2557 \caption{Illustration of \CFA Monitor}
    2558 \label{fig:monitor_cfa}
    2559 \end{figure}
    2560 
    2561 This picture and the proper entry and leave algorithms (see listing \ref{f:entry2}) is the fundamental implementation of internal scheduling.
    2562 Note that when a thread is moved from the condition to the AS-stack, it is conceptually split into N pieces, where N is the number of monitors specified in the parameter list.
    2563 The thread is woken up when all the pieces have popped from the AS-stacks and made active.
    2564 In this picture, the threads are split into halves but this is only because there are two monitors.
    2565 For a specific signalling operation every monitor needs a piece of thread on its AS-stack.
    2566 
    2567 \begin{figure}
    2568 \begin{multicols}{2}
    2569 Entry
    2570 \begin{cfa}
    2571 if monitor is free
    2572         enter
    2573 elif already own the monitor
    2574         continue
    2575 else
    2576         block
    2577 increment recursion
    2578 
    2579 \end{cfa}
    2580 \columnbreak
    2581 Exit
    2582 \begin{cfa}
    2583 decrement recursion
    2584 if recursion == 0
    2585         if signal_stack not empty
    2586                 set_owner to thread
    2587                 if all monitors ready
    2588                         wake-up thread
    2589 
    2590         if entry queue not empty
    2591                 wake-up thread
    2592 \end{cfa}
    2593 \end{multicols}
    2594 \begin{cfa}[caption={Entry and exit routine for monitors with internal scheduling},label={f:entry2}]
    2595 \end{cfa}
    2596 \end{figure}
    2597 
    2598 The solution discussed in \ref{s:InternalScheduling} can be seen in the exit routine of listing \ref{f:entry2}.
    2599 Basically, the solution boils down to having a separate data structure for the condition queue and the AS-stack, and unconditionally transferring ownership of the monitors but only unblocking the thread when the last monitor has transferred ownership.
    2600 This solution is deadlock safe as well as preventing any potential barging.
    2601 The data structures used for the AS-stack are reused extensively for external scheduling, but in the case of internal scheduling, the data is allocated using variable-length arrays on the call stack of the @wait@ and @signal_block@ routines.
    2602 
    2603 \begin{figure}
    2604 \begin{center}
    2605 {\resizebox{0.8\textwidth}{!}{\input{monitor_structs.pstex_t}}}
    2606 \end{center}
    2607 \caption{Data structures involved in internal/external scheduling}
    2608 \label{fig:structs}
    2609 \end{figure}
    2610 
    2611 Figure \ref{fig:structs} shows a high-level representation of these data structures.
    2612 The main idea behind them is that, a thread cannot contain an arbitrary number of intrusive ``next'' pointers for linking onto monitors.
    2613 The @condition node@ is the data structure that is queued onto a condition variable and, when signalled, the condition queue is popped and each @condition criterion@ is moved to the AS-stack.
    2614 Once all the criteria have been popped from their respective AS-stacks, the thread is woken up, which is what is shown in listing \ref{f:entry2}.
    2615 
    2616 % ======================================================================
    2617 % ======================================================================
    2618 \section{External Scheduling}
    2619 % ======================================================================
    2620 % ======================================================================
    2621 Similarly to internal scheduling, external scheduling for multiple monitors relies on the idea that waiting-thread queues are no longer specific to a single monitor, as mentioned in section \ref{extsched}.
    2622 For internal scheduling, these queues are part of condition variables, which are still unique for a given scheduling operation (\ie no signal statement uses multiple conditions).
    2623 However, in the case of external scheduling, there is no equivalent object which is associated with @waitfor@ statements.
    2624 This absence means the queues holding the waiting threads must be stored inside at least one of the monitors that is acquired.
    2625 These monitors being the only objects that have sufficient lifetime and are available on both sides of the @waitfor@ statement.
    2626 This requires an algorithm to choose which monitor holds the relevant queue.
    2627 It is also important that said algorithm be independent of the order in which users list parameters.
    2628 The proposed algorithm is to fall back on monitor lock ordering (sorting by address) and specify that the monitor that is acquired first is the one with the relevant waiting queue.
    2629 This assumes that the lock acquiring order is static for the lifetime of all concerned objects but that is a reasonable constraint.
    2630 
    2631 This algorithm choice has two consequences:
    2632 \begin{itemize}
    2633         \item The queue of the monitor with the lowest address is no longer a true FIFO queue because threads can be moved to the front of the queue.
    2634 These queues need to contain a set of monitors for each of the waiting threads.
    2635 Therefore, another thread whose set contains the same lowest address monitor but different lower priority monitors may arrive first but enter the critical section after a thread with the correct pairing.
    2636         \item The queue of the lowest priority monitor is both required and potentially unused.
    2637 Indeed, since it is not known at compile time which monitor is the monitor which has the lowest address, every monitor needs to have the correct queues even though it is possible that some queues go unused for the entire duration of the program, for example if a monitor is only used in a specific pair.
    2638 \end{itemize}
    2639 Therefore, the following modifications need to be made to support external scheduling:
    2640 \begin{itemize}
    2641         \item The threads waiting on the entry queue need to keep track of which routine they are trying to enter, and using which set of monitors.
    2642 The @mutex@ routine already has all the required information on its stack, so the thread only needs to keep a pointer to that information.
    2643         \item The monitors need to keep a mask of acceptable routines.
    2644 This mask contains for each acceptable routine, a routine pointer and an array of monitors to go with it.
    2645 It also needs storage to keep track of which routine was accepted.
    2646 Since this information is not specific to any monitor, the monitors actually contain a pointer to an integer on the stack of the waiting thread.
    2647 Note that if a thread has acquired two monitors but executes a @waitfor@ with only one monitor as a parameter, setting the mask of acceptable routines to both monitors will not cause any problems since the extra monitor will not change ownership regardless.
    2648 This becomes relevant when @when@ clauses affect the number of monitors passed to a @waitfor@ statement.
    2649         \item The entry/exit routines need to be updated as shown in listing \ref{f:entry3}.
    2650 \end{itemize}
    2651 
    2652 \subsection{External Scheduling - Destructors}
    2653 Finally, to support the ordering inversion of destructors, the code generation needs to be modified to use a special entry routine.
    2654 This routine is needed because of the storage requirements of the call order inversion.
    2655 Indeed, when waiting for the destructors, storage is needed for the waiting context and the lifetime of said storage needs to outlive the waiting operation it is needed for.
    2656 For regular @waitfor@ statements, the call stack of the routine itself matches this requirement but it is no longer the case when waiting for the destructor since it is pushed on to the AS-stack for later.
    2657 The @waitfor@ semantics can then be adjusted correspondingly, as seen in listing \ref{f:entry-dtor}
    2658 
    2659 \begin{figure}
    2660 \begin{multicols}{2}
    2661 Entry
    2662 \begin{cfa}
    2663 if monitor is free
    2664         enter
    2665 elif already own the monitor
    2666         continue
    2667 elif matches waitfor mask
    2668         push criteria to AS-stack
    2669         continue
    2670 else
    2671         block
    2672 increment recursion
    2673 \end{cfa}
    2674 \columnbreak
    2675 Exit
    2676 \begin{cfa}
    2677 decrement recursion
    2678 if recursion == 0
    2679         if signal_stack not empty
    2680                 set_owner to thread
    2681                 if all monitors ready
    2682                         wake-up thread
    2683                 endif
    2684         endif
    2685 
    2686         if entry queue not empty
    2687                 wake-up thread
    2688         endif
    2689 \end{cfa}
    2690 \end{multicols}
    2691 \begin{cfa}[caption={Entry and exit routine for monitors with internal scheduling and external scheduling},label={f:entry3}]
    2692 \end{cfa}
    2693 \end{figure}
    2694 
    2695 \begin{figure}
    2696 \begin{multicols}{2}
    2697 Destructor Entry
    2698 \begin{cfa}
    2699 if monitor is free
    2700         enter
    2701 elif already own the monitor
    2702         increment recursion
    2703         return
    2704 create wait context
    2705 if matches waitfor mask
    2706         reset mask
    2707         push self to AS-stack
    2708         baton pass
    2709 else
    2710         wait
    2711 increment recursion
    2712 \end{cfa}
    2713 \columnbreak
    2714 Waitfor
    2715 \begin{cfa}
    2716 if matching thread is already there
    2717         if found destructor
    2718                 push destructor to AS-stack
    2719                 unlock all monitors
    2720         else
    2721                 push self to AS-stack
    2722                 baton pass
    2723         endif
    2724         return
    2725 endif
    2726 if non-blocking
    2727         Unlock all monitors
    2728         Return
    2729 endif
    2730 
    2731 push self to AS-stack
    2732 set waitfor mask
    2733 block
    2734 return
    2735 \end{cfa}
    2736 \end{multicols}
    2737 \begin{cfa}[caption={Pseudo code for the \protect\lstinline|waitfor| routine and the \protect\lstinline|mutex| entry routine for destructors},label={f:entry-dtor}]
    2738 \end{cfa}
    2739 \end{figure}
    2740 
    2741 
    2742 % ======================================================================
    2743 % ======================================================================
    2744 \section{Putting It All Together}
    2745 % ======================================================================
    2746 % ======================================================================
    2747 
    2748 
    2749 \section{Threads As Monitors}
    2750 As it was subtly alluded in section \ref{threads}, @thread@s in \CFA are in fact monitors, which means that all monitor features are available when using threads.
    2751 For example, here is a very simple two thread pipeline that could be used for a simulator of a game engine:
    2752 \begin{figure}
    2753 \begin{cfa}[caption={Toy simulator using \protect\lstinline|thread|s and \protect\lstinline|monitor|s.},label={f:engine-v1}]
    2754 // Visualization declaration
    2755 thread Renderer {} renderer;
    2756 Frame * simulate( Simulator & this );
    2757 
    2758 // Simulation declaration
    2759 thread Simulator{} simulator;
    2760 void render( Renderer & this );
    2761 
    2762 // Blocking call used as communication
    2763 void draw( Renderer & mutex this, Frame * frame );
    2764 
    2765 // Simulation loop
    2766 void main( Simulator & this ) {
    2767         while( true ) {
    2768                 Frame * frame = simulate( this );
    2769                 draw( renderer, frame );
    2770         }
    2771 }
    2772 
    2773 // Rendering loop
    2774 void main( Renderer & this ) {
    2775         while( true ) {
    2776                 waitfor( draw, this );
    2777                 render( this );
    2778         }
    2779 }
    2780 \end{cfa}
    2781 \end{figure}
    2782 One of the obvious complaints of the previous code snippet (other than its toy-like simplicity) is that it does not handle exit conditions and just goes on forever.
    2783 Luckily, the monitor semantics can also be used to clearly enforce a shutdown order in a concise manner:
    2784 \begin{figure}
    2785 \begin{cfa}[caption={Same toy simulator with proper termination condition.},label={f:engine-v2}]
    2786 // Visualization declaration
    2787 thread Renderer {} renderer;
    2788 Frame * simulate( Simulator & this );
    2789 
    2790 // Simulation declaration
    2791 thread Simulator{} simulator;
    2792 void render( Renderer & this );
    2793 
    2794 // Blocking call used as communication
    2795 void draw( Renderer & mutex this, Frame * frame );
    2796 
    2797 // Simulation loop
    2798 void main( Simulator & this ) {
    2799         while( true ) {
    2800                 Frame * frame = simulate( this );
    2801                 draw( renderer, frame );
    2802 
    2803                 // Exit main loop after the last frame
    2804                 if( frame->is_last ) break;
    2805         }
    2806 }
    2807 
    2808 // Rendering loop
    2809 void main( Renderer & this ) {
    2810         while( true ) {
    2811                    waitfor( draw, this );
    2812                 or waitfor( ^?{}, this ) {
    2813                         // Add an exit condition
    2814                         break;
    2815                 }
    2816 
    2817                 render( this );
    2818         }
    2819 }
    2820 
    2821 // Call destructor for simulator once simulator finishes
    2822 // Call destructor for renderer to signify shutdown
    2823 \end{cfa}
    2824 \end{figure}
    2825 
    2826 \section{Fibers \& Threads}
    2827 As mentioned in section \ref{preemption}, \CFA uses preemptive threads by default but can use fibers on demand.
    2828 Currently, using fibers is done by adding the following line of code to the program~:
    2829 \begin{cfa}
    2830 unsigned int default_preemption() {
    2831         return 0;
    2832 }
    2833 \end{cfa}
    2834 This routine is called by the kernel to fetch the default preemption rate, where 0 signifies an infinite time-slice, \ie no preemption.
    2835 However, once clusters are fully implemented, it will be possible to create fibers and \textbf{uthread} in the same system, as in listing \ref{f:fiber-uthread}
    2836 \begin{figure}
    2837 \lstset{language=CFA,deletedelim=**[is][]{`}{`}}
    2838 \begin{cfa}[caption={Using fibers and \textbf{uthread} side-by-side in \CFA},label={f:fiber-uthread}]
    2839 // Cluster forward declaration
    2840 struct cluster;
    2841 
    2842 // Processor forward declaration
    2843 struct processor;
    2844 
    2845 // Construct clusters with a preemption rate
    2846 void ?{}(cluster& this, unsigned int rate);
    2847 // Construct processor and add it to cluster
    2848 void ?{}(processor& this, cluster& cluster);
    2849 // Construct thread and schedule it on cluster
    2850 void ?{}(thread& this, cluster& cluster);
    2851 
    2852 // Declare two clusters
    2853 cluster thread_cluster = { 10`ms };                     // Preempt every 10 ms
    2854 cluster fibers_cluster = { 0 };                         // Never preempt
    2855 
    2856 // Construct 4 processors
    2857 processor processors[4] = {
    2858         //2 for the thread cluster
    2859         thread_cluster;
    2860         thread_cluster;
    2861         //2 for the fibers cluster
    2862         fibers_cluster;
    2863         fibers_cluster;
    2864 };
    2865 
    2866 // Declares thread
    2867 thread UThread {};
    2868 void ?{}(UThread& this) {
    2869         // Construct underlying thread to automatically
    2870         // be scheduled on the thread cluster
    2871         (this){ thread_cluster }
    2872 }
    2873 
    2874 void main(UThread & this);
    2875 
    2876 // Declares fibers
    2877 thread Fiber {};
    2878 void ?{}(Fiber& this) {
    2879         // Construct underlying thread to automatically
    2880         // be scheduled on the fiber cluster
    2881         (this.__thread){ fibers_cluster }
    2882 }
    2883 
    2884 void main(Fiber & this);
    2885 \end{cfa}
    2886 \end{figure}
    2887 
    2888 
    2889 % ======================================================================
    2890 % ======================================================================
    2891 \section{Performance Results} \label{results}
    2892 % ======================================================================
    2893 % ======================================================================
    2894 \section{Machine Setup}
    2895 Table \ref{tab:machine} shows the characteristics of the machine used to run the benchmarks.
    2896 All tests were made on this machine.
    2897 \begin{table}
    2898 \begin{center}
    2899 \begin{tabular}{| l | r | l | r |}
    2900 \hline
    2901 Architecture            & x86\_64                       & NUMA node(s)  & 8 \\
    2902 \hline
    2903 CPU op-mode(s)          & 32-bit, 64-bit                & Model name    & AMD Opteron\texttrademark  Processor 6380 \\
    2904 \hline
    2905 Byte Order                      & Little Endian                 & CPU Freq              & 2.5\si{\giga\hertz} \\
    2906 \hline
    2907 CPU(s)                  & 64                            & L1d cache     & \SI{16}{\kibi\byte} \\
    2908 \hline
    2909 Thread(s) per core      & 2                             & L1i cache     & \SI{64}{\kibi\byte} \\
    2910 \hline
    2911 Core(s) per socket      & 8                             & L2 cache              & \SI{2048}{\kibi\byte} \\
    2912 \hline
    2913 Socket(s)                       & 4                             & L3 cache              & \SI{6144}{\kibi\byte} \\
     2518thread  & stateful                              & \multicolumn{1}{c|}{No} & \multicolumn{1}{c}{Yes} \\
    29142519\hline
    29152520\hline
    2916 Operating system                & Ubuntu 16.04.3 LTS    & Kernel                & Linux 4.4-97-generic \\
     2521No              & No                                    & \textbf{1}\ \ \ aggregate type                & \textbf{2}\ \ \ @monitor@ aggregate type \\
    29172522\hline
    2918 Compiler                        & GCC 6.3               & Translator    & CFA 1 \\
     2523No              & Yes (stackless)               & \textbf{3}\ \ \ @generator@                   & \textbf{4}\ \ \ @monitor@ @generator@ \\
    29192524\hline
    2920 Java version            & OpenJDK-9             & Go version    & 1.9.2 \\
     2525No              & Yes (stackful)                & \textbf{5}\ \ \ @coroutine@                   & \textbf{6}\ \ \ @monitor@ @coroutine@ \\
    29212526\hline
     2527Yes             & No / Yes (stackless)  & \textbf{7}\ \ \ {\color{red}rejected} & \textbf{8}\ \ \ {\color{red}rejected} \\
     2528\hline
     2529Yes             & Yes (stackful)                & \textbf{9}\ \ \ @thread@                              & \textbf{10}\ \ @monitor@ @thread@ \\
    29222530\end{tabular}
    2923 \end{center}
    2924 \caption{Machine setup used for the tests}
    2925 \label{tab:machine}
    29262531\end{table}
    29272532
    2928 \section{Micro Benchmarks}
    2929 All benchmarks are run using the same harness to produce the results, seen as the @BENCH()@ macro in the following examples.
    2930 This macro uses the following logic to benchmark the code:
    2931 \begin{cfa}
    2932 #define BENCH(run, result) \
    2933         before = gettime(); \
    2934         run; \
    2935         after  = gettime(); \
    2936         result = (after - before) / N;
    2937 \end{cfa}
    2938 The method used to get time is @clock_gettime(CLOCK_THREAD_CPUTIME_ID);@.
    2939 Each benchmark is using many iterations of a simple call to measure the cost of the call.
    2940 The specific number of iterations depends on the specific benchmark.
    2941 
    2942 \subsection{Context-Switching}
    2943 The first interesting benchmark is to measure how long context-switches take.
    2944 The simplest approach to do this is to yield on a thread, which executes a 2-step context switch.
    2945 Yielding causes the thread to context-switch to the scheduler and back, more precisely: from the \textbf{uthread} to the \textbf{kthread} then from the \textbf{kthread} back to the same \textbf{uthread} (or a different one in the general case).
    2946 In order to make the comparison fair, coroutines also execute a 2-step context-switch by resuming another coroutine which does nothing but suspending in a tight loop, which is a resume/suspend cycle instead of a yield.
    2947 Figure~\ref{f:ctx-switch} shows the code for coroutines and threads with the results in table \ref{tab:ctx-switch}.
    2948 All omitted tests are functionally identical to one of these tests.
    2949 The difference between coroutines and threads can be attributed to the cost of scheduling.
     2533
     2534\subsection{Low-level Locks}
     2535
     2536For completeness and efficiency, \CFA provides a standard set of low-level locks: recursive mutex, condition, semaphore, barrier, \etc, and atomic instructions: @fetchAssign@, @fetchAdd@, @testSet@, @compareSet@, \etc.
     2537Some of these low-level mechanism are used in the \CFA runtime, but we strongly advocate using high-level mechanisms whenever possible.
     2538
     2539
     2540% \section{Parallelism}
     2541% \label{s:Parallelism}
     2542%
     2543% Historically, computer performance was about processor speeds.
     2544% However, with heat dissipation being a direct consequence of speed increase, parallelism is the new source for increased performance~\cite{Sutter05, Sutter05b}.
     2545% Therefore, high-performance applications must care about parallelism, which requires concurrency.
     2546% The lowest-level approach of parallelism is to use \newterm{kernel threads} in combination with semantics like @fork@, @join@, \etc.
     2547% However, kernel threads are better as an implementation tool because of complexity and higher cost.
     2548% Therefore, different abstractions are often layered onto kernel threads to simplify them, \eg pthreads.
     2549%
     2550%
     2551% \subsection{User Threads}
     2552%
     2553% A direct improvement on kernel threads is user threads, \eg Erlang~\cite{Erlang} and \uC~\cite{uC++book}.
     2554% This approach provides an interface that matches the language paradigms, gives more control over concurrency by the language runtime, and an abstract (and portable) interface to the underlying kernel threads across operating systems.
     2555% In many cases, user threads can be used on a much larger scale (100,000 threads).
     2556% Like kernel threads, user threads support preemption, which maximizes nondeterminism, but increases the potential for concurrency errors: race, livelock, starvation, and deadlock.
     2557% \CFA adopts user-threads to provide more flexibility and a low-cost mechanism to build any other concurrency approach, \eg thread pools and actors~\cite{Actors}.
     2558%
     2559% A variant of user thread is \newterm{fibres}, which removes preemption, \eg Go~\cite{Go} @goroutine@s.
     2560% Like functional programming, which removes mutation and its associated problems, removing preemption from concurrency reduces nondeterminism, making race and deadlock errors more difficult to generate.
     2561% However, preemption is necessary for fairness and to reduce tail-latency.
     2562% For concurrency that relies on spinning, if all cores spin the system is livelocked, whereas preemption breaks the livelock.
     2563
     2564
     2565\begin{comment}
     2566\subsection{Thread Pools}
     2567
     2568In contrast to direct threading is indirect \newterm{thread pools}, \eg Java @executor@, where small jobs (work units) are inserted into a work pool for execution.
     2569If the jobs are dependent, \ie interact, there is an implicit/explicit dependency graph that ties them together.
     2570While removing direct concurrency, and hence the amount of context switching, thread pools significantly limit the interaction that can occur among jobs.
     2571Indeed, jobs should not block because that also blocks the underlying thread, which effectively means the CPU utilization, and therefore throughput, suffers.
     2572While it is possible to tune the thread pool with sufficient threads, it becomes difficult to obtain high throughput and good core utilization as job interaction increases.
     2573As well, concurrency errors return, which threads pools are suppose to mitigate.
     2574
    29502575\begin{figure}
     2576\centering
     2577\begin{tabular}{@{}l|l@{}}
     2578\begin{cfa}
     2579struct Adder {
     2580    int * row, cols;
     2581};
     2582int operator()() {
     2583        subtotal = 0;
     2584        for ( int c = 0; c < cols; c += 1 )
     2585                subtotal += row[c];
     2586        return subtotal;
     2587}
     2588void ?{}( Adder * adder, int row[$\,$], int cols, int & subtotal ) {
     2589        adder.[rows, cols, subtotal] = [rows, cols, subtotal];
     2590}
     2591
     2592
     2593
     2594
     2595\end{cfa}
     2596&
     2597\begin{cfa}
     2598int main() {
     2599        const int rows = 10, cols = 10;
     2600        int matrix[rows][cols], subtotals[rows], total = 0;
     2601        // read matrix
     2602        Executor executor( 4 ); // kernel threads
     2603        Adder * adders[rows];
     2604        for ( r; rows ) { // send off work for executor
     2605                adders[r] = new( matrix[r], cols, &subtotal[r] );
     2606                executor.send( *adders[r] );
     2607        }
     2608        for ( r; rows ) {       // wait for results
     2609                delete( adders[r] );
     2610                total += subtotals[r];
     2611        }
     2612        sout | total;
     2613}
     2614\end{cfa}
     2615\end{tabular}
     2616\caption{Executor}
     2617\end{figure}
     2618\end{comment}
     2619
     2620
     2621\section{Runtime Structure}
     2622\label{s:CFARuntimeStructure}
     2623
     2624Figure~\ref{f:RunTimeStructure} illustrates the runtime structure of a \CFA program.
     2625In addition to the new kinds of objects introduced by \CFA, there are two more runtime entities used to control parallel execution: cluster and (virtual) processor.
     2626An executing thread is illustrated by its containment in a processor.
     2627
     2628\begin{figure}
     2629\centering
     2630\input{RunTimeStructure}
     2631\caption{\CFA Runtime structure}
     2632\label{f:RunTimeStructure}
     2633\end{figure}
     2634
     2635
     2636\subsection{Cluster}
     2637\label{s:RuntimeStructureCluster}
     2638
     2639A \newterm{cluster} is a collection of threads and virtual processors (abstract kernel-thread) that execute the (user) threads from its own ready queue (like an OS executing kernel threads).
     2640The purpose of a cluster is to control the amount of parallelism that is possible among threads, plus scheduling and other execution defaults.
     2641The default cluster-scheduler is single-queue multi-server, which provides automatic load-balancing of threads on processors.
     2642However, the design allows changing the scheduler, \eg multi-queue multi-server with work-stealing/sharing across the virtual processors.
     2643If several clusters exist, both threads and virtual processors, can be explicitly migrated from one cluster to another.
     2644No automatic load balancing among clusters is performed by \CFA.
     2645
     2646When a \CFA program begins execution, it creates a user cluster with a single processor and a special processor to handle preemption that does not execute user threads.
     2647The user cluster is created to contain the application user-threads.
     2648Having all threads execute on the one cluster often maximizes utilization of processors, which minimizes runtime.
     2649However, because of limitations of scheduling requirements (real-time), NUMA architecture, heterogeneous hardware, or issues with the underlying operating system, multiple clusters are sometimes necessary.
     2650
     2651
     2652\subsection{Virtual Processor}
     2653\label{s:RuntimeStructureProcessor}
     2654
     2655A virtual processor is implemented by a kernel thread (\eg UNIX process), which are scheduled for execution on a hardware processor by the underlying operating system.
     2656Programs may use more virtual processors than hardware processors.
     2657On a multiprocessor, kernel threads are distributed across the hardware processors resulting in virtual processors executing in parallel.
     2658(It is possible to use affinity to lock a virtual processor onto a particular hardware processor~\cite{affinityLinux, affinityWindows, affinityFreebsd, affinityNetbsd, affinityMacosx}, which is used when caching issues occur or for heterogeneous hardware processors.)
     2659The \CFA runtime attempts to block unused processors and unblock processors as the system load increases;
     2660balancing the workload with processors is difficult because it requires future knowledge, \ie what will the applicaton workload do next.
     2661Preemption occurs on virtual processors rather than user threads, via operating-system interrupts.
     2662Thus virtual processors execute user threads, where preemption frequency applies to a virtual processor, so preemption occurs randomly across the executed user threads.
     2663Turning off preemption transforms user threads into fibres.
     2664
     2665
     2666\begin{comment}
     2667\section{Implementation}
     2668\label{s:Implementation}
     2669
     2670A primary implementation challenge is avoiding contention from dynamically allocating memory because of bulk acquire, \eg the internal-scheduling design is (almost) free of allocations.
     2671All blocking operations are made by parking threads onto queues, therefore all queues are designed with intrusive nodes, where each node has preallocated link fields for chaining.
     2672Furthermore, several bulk-acquire operations need a variable amount of memory.
     2673This storage is allocated at the base of a thread's stack before blocking, which means programmers must add a small amount of extra space for stacks.
     2674
     2675In \CFA, ordering of monitor acquisition relies on memory ordering to prevent deadlock~\cite{Havender68}, because all objects have distinct non-overlapping memory layouts, and mutual-exclusion for a monitor is only defined for its lifetime.
     2676When a mutex call is made, pointers to the concerned monitors are aggregated into a variable-length array and sorted.
     2677This array persists for the entire duration of the mutual exclusion and is used extensively for synchronization operations.
     2678
     2679To improve performance and simplicity, context switching occurs inside a function call, so only callee-saved registers are copied onto the stack and then the stack register is switched;
     2680the corresponding registers are then restored for the other context.
     2681Note, the instruction pointer is untouched since the context switch is always inside the same function.
     2682Experimental results (not presented) for a stackless or stackful scheduler (1 versus 2 context switches) (see Section~\ref{s:Concurrency}) show the performance is virtually equivalent, because both approaches are dominated by locking to prevent a race condition.
     2683
     2684All kernel threads (@pthreads@) created a stack.
     2685Each \CFA virtual processor is implemented as a coroutine and these coroutines run directly on the kernel-thread stack, effectively stealing this stack.
     2686The exception to this rule is the program main, \ie the initial kernel thread that is given to any program.
     2687In order to respect C expectations, the stack of the initial kernel thread is used by program main rather than the main processor, allowing it to grow dynamically as in a normal C program.
     2688\end{comment}
     2689
     2690
     2691\subsection{Preemption}
     2692
     2693Nondeterministic preemption provides fairness from long-running threads, and forces concurrent programmers to write more robust programs, rather than relying on code between cooperative scheduling to be atomic.
     2694This atomic reliance can fail on multi-core machines, because execution across cores is nondeterministic.
     2695A different reason for not supporting preemption is that it significantly complicates the runtime system, \eg Microsoft runtime does not support interrupts and on Linux systems, interrupts are complex (see below).
     2696Preemption is normally handled by setting a countdown timer on each virtual processor.
     2697When the timer expires, an interrupt is delivered, and the interrupt handler resets the countdown timer, and if the virtual processor is executing in user code, the signal handler performs a user-level context-switch, or if executing in the language runtime kernel, the preemption is ignored or rolled forward to the point where the runtime kernel context switches back to user code.
     2698Multiple signal handlers may be pending.
     2699When control eventually switches back to the signal handler, it returns normally, and execution continues in the interrupted user thread, even though the return from the signal handler may be on a different kernel thread than the one where the signal is delivered.
     2700The only issue with this approach is that signal masks from one kernel thread may be restored on another as part of returning from the signal handler;
     2701therefore, the same signal mask is required for all virtual processors in a cluster.
     2702Because preemption frequency is usually long (1 millisecond) performance cost is negligible.
     2703
     2704Linux switched a decade ago from specific to arbitrary process signal-delivery for applications with multiple kernel threads.
     2705\begin{cquote}
     2706A process-directed signal may be delivered to any one of the threads that does not currently have the signal blocked.
     2707If more than one of the threads has the signal unblocked, then the kernel chooses an arbitrary thread to which it will deliver the signal.
     2708SIGNAL(7) - Linux Programmer's Manual
     2709\end{cquote}
     2710Hence, the timer-expiry signal, which is generated \emph{externally} by the Linux kernel to an application, is delivered to any of its Linux subprocesses (kernel threads).
     2711To ensure each virtual processor receives a preemption signal, a discrete-event simulation is run on a special virtual processor, and only it sets and receives timer events.
     2712Virtual processors register an expiration time with the discrete-event simulator, which is inserted in sorted order.
     2713The simulation sets the countdown timer to the value at the head of the event list, and when the timer expires, all events less than or equal to the current time are processed.
     2714Processing a preemption event sends an \emph{internal} @SIGUSR1@ signal to the registered virtual processor, which is always delivered to that processor.
     2715
     2716
     2717\subsection{Debug Kernel}
     2718
     2719There are two versions of the \CFA runtime kernel: debug and non-debug.
     2720The debugging version has many runtime checks and internal assertions, \eg stack (non-writable) guard page, and checks for stack overflow whenever context switches occur among coroutines and threads, which catches most stack overflows.
     2721After a program is debugged, the non-debugging version can be used to significantly decrease space and increase performance.
     2722
     2723
     2724\section{Performance}
     2725\label{s:Performance}
     2726
     2727To verify the implementation of the \CFA runtime, a series of microbenchmarks are performed comparing \CFA with pthreads, Java OpenJDK-9, Go 1.12.6 and \uC 7.0.0.
     2728For comparison, the package must be multi-processor (M:N), which excludes libdill/libmil~\cite{libdill} (M:1)), and use a shared-memory programming model, \eg not message passing.
     2729The benchmark computer is an AMD Opteron\texttrademark\ 6380 NUMA 64-core, 8 socket, 2.5 GHz processor, running Ubuntu 16.04.6 LTS, and \CFA/\uC are compiled with gcc 6.5.
     2730
     2731All benchmarks are run using the following harness. (The Java harness is augmented to circumvent JIT issues.)
     2732\begin{cfa}
     2733unsigned int N = 10_000_000;
     2734#define BENCH( `run` ) Time before = getTimeNsec();  `run;`  Duration result = (getTimeNsec() - before) / N;
     2735\end{cfa}
     2736The method used to get time is @clock_gettime( CLOCK_REALTIME )@.
     2737Each benchmark is performed @N@ times, where @N@ varies depending on the benchmark;
     2738the total time is divided by @N@ to obtain the average time for a benchmark.
     2739Each benchmark experiment is run 31 times.
     2740All omitted tests for other languages are functionally identical to the \CFA tests and available online~\cite{CforallBenchMarks}.
     2741% tar --exclude=.deps --exclude=Makefile --exclude=Makefile.in --exclude=c.c --exclude=cxx.cpp --exclude=fetch_add.c -cvhf benchmark.tar benchmark
     2742
     2743\paragraph{Object Creation}
     2744
     2745Object creation is measured by creating/deleting the specific kind of concurrent object.
     2746Figure~\ref{f:creation} shows the code for \CFA, with results in Table~\ref{tab:creation}.
     2747The only note here is that the call stacks of \CFA coroutines are lazily created, therefore without priming the coroutine to force stack creation, the creation cost is artificially low.
     2748
    29512749\begin{multicols}{2}
    2952 \CFA Coroutines
    2953 \begin{cfa}
    2954 coroutine GreatSuspender {};
    2955 void main(GreatSuspender& this) {
    2956         while(true) { suspend(); }
    2957 }
     2750\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
     2751\begin{cfa}
     2752@thread@ MyThread {};
     2753void @main@( MyThread & ) {}
    29582754int main() {
    2959         GreatSuspender s;
    2960         resume(s);
     2755        BENCH( for ( N ) { @MyThread m;@ } )
     2756        sout | result`ns;
     2757}
     2758\end{cfa}
     2759\captionof{figure}{\CFA object-creation benchmark}
     2760\label{f:creation}
     2761
     2762\columnbreak
     2763
     2764\vspace*{-16pt}
     2765\captionof{table}{Object creation comparison (nanoseconds)}
     2766\label{tab:creation}
     2767
     2768\begin{tabular}[t]{@{}r*{3}{D{.}{.}{5.2}}@{}}
     2769\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
     2770\CFA Coroutine Lazy             & 13.2          & 13.1          & 0.44          \\
     2771\CFA Coroutine Eager    & 531.3         & 536.0         & 26.54         \\
     2772\CFA Thread                             & 2074.9        & 2066.5        & 170.76        \\
     2773\uC Coroutine                   & 89.6          & 90.5          & 1.83          \\
     2774\uC Thread                              & 528.2         & 528.5         & 4.94          \\
     2775Goroutine                               & 4068.0        & 4113.1        & 414.55        \\
     2776Java Thread                             & 103848.5      & 104295.4      & 2637.57       \\
     2777Pthreads                                & 33112.6       & 33127.1       & 165.90
     2778\end{tabular}
     2779\end{multicols}
     2780
     2781
     2782\paragraph{Context-Switching}
     2783
     2784In procedural programming, the cost of a function call is important as modularization (refactoring) increases.
     2785(In many cases, a compiler inlines function calls to eliminate this cost.)
     2786Similarly, when modularization extends to coroutines/tasks, the time for a context switch becomes a relevant factor.
     2787The coroutine test is from resumer to suspender and from suspender to resumer, which is two context switches.
     2788The thread test is using yield to enter and return from the runtime kernel, which is two context switches.
     2789The difference in performance between coroutine and thread context-switch is the cost of scheduling for threads, whereas coroutines are self-scheduling.
     2790Figure~\ref{f:ctx-switch} only shows the \CFA code for coroutines/threads (other systems are similar) with all results in Table~\ref{tab:ctx-switch}.
     2791
     2792\begin{multicols}{2}
     2793\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
     2794\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     2795@coroutine@ C {} c;
     2796void main( C & ) { for ( ;; ) { @suspend;@ } }
     2797int main() { // coroutine test
     2798        BENCH( for ( N ) { @resume( c );@ } )
     2799        sout | result`ns;
     2800}
     2801int main() { // task test
     2802        BENCH( for ( N ) { @yield();@ } )
     2803        sout | result`ns;
     2804}
     2805\end{cfa}
     2806\captionof{figure}{\CFA context-switch benchmark}
     2807\label{f:ctx-switch}
     2808
     2809\columnbreak
     2810
     2811\vspace*{-16pt}
     2812\captionof{table}{Context switch comparison (nanoseconds)}
     2813\label{tab:ctx-switch}
     2814\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
     2815\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
     2816C function              & 1.8   & 1.8   & 0.01  \\
     2817\CFA generator  & 2.4   & 2.2   & 0.25  \\
     2818\CFA Coroutine  & 36.2  & 36.2  & 0.25  \\
     2819\CFA Thread             & 93.2  & 93.5  & 2.09  \\
     2820\uC Coroutine   & 52.0  & 52.1  & 0.51  \\
     2821\uC Thread              & 96.2  & 96.3  & 0.58  \\
     2822Goroutine               & 141.0 & 141.3 & 3.39  \\
     2823Java Thread             & 374.0 & 375.8 & 10.38 \\
     2824Pthreads Thread & 361.0 & 365.3 & 13.19
     2825\end{tabular}
     2826\end{multicols}
     2827
     2828
     2829\paragraph{Mutual-Exclusion}
     2830
     2831Uncontented mutual exclusion, which frequently occurs, is measured by entering/leaving a critical section.
     2832For monitors, entering and leaving a monitor function is measured.
     2833To put the results in context, the cost of entering a non-inline function and the cost of acquiring and releasing a @pthread_mutex@ lock is also measured.
     2834Figure~\ref{f:mutex} shows the code for \CFA with all results in Table~\ref{tab:mutex}.
     2835Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects.
     2836
     2837\begin{multicols}{2}
     2838\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
     2839\begin{cfa}
     2840@monitor@ M {} m1/*, m2, m3, m4*/;
     2841void __attribute__((noinline))
     2842do_call( M & @mutex m/*, m2, m3, m4*/@ ) {}
     2843int main() {
    29612844        BENCH(
    2962                 for(size_t i=0; i<n; i++) {
    2963                         resume(s);
    2964                 },
    2965                 result
     2845                for( N ) do_call( m1/*, m2, m3, m4*/ );
    29662846        )
    2967         printf("%llu\n", result);
    2968 }
    2969 \end{cfa}
     2847        sout | result`ns;
     2848}
     2849\end{cfa}
     2850\captionof{figure}{\CFA acquire/release mutex benchmark}
     2851\label{f:mutex}
     2852
    29702853\columnbreak
    2971 \CFA Threads
    2972 \begin{cfa}
    2973 
    2974 
    2975 
    2976 
    2977 int main() {
    2978 
    2979 
    2980         BENCH(
    2981                 for(size_t i=0; i<n; i++) {
    2982                         yield();
    2983                 },
    2984                 result
    2985         )
    2986         printf("%llu\n", result);
    2987 }
    2988 \end{cfa}
     2854
     2855\vspace*{-16pt}
     2856\captionof{table}{Mutex comparison (nanoseconds)}
     2857\label{tab:mutex}
     2858\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
     2859\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
     2860test and test-and-test lock             & 19.1  & 18.9  & 0.40  \\
     2861\CFA @mutex@ function, 1 arg.   & 45.9  & 46.6  & 1.45  \\
     2862\CFA @mutex@ function, 2 arg.   & 105.0 & 104.7 & 3.08  \\
     2863\CFA @mutex@ function, 4 arg.   & 165.0 & 167.6 & 5.65  \\
     2864\uC @monitor@ member rtn.               & 54.0  & 53.7  & 0.82  \\
     2865Java synchronized method                & 31.0  & 31.1  & 0.50  \\
     2866Pthreads Mutex Lock                             & 33.6  & 32.6  & 1.14
     2867\end{tabular}
    29892868\end{multicols}
    2990 \begin{cfa}[caption={\CFA benchmark code used to measure context-switches for coroutines and threads.},label={f:ctx-switch}]
    2991 \end{cfa}
    2992 \end{figure}
    2993 
    2994 \begin{table}
    2995 \begin{center}
    2996 \begin{tabular}{| l | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] |}
    2997 \cline{2-4}
    2998 \multicolumn{1}{c |}{} & \multicolumn{1}{c |}{ Median } &\multicolumn{1}{c |}{ Average } & \multicolumn{1}{c |}{ Standard Deviation} \\
    2999 \hline
    3000 Kernel Thread   & 241.5 & 243.86        & 5.08 \\
    3001 \CFA Coroutine  & 38            & 38            & 0    \\
    3002 \CFA Thread             & 103           & 102.96        & 2.96 \\
    3003 \uC Coroutine   & 46            & 45.86 & 0.35 \\
    3004 \uC Thread              & 98            & 99.11 & 1.42 \\
    3005 Goroutine               & 150           & 149.96        & 3.16 \\
    3006 Java Thread             & 289           & 290.68        & 8.72 \\
    3007 \hline
    3008 \end{tabular}
    3009 \end{center}
    3010 \caption{Context Switch comparison.
    3011 All numbers are in nanoseconds(\si{\nano\second})}
    3012 \label{tab:ctx-switch}
    3013 \end{table}
    3014 
    3015 \subsection{Mutual-Exclusion}
    3016 The next interesting benchmark is to measure the overhead to enter/leave a critical-section.
    3017 For monitors, the simplest approach is to measure how long it takes to enter and leave a monitor routine.
    3018 Figure~\ref{f:mutex} shows the code for \CFA.
    3019 To put the results in context, the cost of entering a non-inline routine and the cost of acquiring and releasing a @pthread_mutex@ lock is also measured.
    3020 The results can be shown in table \ref{tab:mutex}.
    3021 
    3022 \begin{figure}
    3023 \begin{cfa}[caption={\CFA benchmark code used to measure mutex routines.},label={f:mutex}]
    3024 monitor M {};
    3025 void __attribute__((noinline)) call( M & mutex m /*, m2, m3, m4*/ ) {}
    3026 
    3027 int main() {
    3028         M m/*, m2, m3, m4*/;
    3029         BENCH(
    3030                 for(size_t i=0; i<n; i++) {
    3031                         call(m/*, m2, m3, m4*/);
    3032                 },
    3033                 result
    3034         )
    3035         printf("%llu\n", result);
    3036 }
    3037 \end{cfa}
    3038 \end{figure}
    3039 
    3040 \begin{table}
    3041 \begin{center}
    3042 \begin{tabular}{| l | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] |}
    3043 \cline{2-4}
    3044 \multicolumn{1}{c |}{} & \multicolumn{1}{c |}{ Median } &\multicolumn{1}{c |}{ Average } & \multicolumn{1}{c |}{ Standard Deviation} \\
    3045 \hline
    3046 C routine                                               & 2             & 2             & 0    \\
    3047 FetchAdd + FetchSub                             & 26            & 26            & 0    \\
    3048 Pthreads Mutex Lock                             & 31            & 31.86 & 0.99 \\
    3049 \uC @monitor@ member routine            & 30            & 30            & 0    \\
    3050 \CFA @mutex@ routine, 1 argument        & 41            & 41.57 & 0.9  \\
    3051 \CFA @mutex@ routine, 2 argument        & 76            & 76.96 & 1.57 \\
    3052 \CFA @mutex@ routine, 4 argument        & 145           & 146.68        & 3.85 \\
    3053 Java synchronized routine                       & 27            & 28.57 & 2.6  \\
    3054 \hline
    3055 \end{tabular}
    3056 \end{center}
    3057 \caption{Mutex routine comparison.
    3058 All numbers are in nanoseconds(\si{\nano\second})}
    3059 \label{tab:mutex}
    3060 \end{table}
    3061 
    3062 \subsection{Internal Scheduling}
    3063 The internal-scheduling benchmark measures the cost of waiting on and signalling a condition variable.
    3064 Figure~\ref{f:int-sched} shows the code for \CFA, with results table \ref{tab:int-sched}.
    3065 As with all other benchmarks, all omitted tests are functionally identical to one of these tests.
    3066 
    3067 \begin{figure}
    3068 \begin{cfa}[caption={Benchmark code for internal scheduling},label={f:int-sched}]
     2869
     2870
     2871\paragraph{External Scheduling}
     2872
     2873External scheduling is measured using a cycle of two threads calling and accepting the call using the @waitfor@ statement.
     2874Figure~\ref{f:ext-sched} shows the code for \CFA, with results in Table~\ref{tab:ext-sched}.
     2875Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects.
     2876
     2877\begin{multicols}{2}
     2878\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
     2879\vspace*{-16pt}
     2880\begin{cfa}
    30692881volatile int go = 0;
    3070 condition c;
    3071 monitor M {};
    3072 M m1;
    3073 
    3074 void __attribute__((noinline)) do_call( M & mutex a1 ) { signal(c); }
    3075 
     2882@monitor@ M {} m;
    30762883thread T {};
    3077 void ^?{}( T & mutex this ) {}
    3078 void main( T & this ) {
    3079         while(go == 0) { yield(); }
    3080         while(go == 1) { do_call(m1); }
    3081 }
    3082 int  __attribute__((noinline)) do_wait( M & mutex a1 ) {
    3083         go = 1;
    3084         BENCH(
    3085                 for(size_t i=0; i<n; i++) {
    3086                         wait(c);
    3087                 },
    3088                 result
    3089         )
    3090         printf("%llu\n", result);
    3091         go = 0;
    3092         return 0;
     2884void __attribute__((noinline))
     2885do_call( M & @mutex@ ) {}
     2886void main( T & ) {
     2887        while ( go == 0 ) { yield(); }
     2888        while ( go == 1 ) { do_call( m ); }
     2889}
     2890int __attribute__((noinline))
     2891do_wait( M & @mutex@ m ) {
     2892        go = 1; // continue other thread
     2893        BENCH( for ( N ) { @waitfor( do_call, m );@ } )
     2894        go = 0; // stop other thread
     2895        sout | result`ns;
    30932896}
    30942897int main() {
    30952898        T t;
    3096         return do_wait(m1);
    3097 }
    3098 \end{cfa}
    3099 \end{figure}
    3100 
    3101 \begin{table}
    3102 \begin{center}
    3103 \begin{tabular}{| l | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] |}
    3104 \cline{2-4}
    3105 \multicolumn{1}{c |}{} & \multicolumn{1}{c |}{ Median } &\multicolumn{1}{c |}{ Average } & \multicolumn{1}{c |}{ Standard Deviation} \\
    3106 \hline
    3107 Pthreads Condition Variable                     & 5902.5        & 6093.29       & 714.78 \\
    3108 \uC @signal@                                    & 322           & 323   & 3.36   \\
    3109 \CFA @signal@, 1 @monitor@      & 352.5 & 353.11        & 3.66   \\
    3110 \CFA @signal@, 2 @monitor@      & 430           & 430.29        & 8.97   \\
    3111 \CFA @signal@, 4 @monitor@      & 594.5 & 606.57        & 18.33  \\
    3112 Java @notify@                           & 13831.5       & 15698.21      & 4782.3 \\
    3113 \hline
     2899        do_wait( m );
     2900}
     2901\end{cfa}
     2902\captionof{figure}{\CFA external-scheduling benchmark}
     2903\label{f:ext-sched}
     2904
     2905\columnbreak
     2906
     2907\vspace*{-16pt}
     2908\captionof{table}{External-scheduling comparison (nanoseconds)}
     2909\label{tab:ext-sched}
     2910\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
     2911\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
     2912\CFA @waitfor@, 1 @monitor@     & 376.4 & 376.8 & 7.63  \\
     2913\CFA @waitfor@, 2 @monitor@     & 491.4 & 492.0 & 13.31 \\
     2914\CFA @waitfor@, 4 @monitor@     & 681.0 & 681.7 & 19.10 \\
     2915\uC @_Accept@                           & 331.1 & 331.4 & 2.66
    31142916\end{tabular}
    3115 \end{center}
    3116 \caption{Internal scheduling comparison.
    3117 All numbers are in nanoseconds(\si{\nano\second})}
    3118 \label{tab:int-sched}
    3119 \end{table}
    3120 
    3121 \subsection{External Scheduling}
    3122 The Internal scheduling benchmark measures the cost of the @waitfor@ statement (@_Accept@ in \uC).
    3123 Figure~\ref{f:ext-sched} shows the code for \CFA, with results in table \ref{tab:ext-sched}.
    3124 As with all other benchmarks, all omitted tests are functionally identical to one of these tests.
    3125 
    3126 \begin{figure}
    3127 \begin{cfa}[caption={Benchmark code for external scheduling},label={f:ext-sched}]
     2917\end{multicols}
     2918
     2919
     2920\paragraph{Internal Scheduling}
     2921
     2922Internal scheduling is measured using a cycle of two threads signalling and waiting.
     2923Figure~\ref{f:int-sched} shows the code for \CFA, with results in Table~\ref{tab:int-sched}.
     2924Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects.
     2925Java scheduling is significantly greater because the benchmark explicitly creates multiple thread in order to prevent the JIT from making the program sequential, \ie removing all locking.
     2926
     2927\begin{multicols}{2}
     2928\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
     2929\begin{cfa}
    31282930volatile int go = 0;
    3129 monitor M {};
    3130 M m1;
     2931@monitor@ M { @condition c;@ } m;
     2932void __attribute__((noinline))
     2933do_call( M & @mutex@ a1 ) { @signal( c );@ }
    31312934thread T {};
    3132 
    3133 void __attribute__((noinline)) do_call( M & mutex a1 ) {}
    3134 
    3135 void ^?{}( T & mutex this ) {}
    31362935void main( T & this ) {
    3137         while(go == 0) { yield(); }
    3138         while(go == 1) { do_call(m1); }
    3139 }
    3140 int  __attribute__((noinline)) do_wait( M & mutex a1 ) {
    3141         go = 1;
    3142         BENCH(
    3143                 for(size_t i=0; i<n; i++) {
    3144                         waitfor(call, a1);
    3145                 },
    3146                 result
    3147         )
    3148         printf("%llu\n", result);
    3149         go = 0;
    3150         return 0;
     2936        while ( go == 0 ) { yield(); }
     2937        while ( go == 1 ) { do_call( m ); }
     2938}
     2939int  __attribute__((noinline))
     2940do_wait( M & mutex m ) with(m) {
     2941        go = 1; // continue other thread
     2942        BENCH( for ( N ) { @wait( c );@ } );
     2943        go = 0; // stop other thread
     2944        sout | result`ns;
    31512945}
    31522946int main() {
    31532947        T t;
    3154         return do_wait(m1);
    3155 }
    3156 \end{cfa}
    3157 \end{figure}
    3158 
    3159 \begin{table}
    3160 \begin{center}
    3161 \begin{tabular}{| l | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] |}
    3162 \cline{2-4}
    3163 \multicolumn{1}{c |}{} & \multicolumn{1}{c |}{ Median } &\multicolumn{1}{c |}{ Average } & \multicolumn{1}{c |}{ Standard Deviation} \\
    3164 \hline
    3165 \uC @Accept@                                    & 350           & 350.61        & 3.11  \\
    3166 \CFA @waitfor@, 1 @monitor@     & 358.5 & 358.36        & 3.82  \\
    3167 \CFA @waitfor@, 2 @monitor@     & 422           & 426.79        & 7.95  \\
    3168 \CFA @waitfor@, 4 @monitor@     & 579.5 & 585.46        & 11.25 \\
    3169 \hline
     2948        do_wait( m );
     2949}
     2950\end{cfa}
     2951\captionof{figure}{\CFA Internal-scheduling benchmark}
     2952\label{f:int-sched}
     2953
     2954\columnbreak
     2955
     2956\vspace*{-16pt}
     2957\captionof{table}{Internal-scheduling comparison (nanoseconds)}
     2958\label{tab:int-sched}
     2959\bigskip
     2960
     2961\begin{tabular}{@{}r*{3}{D{.}{.}{5.2}}@{}}
     2962\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
     2963\CFA @signal@, 1 @monitor@      & 372.6         & 374.3         & 14.17         \\
     2964\CFA @signal@, 2 @monitor@      & 492.7         & 494.1         & 12.99         \\
     2965\CFA @signal@, 4 @monitor@      & 749.4         & 750.4         & 24.74         \\
     2966\uC @signal@                            & 320.5         & 321.0         & 3.36          \\
     2967Java @notify@                           & 10160.5       & 10169.4       & 267.71        \\
     2968Pthreads Cond. Variable         & 4949.6        & 5065.2        & 363
    31702969\end{tabular}
    3171 \end{center}
    3172 \caption{External scheduling comparison.
    3173 All numbers are in nanoseconds(\si{\nano\second})}
    3174 \label{tab:ext-sched}
    3175 \end{table}
    3176 
    3177 
    3178 \subsection{Object Creation}
    3179 Finally, the last benchmark measures the cost of creation for concurrent objects.
    3180 Figure~\ref{f:creation} shows the code for @pthread@s and \CFA threads, with results shown in table \ref{tab:creation}.
    3181 As with all other benchmarks, all omitted tests are functionally identical to one of these tests.
    3182 The only note here is that the call stacks of \CFA coroutines are lazily created, therefore without priming the coroutine, the creation cost is very low.
    3183 
    3184 \begin{figure}
    3185 \begin{center}
    3186 @pthread@
    3187 \begin{cfa}
    3188 int main() {
    3189         BENCH(
    3190                 for(size_t i=0; i<n; i++) {
    3191                         pthread_t thread;
    3192                         if(pthread_create(&thread,NULL,foo,NULL)<0) {
    3193                                 perror( "failure" );
    3194                                 return 1;
    3195                         }
    3196 
    3197                         if(pthread_join(thread, NULL)<0) {
    3198                                 perror( "failure" );
    3199                                 return 1;
    3200                         }
    3201                 },
    3202                 result
    3203         )
    3204         printf("%llu\n", result);
    3205 }
    3206 \end{cfa}
    3207 
    3208 
    3209 
    3210 \CFA Threads
    3211 \begin{cfa}
    3212 int main() {
    3213         BENCH(
    3214                 for(size_t i=0; i<n; i++) {
    3215                         MyThread m;
    3216                 },
    3217                 result
    3218         )
    3219         printf("%llu\n", result);
    3220 }
    3221 \end{cfa}
    3222 \end{center}
    3223 \caption{Benchmark code for \protect\lstinline|pthread|s and \CFA to measure object creation}
    3224 \label{f:creation}
    3225 \end{figure}
    3226 
    3227 \begin{table}
    3228 \begin{center}
    3229 \begin{tabular}{| l | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] |}
    3230 \cline{2-4}
    3231 \multicolumn{1}{c |}{} & \multicolumn{1}{c |}{ Median } &\multicolumn{1}{c |}{ Average } & \multicolumn{1}{c |}{ Standard Deviation} \\
    3232 \hline
    3233 Pthreads                        & 26996 & 26984.71      & 156.6  \\
    3234 \CFA Coroutine Lazy     & 6             & 5.71  & 0.45   \\
    3235 \CFA Coroutine Eager    & 708           & 706.68        & 4.82   \\
    3236 \CFA Thread                     & 1173.5        & 1176.18       & 15.18  \\
    3237 \uC Coroutine           & 109           & 107.46        & 1.74   \\
    3238 \uC Thread                      & 526           & 530.89        & 9.73   \\
    3239 Goroutine                       & 2520.5        & 2530.93       & 61,56  \\
    3240 Java Thread                     & 91114.5       & 92272.79      & 961.58 \\
    3241 \hline
    3242 \end{tabular}
    3243 \end{center}
    3244 \caption{Creation comparison.
    3245 All numbers are in nanoseconds(\si{\nano\second}).}
    3246 \label{tab:creation}
    3247 \end{table}
    3248 
     2970\end{multicols}
    32492971
    32502972
    32512973\section{Conclusion}
    3252 This paper has achieved a minimal concurrency \textbf{api} that is simple, efficient and usable as the basis for higher-level features.
    3253 The approach presented is based on a lightweight thread-system for parallelism, which sits on top of clusters of processors.
    3254 This M:N model is judged to be both more efficient and allow more flexibility for users.
    3255 Furthermore, this document introduces monitors as the main concurrency tool for users.
    3256 This paper also offers a novel approach allowing multiple monitors to be accessed simultaneously without running into the Nested Monitor Problem~\cite{Lister77}.
    3257 It also offers a full implementation of the concurrency runtime written entirely in \CFA, effectively the largest \CFA code base to date.
    3258 
    3259 
    3260 % ======================================================================
    3261 % ======================================================================
     2974
     2975Advanced control-flow will always be difficult, especially when there is temporal ordering and nondeterminism.
     2976However, many systems exacerbate the difficulty through their presentation mechanisms.
     2977This paper shows it is possible to present a hierarchy of control-flow features, generator, coroutine, thread, and monitor, providing an integrated set of high-level, efficient, and maintainable control-flow features.
     2978Eliminated from \CFA are spurious wakeup and barging, which are nonintuitive and lead to errors, and having to work with a bewildering set of low-level locks and acquisition techniques.
     2979\CFA high-level race-free monitors and tasks provide the core mechanisms for mutual exclusion and synchronization, without having to resort to magic qualifiers like @volatile@/@atomic@.
     2980Extending these mechanisms to handle high-level deadlock-free bulk acquire across both mutual exclusion and synchronization is a unique contribution.
     2981The \CFA runtime provides concurrency based on a preemptive M:N user-level threading-system, executing in clusters, which encapsulate scheduling of work on multiple kernel threads providing parallelism.
     2982The M:N model is judged to be efficient and provide greater flexibility than a 1:1 threading model.
     2983These concepts and the \CFA runtime-system are written in the \CFA language, extensively leveraging the \CFA type-system, which demonstrates the expressiveness of the \CFA language.
     2984Performance comparisons with other concurrent systems/languages show the \CFA approach is competitive across all low-level operations, which translates directly into good performance in well-written concurrent applications.
     2985C programmers should feel comfortable using these mechanisms for developing complex control-flow in applications, with the ability to obtain maximum available performance by selecting mechanisms at the appropriate level of need.
     2986
     2987
    32622988\section{Future Work}
    3263 % ======================================================================
    3264 % ======================================================================
    3265 
    3266 \subsection{Performance} \label{futur:perf}
    3267 This paper presents a first implementation of the \CFA concurrency runtime.
    3268 Therefore, there is still significant work to improve performance.
    3269 Many of the data structures and algorithms may change in the future to more efficient versions.
    3270 For example, the number of monitors in a single bulk acquire is only bound by the stack size, this is probably unnecessarily generous.
    3271 It may be possible that limiting the number helps increase performance.
    3272 However, it is not obvious that the benefit would be significant.
    3273 
    3274 \subsection{Flexible Scheduling} \label{futur:sched}
     2989
     2990While control flow in \CFA has a strong start, development is still underway to complete a number of missing features.
     2991
     2992\paragraph{Flexible Scheduling}
     2993\label{futur:sched}
     2994
    32752995An important part of concurrency is scheduling.
    32762996Different scheduling algorithms can affect performance (both in terms of average and variation).
    32772997However, no single scheduler is optimal for all workloads and therefore there is value in being able to change the scheduler for given programs.
    3278 One solution is to offer various tweaking options to users, allowing the scheduler to be adjusted to the requirements of the workload.
    3279 However, in order to be truly flexible, it would be interesting to allow users to add arbitrary data and arbitrary scheduling algorithms.
    3280 For example, a web server could attach Type-of-Service information to threads and have a ``ToS aware'' scheduling algorithm tailored to this specific web server.
    3281 This path of flexible schedulers will be explored for \CFA.
    3282 
    3283 \subsection{Non-Blocking I/O} \label{futur:nbio}
    3284 While most of the parallelism tools are aimed at data parallelism and control-flow parallelism, many modern workloads are not bound on computation but on IO operations, a common case being web servers and XaaS (anything as a service).
    3285 These types of workloads often require significant engineering around amortizing costs of blocking IO operations.
    3286 At its core, non-blocking I/O is an operating system level feature that allows queuing IO operations (\eg network operations) and registering for notifications instead of waiting for requests to complete.
    3287 In this context, the role of the language makes Non-Blocking IO easily available and with low overhead.
    3288 The current trend is to use asynchronous programming using tools like callbacks and/or futures and promises, which can be seen in frameworks like Node.js~\cite{NodeJs} for JavaScript, Spring MVC~\cite{SpringMVC} for Java and Django~\cite{Django} for Python.
    3289 However, while these are valid solutions, they lead to code that is harder to read and maintain because it is much less linear.
    3290 
    3291 \subsection{Other Concurrency Tools} \label{futur:tools}
    3292 While monitors offer a flexible and powerful concurrent core for \CFA, other concurrency tools are also necessary for a complete multi-paradigm concurrency package.
    3293 Examples of such tools can include simple locks and condition variables, futures and promises~\cite{promises}, executors and actors.
    3294 These additional features are useful when monitors offer a level of abstraction that is inadequate for certain tasks.
    3295 
    3296 \subsection{Implicit Threading} \label{futur:implcit}
    3297 Simpler applications can benefit greatly from having implicit parallelism.
    3298 That is, parallelism that does not rely on the user to write concurrency.
    3299 This type of parallelism can be achieved both at the language level and at the library level.
    3300 The canonical example of implicit parallelism is parallel for loops, which are the simplest example of a divide and conquer algorithms~\cite{uC++book}.
    3301 Table \ref{f:parfor} shows three different code examples that accomplish point-wise sums of large arrays.
    3302 Note that none of these examples explicitly declare any concurrency or parallelism objects.
    3303 
    3304 \begin{table}
    3305 \begin{center}
    3306 \begin{tabular}[t]{|c|c|c|}
    3307 Sequential & Library Parallel & Language Parallel \\
    3308 \begin{cfa}[tabsize=3]
    3309 void big_sum(
    3310         int* a, int* b,
    3311         int* o,
    3312         size_t len)
    3313 {
    3314         for(
    3315                 int i = 0;
    3316                 i < len;
    3317                 ++i )
    3318         {
    3319                 o[i]=a[i]+b[i];
    3320         }
    3321 }
    3322 
    3323 
    3324 
    3325 
    3326 
    3327 int* a[10000];
    3328 int* b[10000];
    3329 int* c[10000];
    3330 //... fill in a & b
    3331 big_sum(a,b,c,10000);
    3332 \end{cfa} &\begin{cfa}[tabsize=3]
    3333 void big_sum(
    3334         int* a, int* b,
    3335         int* o,
    3336         size_t len)
    3337 {
    3338         range ar(a, a+len);
    3339         range br(b, b+len);
    3340         range or(o, o+len);
    3341         parfor( ai, bi, oi,
    3342         [](     int* ai,
    3343                 int* bi,
    3344                 int* oi)
    3345         {
    3346                 oi=ai+bi;
    3347         });
    3348 }
    3349 
    3350 
    3351 int* a[10000];
    3352 int* b[10000];
    3353 int* c[10000];
    3354 //... fill in a & b
    3355 big_sum(a,b,c,10000);
    3356 \end{cfa}&\begin{cfa}[tabsize=3]
    3357 void big_sum(
    3358         int* a, int* b,
    3359         int* o,
    3360         size_t len)
    3361 {
    3362         parfor (ai,bi,oi)
    3363             in (a, b, o )
    3364         {
    3365                 oi = ai + bi;
    3366         }
    3367 }
    3368 
    3369 
    3370 
    3371 
    3372 
    3373 
    3374 
    3375 int* a[10000];
    3376 int* b[10000];
    3377 int* c[10000];
    3378 //... fill in a & b
    3379 big_sum(a,b,c,10000);
    3380 \end{cfa}
    3381 \end{tabular}
    3382 \end{center}
    3383 \caption{For loop to sum numbers: Sequential, using library parallelism and language parallelism.}
    3384 \label{f:parfor}
    3385 \end{table}
    3386 
    3387 Implicit parallelism is a restrictive solution and therefore has its limitations.
    3388 However, it is a quick and simple approach to parallelism, which may very well be sufficient for smaller applications and reduces the amount of boilerplate needed to start benefiting from parallelism in modern CPUs.
    3389 
    3390 
    3391 % A C K N O W L E D G E M E N T S
    3392 % -------------------------------
     2998One solution is to offer various tuning options, allowing the scheduler to be adjusted to the requirements of the workload.
     2999However, to be truly flexible, a pluggable scheduler is necessary.
     3000Currently, the \CFA pluggable scheduler is too simple to handle complex scheduling, \eg quality of service and real-time, where the scheduler must interact with mutex objects to deal with issues like priority inversion~\cite{Buhr00b}.
     3001
     3002\paragraph{Non-Blocking I/O}
     3003\label{futur:nbio}
     3004
     3005Many modern workloads are not bound by computation but IO operations, a common case being web servers and XaaS~\cite{XaaS} (anything as a service).
     3006These types of workloads require significant engineering to amortizing costs of blocking IO-operations.
     3007At its core, non-blocking I/O is an operating-system level feature queuing IO operations, \eg network operations, and registering for notifications instead of waiting for requests to complete.
     3008Current trends use asynchronous programming like callbacks, futures, and/or promises, \eg Node.js~\cite{NodeJs} for JavaScript, Spring MVC~\cite{SpringMVC} for Java, and Django~\cite{Django} for Python.
     3009However, these solutions lead to code that is hard to create, read and maintain.
     3010A better approach is to tie non-blocking I/O into the concurrency system to provide ease of use with low overhead, \eg thread-per-connection web-services.
     3011A non-blocking I/O library is currently under development for \CFA.
     3012
     3013\paragraph{Other Concurrency Tools}
     3014\label{futur:tools}
     3015
     3016While monitors offer flexible and powerful concurrency for \CFA, other concurrency tools are also necessary for a complete multi-paradigm concurrency package.
     3017Examples of such tools can include futures and promises~\cite{promises}, executors and actors.
     3018These additional features are useful for applications that can be constructed without shared data and direct blocking.
     3019As well, new \CFA extensions should make it possible to create a uniform interface for virtually all mutual exclusion, including monitors and low-level locks.
     3020
     3021\paragraph{Implicit Threading}
     3022\label{futur:implcit}
     3023
     3024Basic concurrent (embarrassingly parallel) applications can benefit greatly from implicit concurrency, where sequential programs are converted to concurrent, possibly with some help from pragmas to guide the conversion.
     3025This type of concurrency can be achieved both at the language level and at the library level.
     3026The canonical example of implicit concurrency is concurrent nested @for@ loops, which are amenable to divide and conquer algorithms~\cite{uC++book}.
     3027The \CFA language features should make it possible to develop a reasonable number of implicit concurrency mechanism to solve basic HPC data-concurrency problems.
     3028However, implicit concurrency is a restrictive solution with significant limitations, so it can never replace explicit concurrent programming.
     3029
     3030
    33933031\section{Acknowledgements}
    33943032
    3395 Thanks to Aaron Moss, Rob Schluntz and Andrew Beach for their work on the \CFA project as well as all the discussions which helped concretize the ideas in this paper.
    3396 Partial funding was supplied by the Natural Sciences and Engineering Research Council of Canada and a corporate partnership with Huawei Ltd.
    3397 
    3398 
    3399 % B I B L I O G R A P H Y
    3400 % -----------------------------
    3401 %\bibliographystyle{plain}
     3033The authors would like to recognize the design assistance of Aaron Moss, Rob Schluntz, Andrew Beach and Michael Brooks on the features described in this paper.
     3034Funding for this project has been provided by Huawei Ltd.\ (\url{http://www.huawei.com}). %, and Peter Buhr is partially funded by the Natural Sciences and Engineering Research Council of Canada.
     3035
     3036{%
     3037\fontsize{9bp}{12bp}\selectfont%
    34023038\bibliography{pl,local}
    3403 
     3039}%
    34043040
    34053041\end{document}
Note: See TracChangeset for help on using the changeset viewer.