Changes in / [63238a4:d286cf68]


Ignore:
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • doc/papers/OOPSLA17/Makefile

    r63238a4 rd286cf68  
    3333
    3434DOCUMENT = generic_types.pdf
    35 BASE = ${basename ${DOCUMENT}}
    3635
    3736# Directives #
     
    4241
    4342clean :
    44         @rm -frv ${DOCUMENT} ${BASE}.ps ${Build}
     43        @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build}
    4544
    4645# File Dependencies #
    4746
    48 ${DOCUMENT} : ${BASE}.ps
     47${DOCUMENT} : ${basename ${DOCUMENT}}.ps
    4948        ps2pdf $<
    5049
    51 ${BASE}.ps : ${BASE}.dvi
     50${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
    5251        dvips ${Build}/$< -o $@
    5352
    54 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
    55                 ../../bibliography/pl.bib | ${Build}
     53${basename ${DOCUMENT}}.dvi : Makefile ${Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ../../bibliography/pl.bib
    5654        # Must have *.aux file containing citations for bibtex
    5755        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
     
    6563## Define the default recipes.
    6664
    67 ${Build} :
     65${Build}:
    6866        mkdir -p ${Build}
    6967
     
    7169        gnuplot -e Build="'${Build}/'" evaluation/timing.gp
    7270
    73 %.tex : %.fig | ${Build}
     71%.tex : %.fig
    7472        fig2dev -L eepic $< > ${Build}/$@
    7573
    76 %.ps : %.fig | ${Build}
     74%.ps : %.fig
    7775        fig2dev -L ps $< > ${Build}/$@
    7876
    79 %.pstex : %.fig | ${Build}
     77%.pstex : %.fig
    8078        fig2dev -L pstex $< > ${Build}/$@
    8179        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
  • doc/papers/concurrency/Makefile

    r63238a4 rd286cf68  
    2020
    2121FIGURES = ${addsuffix .tex, \
     22monitor \
     23ext_monitor \
    2224int_monitor \
    2325dependency \
     
    2527
    2628PICTURES = ${addsuffix .pstex, \
    27 monitor \
    28 ext_monitor \
    2929system \
    3030monitor_structs \
     
    5959        dvips ${Build}/$< -o $@
    6060
    61 ${BASE}.dvi : Makefile ${BASE}.out.ps WileyNJD-AMA.bst ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
    62                 annex/local.bib ../../bibliography/pl.bib | ${Build}
     61${BASE}.dvi : Makefile ${Build} ${BASE}.out.ps WileyNJD-AMA.bst ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
     62                annex/local.bib ../../bibliography/pl.bib
    6363        # Must have *.aux file containing citations for bibtex
    6464        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
    65         -${BibTeX} ${Build}/${basename $@}
     65        ${BibTeX} ${Build}/${basename $@}
    6666        # Some citations reference others so run again to resolve these citations
    6767        ${LaTeX} ${basename $@}.tex
    68         -${BibTeX} ${Build}/${basename $@}
     68        ${BibTeX} ${Build}/${basename $@}
    6969        # Run again to finish citations
    7070        ${LaTeX} ${basename $@}.tex
     
    7272## Define the default recipes.
    7373
    74 ${Build} :
     74${Build}:
    7575        mkdir -p ${Build}
    7676
    77 ${BASE}.out.ps : | ${Build}
     77${BASE}.out.ps: ${Build}
    7878        ln -fs ${Build}/Paper.out.ps .
    7979
    80 WileyNJD-AMA.bst :
     80WileyNJD-AMA.bst:
    8181        ln -fs ../AMA/AMA-stix/ama/WileyNJD-AMA.bst .
    8282
    83 %.tex : %.fig | ${Build}
     83%.tex : %.fig ${Build}
    8484        fig2dev -L eepic $< > ${Build}/$@
    8585
    86 %.ps : %.fig | ${Build}
     86%.ps : %.fig ${Build}
    8787        fig2dev -L ps $< > ${Build}/$@
    8888
    89 %.pstex : %.fig | ${Build}
     89%.pstex : %.fig ${Build}
    9090        fig2dev -L pstex $< > ${Build}/$@
    9191        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
  • doc/papers/concurrency/Paper.tex

    r63238a4 rd286cf68  
    271271Hence, there are two problems to be solved: concurrency and parallelism.
    272272While these two concepts are often combined, they are distinct, requiring different tools~\cite[\S~2]{Buhr05a}.
    273 Concurrency tools handle mutual exclusion and synchronization, while parallelism tools handle performance, cost, and resource utilization.
     273Concurrency tools handle synchronization and mutual exclusion, while parallelism tools handle performance, cost and resource utilization.
    274274
    275275The proposed concurrency API is implemented in a dialect of C, called \CFA.
     
    282282Extended versions and explanation of the following code examples are available at the \CFA website~\cite{Cforall} or in Moss~\etal~\cite{Moss18}.
    283283
    284 \CFA is a non-object-oriented extension of ISO-C, and hence, supports all C paradigms.
     284\CFA is an extension of ISO-C, and hence, supports all C paradigms.
    285285%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 building blocks of \CFA are structures and routines.
     286Like C, the basics of \CFA revolve around structures and routines.
    287287Virtually all of the code generated by the \CFA translator respects C memory layouts and calling conventions.
    288288While \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}.
     
    296296int x = 1, y = 2, z = 3;
    297297int * p1 = &x, ** p2 = &p1,  *** p3 = &p2,      $\C{// pointers to x}$
    298     `&` r1 = x,   `&&` r2 = r1,   `&&&` r3 = r2;        $\C{// references to x}$
     298        `&` r1 = x,  `&&` r2 = r1,  `&&&` r3 = r2;      $\C{// references to x}$
    299299int * p4 = &z, `&` r4 = z;
    300300
     
    411411\end{cquote}
    412412Overloading is important for \CFA concurrency since the runtime system relies on creating different types to represent concurrency objects.
    413 Therefore, overloading eliminates long prefixes and other naming conventions to prevent name clashes.
     413Therefore, overloading is necessary to prevent the need for long prefixes and other naming conventions to prevent name clashes.
    414414As seen in Section~\ref{basics}, routine @main@ is heavily overloaded.
    415 For example, variable overloading is useful in the parallel semantics of the @with@ statement for fields with the same name:
     415
     416Variable overloading is useful in the parallel semantics of the @with@ statement for fields with the same name:
    416417\begin{cfa}
    417418struct S { int `i`; int j; double m; } s;
     
    427428}
    428429\end{cfa}
    429 For parallel semantics, both @s.i@ and @t.i@ are visible with the same type, so only @i@ is ambiguous without qualification.
     430For parallel semantics, both @s.i@ and @t.i@ are visible the same type, so only @i@ is ambiguous without qualification.
    430431
    431432
     
    467468\end{cquote}
    468469While 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
     475The 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.
     476For example, the following sum routine works for any type that supports construction from 0 and addition:
     477\begin{cfa}
     478forall( otype T | { void `?{}`( T *, zero_t ); T `?+?`( T, T ); } ) // constraint type, 0 and +
     479T 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}
     485S sa[5];
     486int 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}
     491trait `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};
     498forall( otype T `| sumable( T )` )                      $\C{// use trait}$
     499T sum( T a[$\,$], size_t size );
     500\end{cfa}
     501
     502Assertions 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
     506Using the return type for discrimination, it is possible to write a type-safe @alloc@ based on the C @malloc@:
     507\begin{cfa}
     508forall( dtype T | sized(T) ) T * alloc( void ) { return (T *)malloc( sizeof(T) ); }
     509int * ip = alloc();                                                     $\C{// select type and size from left-hand side}$
     510double * dp = alloc();
     511struct S {...} * sp = alloc();
     512\end{cfa}
     513where the return type supplies the type/size of the allocation, which is impossible in most type systems.
    469514
    470515
     
    495540\CFA also provides @new@ and @delete@, which behave like @malloc@ and @free@, in addition to constructing and destructing objects:
    496541\begin{cfa}
    497 {
    498         ... struct S s = {10}; ...                              $\C{// allocation, call constructor}$
     542{       struct S s = {10};                                              $\C{// allocation, call constructor}$
     543        ...
    499544}                                                                                       $\C{// deallocation, call destructor}$
    500545struct S * s = new();                                           $\C{// allocation, call constructor}$
     
    502547delete( s );                                                            $\C{// deallocation, call destructor}$
    503548\end{cfa}
    504 \CFA concurrency uses object lifetime as a means of mutual exclusion and/or synchronization.
    505 
    506 
    507 \subsection{Parametric Polymorphism}
    508 \label{s:ParametricPolymorphism}
    509 
    510 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.
    511 For example, the following sum routine works for any type that supports construction from 0 and addition:
    512 \begin{cfa}
    513 forall( otype T | { void `?{}`( T *, zero_t ); T `?+?`( T, T ); } ) // constraint type, 0 and +
    514 T sum( T a[$\,$], size_t size ) {
    515         `T` total = { `0` };                                    $\C{// initialize by 0 constructor}$
    516         for ( size_t i = 0; i < size; i += 1 )
    517                 total = total `+` a[i];                         $\C{// select appropriate +}$
    518         return total;
    519 }
    520 S sa[5];
    521 int i = sum( sa, 5 );                                           $\C{// use S's 0 construction and +}$
    522 \end{cfa}
    523 The builtin type @zero_t@ (and @one_t@) overload constant 0 (and 1) for a new types, where both 0 and 1 have special meaning in C.
    524 
    525 \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:
    526 \begin{cfa}
    527 trait `sumable`( otype T ) {
    528         void `?{}`( T &, zero_t );                              $\C{// 0 literal constructor}$
    529         T `?+?`( T, T );                                                $\C{// assortment of additions}$
    530         T ?+=?( T &, T );
    531         T ++?( T & );
    532         T ?++( T & );
    533 };
    534 forall( otype T `| sumable( T )` )                      $\C{// use trait}$
    535 T sum( T a[$\,$], size_t size );
    536 \end{cfa}
    537 
    538 Assertions can be @otype@ or @dtype@.
    539 @otype@ refers to a ``complete'' object, \ie an object has a size, default constructor, copy constructor, destructor and an assignment operator.
    540 @dtype@ only guarantees an object has a size and alignment.
    541 
    542 Using the return type for discrimination, it is possible to write a type-safe @alloc@ based on the C @malloc@:
    543 \begin{cfa}
    544 forall( dtype T | sized(T) ) T * alloc( void ) { return (T *)malloc( sizeof(T) ); }
    545 int * ip = alloc();                                                     $\C{// select type and size from left-hand side}$
    546 double * dp = alloc();
    547 struct S {...} * sp = alloc();
    548 \end{cfa}
    549 where the return type supplies the type/size of the allocation, which is impossible in most type systems.
     549\CFA concurrency uses object lifetime as a means of synchronization and/or mutual exclusion.
    550550
    551551
     
    727727
    728728Using 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, @`coroutine` Fib { int fn; }@, which provides communication, @fn@, for the \newterm{coroutine main}, @main@, which runs on the coroutine stack, and possibly multiple interface routines, \eg @next@.
     729Figure~\ref{f:Coroutine3States} creates a @coroutine@ type:
     730\begin{cfa}
     731`coroutine` Fib { int fn; };
     732\end{cfa}
     733which provides communication, @fn@, for the \newterm{coroutine main}, @main@, which runs on the coroutine stack, and possibly multiple interface routines @next@.
    730734Like 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.
    731 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@.
     735The 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.
    732736The interface routine @next@, takes a Fibonacci instance and context switches to it using @resume@;
    733737on restart, the Fibonacci field, @fn@, contains the next value in the sequence, which is returned.
     
    839843\end{figure}
    840844
    841 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.
    842 However,@resume@/@suspend@ context switch to existing stack-frames rather than create new ones so there is no stack growth.
     845The 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
     846However, there is no stack growth because @resume@/@suspend@ context switch to existing stack-frames rather than create new ones.
    843847\newterm{Symmetric (full) coroutine}s have a coroutine call a resuming routine for another coroutine, which eventually forms a resuming-call cycle.
    844848(The trivial cycle is a coroutine resuming itself.)
     
    929933The producer call to @delivery@ transfers values into the consumer's communication variables, resumes the consumer, and returns the consumer status.
    930934For the first resume, @cons@'s stack is initialized, creating local variables retained between subsequent activations of the coroutine.
    931 The 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).
     935The 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).
    932936The call from the consumer to the @payment@ introduces the cycle between producer and consumer.
    933937When @payment@ is called, the consumer copies values into the producer's communication variable and a resume is executed.
     
    959963\end{cfa}
    960964and the programming language (and possibly its tool set, \eg debugger) may need to understand @baseCoroutine@ because of the stack.
    961 Furthermore, the execution of constructs/destructors is in the wrong order for certain operations.
    962 For example, for threads 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.
     965Furthermore, 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.
    963967
    964968An alternatively is composition:
     
    980984symmetric_coroutine<>::yield_type
    981985\end{cfa}
    982 Similarly, the canonical threading paradigm is often based on routine pointers, \eg @pthreads@~\cite{pthreads}, \Csharp~\cite{Csharp}, Go~\cite{Go}, and Scala~\cite{Scala}.
     986Similarly, the canonical threading paradigm is often based on routine pointers, \eg @pthread@~\cite{pthreads}, \Csharp~\cite{Csharp}, Go~\cite{Go}, and Scala~\cite{Scala}.
    983987However, the generic thread-handle (identifier) is limited (few operations), unless it is wrapped in a custom type.
    984988\begin{cfa}
     
    9971001Note, the type @coroutine_t@ must be an abstract handle to the coroutine, because the coroutine descriptor and its stack are non-copyable.
    9981002Copying the coroutine descriptor results in copies being out of date with the current state of the stack.
    999 Correspondingly, copying the stack results is copies being out of date with the coroutine descriptor, and pointers in the stack being out of date to data on the stack.
     1003Correspondingly, 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.
    10001004(There is no mechanism in C to find all stack-specific pointers and update them as part of a copy.)
    10011005
     
    10111015Furthermore, implementing coroutines without language supports also displays the power of a programming language.
    10121016While this is ultimately the option used for idiomatic \CFA code, coroutines and threads can still be constructed without using the language support.
    1013 The reserved keyword simply eases use for the common cases.
     1017The reserved keyword eases use for the common cases.
    10141018
    10151019Part 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:
     
    10261030The @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.
    10271031The 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.
    1028 The 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@ routine, and possibly redefining @suspend@ and @resume@.
     1032The 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@.
    10291033The \CFA keyword @coroutine@ implicitly implements the getter and forward declarations required for implementing the coroutine main:
    10301034\begin{cquote}
     
    10941098The difference is that a coroutine borrows a thread from its caller, so the first thread resuming a coroutine creates an instance of @main@;
    10951099whereas, 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{
    1096 The \lstinline@main@ routine is already a special routine in C, \ie where the program's initial thread begins, so it is a natural extension of this semantics to use overloading to declare \lstinline@main@s for user coroutines and threads.}
     1100The \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).}
    10971101No 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.
    10981102
     
    11851189void main( Adder & adder ) with( adder ) {
    11861190    subtotal = 0;
    1187     for ( int c = 0; c < cols; c += 1 ) { subtotal += row[c]; }
     1191    for ( int c = 0; c < cols; c += 1 ) {
     1192                subtotal += row[c];
     1193    }
    11881194}
    11891195int main() {
     
    12101216
    12111217Uncontrolled non-deterministic execution is meaningless.
    1212 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}.
     1218To 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}.
    12131219Since 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).
    1214 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}.
    1215 However, in call/return-based languages, these approaches force a clear distinction, \ie introduce a new programming paradigm, between regular and concurrent computation, \eg routine call versus message passing.
     1220In 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}).
     1221However, 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).
    12161222Hence, a programmer must learn and manipulate two sets of design patterns.
    12171223While this distinction can be hidden away in library code, effective use of the library still has to take both paradigms into account.
     
    12381244However, many solutions exist for mutual exclusion, which vary in terms of performance, flexibility and ease of use.
    12391245Methods 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.
    1240 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.
    1241 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.
     1246Ease 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.
     1247For 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.
    12421248However, a significant challenge with locks is composability because it takes careful organization for multiple locks to be used while preventing deadlock.
    12431249Easing composability is another feature higher-level mutual-exclusion mechanisms can offer.
     
    12481254Synchronization enforces relative ordering of execution, and synchronization tools provide numerous mechanisms to establish these timing relationships.
    12491255Low-level synchronization primitives offer good performance and flexibility at the cost of ease of use;
    1250 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.
     1256higher-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.
    12511257Often 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.
    12521258If a writer thread is scheduled for next access, but another reader thread acquires the critical section first, that reader has \newterm{barged}.
     
    12661272The strong association with the call/return paradigm eases programmability, readability and maintainability, at a slight cost in flexibility and efficiency.
    12671273
    1268 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.
     1274Note, 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.
    12691275Copying 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.
    12701276Copying 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.
     
    13691375\end{cfa}
    13701376(While object-oriented monitors can be extended with a mutex qualifier for multiple-monitor members, no prior example of this feature could be found.)
    1371 In practice, writing multi-locking routines that do not deadlock is tricky.
     1377In practice, writing multi-locking routines that do not deadlocks is tricky.
    13721378Having language support for such a feature is therefore a significant asset for \CFA.
    13731379
    13741380The capability to acquire multiple locks before entering a critical section is called \newterm{bulk acquire}.
    1375 In the previous example, \CFA guarantees the order of acquisition is consistent across calls to different routines using the same monitors as arguments.
     1381In previous example, \CFA guarantees the order of acquisition is consistent across calls to different routines using the same monitors as arguments.
    13761382This consistent ordering means acquiring multiple monitors is safe from deadlock.
    13771383However, users can force the acquiring order.
     
    13891395In the calls to @bar@ and @baz@, the monitors are acquired in opposite order.
    13901396
    1391 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 rollback semantics~\cite{Dice10}.
     1397However, 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}.
    13921398In \CFA, safety is guaranteed by using bulk acquire of all monitors to shared objects, whereas other monitor systems provide no aid.
    13931399While \CFA provides only a partial solution, the \CFA partial solution handles many useful cases.
     
    14341440
    14351441
    1436 \section{Scheduling}
    1437 \label{s:Scheduling}
     1442\section{Internal Scheduling}
     1443\label{s:InternalScheduling}
    14381444
    14391445While monitor mutual-exclusion provides safe access to shared data, the monitor data may indicate that a thread accessing it cannot proceed.
     
    14481454The appropriate condition lock is signalled to unblock an opposite kind of thread after an element is inserted/removed from the buffer.
    14491455Signalling is unconditional, because signalling an empty condition lock does nothing.
    1450 
    14511456Signalling semantics cannot have the signaller and signalled thread in the monitor simultaneously, which means:
    14521457\begin{enumerate}
     
    14581463The signalling thread blocks but is marked for urgrent unblocking at the next scheduling point and the signalled thread continues.
    14591464\end{enumerate}
    1460 The first approach is too restrictive, as it precludes solving a reasonable class of problems, \eg dating service.
     1465The first approach is too restrictive, as it precludes solving a reasonable class of problems (\eg dating service).
    14611466\CFA supports the next two semantics as both are useful.
    14621467Finally, while it is common to store a @condition@ as a field of the monitor, in \CFA, a @condition@ variable can be created/stored independently.
     
    15341539If 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.
    15351540Threads making calls to routines that are currently excluded block outside (external) of the monitor on a calling queue, versus blocking on condition queues inside (internal) of the monitor.
    1536 % External scheduling is more constrained and explicit, which helps programmers reduce the non-deterministic nature of concurrency.
    1537 External scheduling allows users to wait for events from other threads without concern of unrelated events occurring.
    1538 The mechnaism can be done in terms of control flow, \eg Ada @accept@ or \uC @_Accept@, or in terms of data, \eg Go channels.
    1539 While both mechanisms have strengths and weaknesses, this project uses a control-flow mechanism to stay consistent with other language semantics.
    1540 Two challenges specific to \CFA for external scheduling are loose object-definitions (see Section~\ref{s:LooseObjectDefinitions}) and multiple-monitor routines (see Section~\ref{s:Multi-MonitorScheduling}).
    15411541
    15421542For internal scheduling, non-blocking signalling (as in the producer/consumer example) is used when the signaller is providing the cooperation for a waiting thread;
    15431543the 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.
    1544 The waiter unblocks next, uses/takes the state, and exits the monitor.
     1544The waiter unblocks next, takes the state, and exits the monitor.
    15451545Blocking signalling is the reverse, where the waiter is providing the cooperation for the signalling thread;
    15461546the 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.
    1547 The waiter changes state and exits the monitor, and the signaller unblocks next from the urgent queue to use/take the state.
     1547The waiter changes state and exits the monitor, and the signaller unblocks next from the urgent queue to take the state.
    15481548
    15491549Figure~\ref{f:DatingService} shows a dating service demonstrating the two forms of signalling: non-blocking and blocking.
    15501550The dating service matches girl and boy threads with matching compatibility codes so they can exchange phone numbers.
    15511551A thread blocks until an appropriate partner arrives.
    1552 The complexity is exchanging phone number in the monitor because the monitor mutual-exclusion property prevents exchanging numbers.
    1553 For internal scheduling, the @exchange@ condition is necessary to block the thread finding the match, while the matcher unblocks to take the oppose number, post its phone number, and unblock the partner.
    1554 For external scheduling, the implicit urgent-condition replaces the explict @exchange@-condition and @signal_block@ puts the finding thread on the urgent condition and unblocks the matcher..
    1555 
    1556 The 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;
    1557 as well, an arriving thread may not find a partner and must wait, which requires a condition variable, and condition variables imply internal scheduling.
     1552The complexity is exchanging phone number in the monitor,
     1553While the non-barging monitor prevents a caller from stealing a phone number, the monitor mutual-exclusion property
     1554
     1555The dating service is an example of a monitor that cannot be written using external scheduling because:
     1556
     1557The example in table \ref{tbl:datingservice} highlights the difference in behaviour.
     1558As mentioned, @signal@ only transfers ownership once the current critical section exits; this behaviour requires additional synchronization when a two-way handshake is needed.
     1559To avoid this explicit synchronization, the @condition@ type offers the @signal_block@ routine, which handles the two-way handshake as shown in the example.
     1560This feature removes the need for a second condition variables and simplifies programming.
     1561Like 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.
    15581562
    15591563\begin{figure}
     
    16511655}
    16521656\end{cfa}
    1653 must have acquired monitor locks that are greater than or equal to the number of locks for the waiting thread signalled from the condition queue.
     1657must have acquired monitor locks that are greater than or equal to the number of locks for the waiting thread signalled from the front of the condition queue.
     1658In general, the signaller does not know the order of waiting threads, so in general, it must acquire the maximum number of mutex locks for the worst-case waiting thread.
    16541659
    16551660Similarly, 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 )@.
     
    16621667void foo( M & mutex m1, M & mutex m2 ) {
    16631668        ... wait( `e, m1` ); ...                                $\C{// release m1, keeping m2 acquired )}$
    1664 void bar( M & mutex m1, M & mutex m2 ) {        $\C{// must acquire m1 and m2 )}$
     1669void baz( M & mutex m1, M & mutex m2 ) {        $\C{// must acquire m1 and m2 )}$
    16651670        ... signal( `e` ); ...
    16661671\end{cfa}
    1667 The @wait@ only releases @m1@ so the signalling thread cannot acquire both @m1@ and @m2@ to  enter @bar@ to get to the @signal@.
     1672The @wait@ only releases @m1@ so the signalling thread cannot acquire both @m1@ and @m2@ to  enter @baz@ to get to the @signal@.
    16681673While deadlock issues can occur with multiple/nesting acquisition, this issue results from the fact that locks, and by extension monitors, are not perfectly composable.
    16691674
     
    17501755However, Figure~\ref{f:OtherWaitingThread} shows this solution is complex depending on other waiters, resulting is choices when the signaller finishes the inner mutex-statement.
    17511756The singaller can retain @m2@ until completion of the outer mutex statement and pass the locks to waiter W1, or it can pass @m2@ to waiter W2 after completing the inner mutex-statement, while continuing to hold @m1@.
    1752 In the latter case, waiter W2 must eventually pass @m2@ to waiter W1, which is complex because W1 may have waited before W2, so W2 is unaware of it.
     1757In the latter case, waiter W2 must eventually pass @m2@ to waiter W1, which is complex because W2 may have waited before W1 so it is unaware of W1.
    17531758Furthermore, there is an execution sequence where the signaller always finds waiter W2, and hence, waiter W1 starves.
    17541759
     
    18511856The 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.
    18521857Resolving dependency graphs being a complex and expensive endeavour, this solution is not the preferred one.
     1858
     1859\subsubsection{Partial Signalling} \label{partial-sig}
    18531860\end{comment}
    18541861
    18551862
     1863\section{External scheduling} \label{extsched}
     1864
     1865An alternative to internal scheduling is external scheduling (see Table~\ref{tbl:sched}).
     1866
    18561867\begin{comment}
    1857 \section{External scheduling} \label{extsched}
    1858 
    18591868\begin{table}
    18601869\begin{tabular}{|c|c|c|}
     
    19201929\label{tbl:sched}
    19211930\end{table}
     1931\end{comment}
     1932
     1933This method is more constrained and explicit, which helps users reduce the non-deterministic nature of concurrency.
     1934Indeed, as the following examples demonstrate, external scheduling allows users to wait for events from other threads without the concern of unrelated events occurring.
     1935External 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).
     1936Of 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.
     1937Two challenges specific to \CFA arise when trying to add external scheduling with loose object definitions and multiple-monitor routines.
     1938The previous example shows a simple use @_Accept@ versus @wait@/@signal@ and its advantages.
     1939Note 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.
    19221940
    19231941For 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.
    19241942On the other hand, external scheduling guarantees that while routine @P@ is waiting, no other routine than @V@ can acquire the monitor.
    1925 \end{comment}
    1926 
    1927 
     1943
     1944% ======================================================================
     1945% ======================================================================
    19281946\subsection{Loose Object Definitions}
    1929 \label{s:LooseObjectDefinitions}
    1930 
    1931 In an object-oriented programming-language, a class includes an exhaustive list of operations.
    1932 However, new members can be added via static inheritance or dynaic members, \eg JavaScript~\cite{JavaScript}.
    1933 Similarly, monitor routines can be added at any time in \CFA, making it less clear for programmers and more difficult to implement.
    1934 \begin{cfa}
    1935 monitor M {};
    1936 void `f`( M & mutex m );
    1937 void g( M & mutex m ) { waitfor( `f` ); }       $\C{// clear which f}$
    1938 void `f`( M & mutex m, int );                           $\C{// different f}$
    1939 void h( M & mutex m ) { waitfor( `f` ); }       $\C{// unclear which f}$
    1940 \end{cfa}
    1941 Hence, the cfa-code for the entering a monitor looks like:
    1942 \begin{cfa}
    1943 if ( $\textrm{\textit{monitor is free}}$ ) $\LstCommentStyle{// \color{red}enter}$
    1944 else if ( $\textrm{\textit{already own monitor}}$ ) $\LstCommentStyle{// \color{red}continue}$
    1945 else if ( $\textrm{\textit{monitor accepts me}}$ ) $\LstCommentStyle{// \color{red}enter}$
    1946 else $\LstCommentStyle{// \color{red}block}$
    1947 \end{cfa}
     1947% ======================================================================
     1948% ======================================================================
     1949In \uC, a monitor class declaration includes an exhaustive list of monitor operations.
     1950Since \CFA is not object oriented, monitors become both more difficult to implement and less clear for a user:
     1951
     1952\begin{cfa}
     1953monitor A {};
     1954
     1955void f(A & mutex a);
     1956void g(A & mutex a) {
     1957        waitfor(f); // Obvious which f() to wait for
     1958}
     1959
     1960void f(A & mutex a, int); // New different F added in scope
     1961void h(A & mutex a) {
     1962        waitfor(f); // Less obvious which f() to wait for
     1963}
     1964\end{cfa}
     1965
     1966Furthermore, external scheduling is an example where implementation constraints become visible from the interface.
     1967Here is the cfa-code for the entering phase of a monitor:
     1968\begin{center}
     1969\begin{tabular}{l}
     1970\begin{cfa}
     1971        if monitor is free
     1972                enter
     1973        elif already own the monitor
     1974                continue
     1975        elif monitor accepts me
     1976                enter
     1977        else
     1978                block
     1979\end{cfa}
     1980\end{tabular}
     1981\end{center}
    19481982For the first two conditions, it is easy to implement a check that can evaluate the condition in a few instructions.
    1949 However, a fast check for \emph{monitor accepts me} is much harder to implement depending on the constraints put on the monitors.
    1950 Figure~\ref{fig:ClassicalMonitor} shows monitors are often expressed as an entry (calling) queue, some acceptor queues, and an urgent stack/queue.
     1983However, a fast check for @monitor accepts me@ is much harder to implement depending on the constraints put on the monitors.
     1984Indeed, monitors are often expressed as an entry queue and some acceptor queue as in Figure~\ref{fig:ClassicalMonitor}.
    19511985
    19521986\begin{figure}
    19531987\centering
    1954 \subfloat[Classical monitor] {
     1988\subfloat[Classical Monitor] {
    19551989\label{fig:ClassicalMonitor}
    1956 {\resizebox{0.45\textwidth}{!}{\input{monitor.pstex_t}}}
     1990{\resizebox{0.45\textwidth}{!}{\input{monitor}}}
    19571991}% subfloat
    1958 \quad
    1959 \subfloat[Bulk acquire monitor] {
     1992\qquad
     1993\subfloat[bulk acquire Monitor] {
    19601994\label{fig:BulkMonitor}
    1961 {\resizebox{0.45\textwidth}{!}{\input{ext_monitor.pstex_t}}}
     1995{\resizebox{0.45\textwidth}{!}{\input{ext_monitor}}}
    19621996}% subfloat
    1963 \caption{Monitor Implementation}
    1964 \label{f:MonitorImplementation}
     1997\caption{External Scheduling Monitor}
    19651998\end{figure}
    19661999
    1967 For a fixed (small) number of mutex routines (\eg 128), the accept check reduces to a bitmask of allowed callers, which can be checked with a single instruction.
    1968 This approach requires a unique dense ordering of routines with a small upper-bound and the ordering must be consistent across translation units.
    1969 For object-oriented languages these constraints are common, but \CFA mutex routines can be added in any scope and are only visible in certain translation unit, precluding program-wide dense-ordering among mutex routines.
    1970 
    1971 Figure~\ref{fig:BulkMonitor} shows the \CFA monitor implementation.
    1972 The mutex routine called is associated with each thread on the entry queue, while a list of acceptable routines is kept separately.
    1973 The accepted list is a variable-sized array of accepted routine pointers, so the single instruction bitmask comparison is replaced by dereferencing a pointer followed by a linear search.
    1974 
    1975 \begin{comment}
     2000There are other alternatives to these pictures, but in the case of the left picture, implementing a fast accept check is relatively easy.
     2001Restricted 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.
     2002This approach requires a unique dense ordering of routines with an upper-bound and that ordering must be consistent across translation units.
     2003For OO languages these constraints are common, since objects only offer adding member routines consistently across translation units via inheritance.
     2004However, in \CFA users can extend objects with mutex routines that are only visible in certain translation unit.
     2005This 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.
     2006
     2007The alternative is to alter the implementation as in Figure~\ref{fig:BulkMonitor}.
     2008Here, the mutex routine called is associated with a thread on the entry queue while a list of acceptable routines is kept separate.
     2009Generating a mask dynamically means that the storage for the mask information can vary between calls to @waitfor@, allowing for more flexibility and extensions.
     2010Storing an array of accepted routine pointers replaces the single instruction bitmask comparison with dereferencing a pointer followed by a linear search.
     2011Furthermore, 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.
     2012
    19762013\begin{figure}
    19772014\begin{cfa}[caption={Example of nested external scheduling},label={f:nest-ext}]
     
    19972034In the end, the most flexible approach has been chosen since it allows users to write programs that would otherwise be  hard to write.
    19982035This 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.
    1999 \end{comment}
    2000 
    2001 
     2036
     2037% ======================================================================
     2038% ======================================================================
    20022039\subsection{Multi-Monitor Scheduling}
    2003 \label{s:Multi-MonitorScheduling}
     2040% ======================================================================
     2041% ======================================================================
    20042042
    20052043External scheduling, like internal scheduling, becomes significantly more complex when introducing multi-monitor syntax.
    2006 Even in the simplest possible case, new semantics needs to be established:
     2044Even in the simplest possible case, some new semantics needs to be established:
    20072045\begin{cfa}
    20082046monitor M {};
    2009 void f( M & mutex m1 );
    2010 void g( M & mutex m1, M & mutex m2 ) {
    2011         waitfor( f );                                                   $\C{// pass m1 or m2 to f?}$
    2012 }
    2013 \end{cfa}
    2014 The solution is for the programmer to disambiguate:
    2015 \begin{cfa}
    2016         waitfor( f, m2 );                                               $\C{// wait for call to f with argument m2}$
    2017 \end{cfa}
    2018 Routine @g@ has acquired both locks, so when routine @f@ is called, the lock for monitor @m2@ is passed from @g@ to @f@ (while @g@ still holds lock @m1@).
    2019 This behaviour can be extended to the multi-monitor @waitfor@ statement.
     2047
     2048void f(M & mutex a);
     2049
     2050void g(M & mutex b, M & mutex c) {
     2051        waitfor(f); // two monitors M => unknown which to pass to f(M & mutex)
     2052}
     2053\end{cfa}
     2054The obvious solution is to specify the correct monitor as follows:
     2055
    20202056\begin{cfa}
    20212057monitor M {};
    2022 void f( M & mutex m1, M & mutex m2 );
    2023 void g( M & mutex m1, M & mutex m2 ) {
    2024         waitfor( f, m1, m2 );                                   $\C{// wait for call to f with arguments m1 and m2}$
    2025 }
    2026 \end{cfa}
    2027 Again, the set of monitors passed to the @waitfor@ statement must be entirely contained in the set of monitors already acquired by accepting routine.
     2058
     2059void f(M & mutex a);
     2060
     2061void g(M & mutex a, M & mutex b) {
     2062        // wait for call to f with argument b
     2063        waitfor(f, b);
     2064}
     2065\end{cfa}
     2066This syntax is unambiguous.
     2067Both locks are acquired and kept by @g@.
     2068When routine @f@ is called, the lock for monitor @b@ is temporarily transferred from @g@ to @f@ (while @g@ still holds lock @a@).
     2069This behaviour can be extended to the multi-monitor @waitfor@ statement as follows.
     2070
     2071\begin{cfa}
     2072monitor M {};
     2073
     2074void f(M & mutex a, M & mutex b);
     2075
     2076void g(M & mutex a, M & mutex b) {
     2077        // wait for call to f with arguments a and b
     2078        waitfor(f, a, b);
     2079}
     2080\end{cfa}
     2081
     2082Note 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.
    20282083
    20292084An important behaviour to note is when a set of monitors only match partially:
     2085
    20302086\begin{cfa}
    20312087mutex struct A {};
     2088
    20322089mutex struct B {};
    2033 void g( A & mutex m1, B & mutex m2 ) {
    2034         waitfor( f, m1, m2 );
    2035 }
     2090
     2091void g(A & mutex a, B & mutex b) {
     2092        waitfor(f, a, b);
     2093}
     2094
    20362095A a1, a2;
    20372096B b;
     2097
    20382098void foo() {
    2039         g( a1, b ); // block on accept
    2040 }
     2099        g(a1, b); // block on accept
     2100}
     2101
    20412102void bar() {
    2042         f( a2, b ); // fulfill cooperation
     2103        f(a2, b); // fulfill cooperation
    20432104}
    20442105\end{cfa}
     
    20472108It 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.
    20482109
    2049 
     2110% ======================================================================
     2111% ======================================================================
    20502112\subsection{\protect\lstinline|waitfor| Semantics}
     2113% ======================================================================
     2114% ======================================================================
    20512115
    20522116Syntactically, the @waitfor@ statement takes a routine identifier and a set of monitors.
     
    21472211\end{figure}
    21482212
    2149 
     2213% ======================================================================
     2214% ======================================================================
    21502215\subsection{Waiting For The Destructor}
    2151 
     2216% ======================================================================
     2217% ======================================================================
    21522218An interesting use for the @waitfor@ statement is destructor semantics.
    21532219Indeed, the @waitfor@ statement can accept any @mutex@ routine, which includes the destructor (see section \ref{data}).
     
    21762242
    21772243
     2244% ######     #    ######     #    #       #       ####### #       ###  #####  #     #
     2245% #     #   # #   #     #   # #   #       #       #       #        #  #     # ##   ##
     2246% #     #  #   #  #     #  #   #  #       #       #       #        #  #       # # # #
     2247% ######  #     # ######  #     # #       #       #####   #        #   #####  #  #  #
     2248% #       ####### #   #   ####### #       #       #       #        #        # #     #
     2249% #       #     # #    #  #     # #       #       #       #        #  #     # #     #
     2250% #       #     # #     # #     # ####### ####### ####### ####### ###  #####  #     #
    21782251\section{Parallelism}
    2179 
    21802252Historically, computer performance was about processor speeds and instruction counts.
    21812253However, with heat dissipation being a direct consequence of speed increase, parallelism has become the new source for increased performance~\cite{Sutter05, Sutter05b}.
     
    21872259While 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.
    21882260
    2189 
    21902261\section{Paradigms}
    2191 
    2192 
    21932262\subsection{User-Level Threads}
    2194 
    21952263A direct improvement on the \textbf{kthread} approach is to use \textbf{uthread}.
    21962264These threads offer most of the same features that the operating system already provides but can be used on a much larger scale.
     
    22012269Examples of languages that support \textbf{uthread} are Erlang~\cite{Erlang} and \uC~\cite{uC++book}.
    22022270
    2203 
    22042271\subsection{Fibers : User-Level Threads Without Preemption} \label{fibers}
    2205 
    22062272A popular variant of \textbf{uthread} is what is often referred to as \textbf{fiber}.
    22072273However, \textbf{fiber} do not present meaningful semantic differences with \textbf{uthread}.
     
    22122278An example of a language that uses fibers is Go~\cite{Go}
    22132279
    2214 
    22152280\subsection{Jobs and Thread Pools}
    2216 
    22172281An approach on the opposite end of the spectrum is to base parallelism on \textbf{pool}.
    22182282Indeed, \textbf{pool} offer limited flexibility but at the benefit of a simpler user interface.
     
    22252289The gold standard of this implementation is Intel's TBB library~\cite{TBB}.
    22262290
    2227 
    22282291\subsection{Paradigm Performance}
    2229 
    22302292While 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.
    22312293Indeed, in many situations one of these paradigms may show better performance but it all strongly depends on the workload.
     
    22352297Finally, if the units of uninterrupted work are large, enough the paradigm choice is largely amortized by the actual work done.
    22362298
    2237 
    22382299\section{The \protect\CFA\ Kernel : Processors, Clusters and Threads}\label{kernel}
    2239 
    22402300A \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}.
    22412301It 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.
     
    22452305Currently \CFA only supports one \textbf{cfacluster}, the initial one.
    22462306
    2247 
    22482307\subsection{Future Work: Machine Setup}\label{machine}
    2249 
    22502308While this was not done in the context of this paper, another important aspect of clusters is affinity.
    22512309While many common desktop and laptop PCs have homogeneous CPUs, other devices often have more heterogeneous setups.
     
    22532311OS 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.
    22542312
    2255 
    22562313\subsection{Paradigms}\label{cfaparadigms}
    2257 
    22582314Given these building blocks, it is possible to reproduce all three of the popular paradigms.
    22592315Indeed, \textbf{uthread} is the default paradigm in \CFA.
     
    22632319
    22642320
     2321
    22652322\section{Behind the Scenes}
    2266 
    22672323There are several challenges specific to \CFA when implementing concurrency.
    22682324These challenges are a direct result of bulk acquire and loose object definitions.
     
    22812337Note 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.
    22822338
    2283 
     2339% ======================================================================
     2340% ======================================================================
    22842341\section{Mutex Routines}
     2342% ======================================================================
     2343% ======================================================================
    22852344
    22862345The first step towards the monitor implementation is simple @mutex@ routines.
     
    23172376\end{figure}
    23182377
    2319 
    23202378\subsection{Details: Interaction with polymorphism}
    2321 
    23222379Depending 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.
    23232380However, it is shown that entry-point locking solves most of the issues.
     
    23992456Furthermore, 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.
    24002457
    2401 
     2458% ======================================================================
     2459% ======================================================================
    24022460\section{Threading} \label{impl:thread}
     2461% ======================================================================
     2462% ======================================================================
    24032463
    24042464Figure \ref{fig:system1} shows a high-level picture if the \CFA runtime system in regards to concurrency.
     
    24132473\end{figure}
    24142474
    2415 
    24162475\subsection{Processors}
    2417 
    24182476Parallelism 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.
    24192477Indeed, any parallelism must go through operating-system libraries.
     
    24232481Processors internally use coroutines to take advantage of the existing context-switching semantics.
    24242482
    2425 
    24262483\subsection{Stack Management}
    2427 
    24282484One of the challenges of this system is to reduce the footprint as much as possible.
    24292485Specifically, all @pthread@s created also have a stack created with them, which should be used as much as possible.
     
    24322488In 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.
    24332489
    2434 
    24352490\subsection{Context Switching}
    2436 
    24372491As 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.
    24382492To improve performance and simplicity, context-switching is implemented using the following assumption: all context-switches happen inside a specific routine call.
     
    24482502This option is not currently present in \CFA, but the changes required to add it are strictly additive.
    24492503
    2450 
    24512504\subsection{Preemption} \label{preemption}
    2452 
    24532505Finally, an important aspect for any complete threading system is preemption.
    24542506As 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.
     
    24842536Indeed, @sigwait@ can differentiate signals sent from @pthread_sigqueue@ from signals sent from alarms or the kernel.
    24852537
    2486 
    24872538\subsection{Scheduler}
    24882539Finally, an aspect that was not mentioned yet is the scheduling algorithm.
     
    24902541Further discussion on scheduling is present in section \ref{futur:sched}.
    24912542
    2492 
     2543% ======================================================================
     2544% ======================================================================
    24932545\section{Internal Scheduling} \label{impl:intsched}
    2494 
     2546% ======================================================================
     2547% ======================================================================
    24952548The following figure is the traditional illustration of a monitor (repeated from page~\pageref{fig:ClassicalMonitor} for convenience):
    24962549
    24972550\begin{figure}
    24982551\begin{center}
    2499 {\resizebox{0.4\textwidth}{!}{\input{monitor.pstex_t}}}
     2552{\resizebox{0.4\textwidth}{!}{\input{monitor}}}
    25002553\end{center}
    25012554\caption{Traditional illustration of a monitor}
  • doc/papers/concurrency/figures/ext_monitor.fig

    r63238a4 rd286cf68  
    88-2
    991200 2
    10 5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 1575.000 3450.000 1575 3150 1275 3450 1575 3750
    11 5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 1575.000 4350.000 1575 4050 1275 4350 1575 4650
    12 6 4275 1950 4575 2250
    13 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4425 2100 105 105 4425 2100 4530 2205
    14 4 1 -1 0 0 0 10 0.0000 2 105 90 4425 2160 d\001
     105 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 3150.000 3450.000 3150 3150 2850 3450 3150 3750
     115 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 3150.000 4350.000 3150 4050 2850 4350 3150 4650
     126 5850 1950 6150 2250
     131 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 2100 105 105 6000 2100 6105 2205
     144 1 -1 0 0 0 10 0.0000 2 105 90 6000 2160 d\001
    1515-6
    16 6 4275 1650 4575 1950
    17 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4425 1800 105 105 4425 1800 4530 1905
    18 4 1 -1 0 0 0 10 0.0000 2 105 90 4425 1860 b\001
     166 5100 2100 5400 2400
     171 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 5250 2250 105 105 5250 2250 5355 2250
     184 1 -1 0 0 0 10 0.0000 2 105 120 5250 2295 X\001
    1919-6
    20 6 1495 5445 5700 5655
    21 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 1575 5550 80 80 1575 5550 1655 5630
    22 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 2925 5550 105 105 2925 5550 3030 5655
    23 1 3 0 1 -1 -1 0 0 4 0.000 1 0.0000 4425 5550 105 105 4425 5550 4530 5655
    24 4 0 -1 0 0 0 12 0.0000 2 135 1035 3150 5625 blocked task\001
    25 4 0 -1 0 0 0 12 0.0000 2 135 870 1725 5625 active task\001
    26 4 0 -1 0 0 0 12 0.0000 2 135 1050 4650 5625 routine mask\001
     206 5100 1800 5400 2100
     211 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 5250 1950 105 105 5250 1950 5355 1950
     224 1 -1 0 0 0 10 0.0000 2 105 120 5250 2010 Y\001
    2723-6
    28 6 3525 1800 3825 2400
    29 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 3675 1950 105 105 3675 1950 3780 1950
     246 5850 1650 6150 1950
     251 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 1800 105 105 6000 1800 6105 1905
     264 1 -1 0 0 0 10 0.0000 2 105 90 6000 1860 b\001
     27-6
     286 3070 5445 7275 5655
     291 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 3150 5550 80 80 3150 5550 3230 5630
     301 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4500 5550 105 105 4500 5550 4605 5655
     311 3 0 1 -1 -1 0 0 4 0.000 1 0.0000 6000 5550 105 105 6000 5550 6105 5655
     324 0 -1 0 0 0 12 0.0000 2 135 1035 4725 5625 blocked task\001
     334 0 -1 0 0 0 12 0.0000 2 135 870 3300 5625 active task\001
     344 0 -1 0 0 0 12 0.0000 2 135 1050 6225 5625 routine mask\001
     35-6
     361 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 3300 3600 105 105 3300 3600 3405 3705
     371 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 3600 3600 105 105 3600 3600 3705 3705
     381 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6600 3900 105 105 6600 3900 6705 4005
     391 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6900 3900 105 105 6900 3900 7005 4005
     401 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 2700 105 105 6000 2700 6105 2805
     411 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 2400 105 105 6000 2400 6105 2505
     421 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 5100 4575 80 80 5100 4575 5180 4655
    30432 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
    31          3525 1800 3825 1800 3825 2400 3525 2400 3525 1800
    32 4 1 4 0 0 0 10 0.0000 2 105 120 3675 2010 Y\001
    33 -6
    34 6 3525 2100 3825 2400
    35 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 3675 2250 105 105 3675 2250 3780 2250
    36 4 1 4 0 0 0 10 0.0000 2 105 120 3675 2295 X\001
    37 -6
    38 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 1725 3600 105 105 1725 3600 1830 3705
    39 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 2025 3600 105 105 2025 3600 2130 3705
    40 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 5025 3900 105 105 5025 3900 5130 4005
    41 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 5325 3900 105 105 5325 3900 5430 4005
    42 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4425 2700 105 105 4425 2700 4530 2805
    43 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4425 2400 105 105 4425 2400 4530 2505
    44 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 3525 4575 80 80 3525 4575 3605 4655
     44         4050 2925 5475 2925 5475 3225 4050 3225 4050 2925
     452 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4
     46         3150 3750 3750 3750 3750 4050 3150 4050
     472 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3
     48         3150 3450 3750 3450 3900 3675
     492 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2
     50         3750 3150 3600 3375
     512 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3
     52         3150 4350 3750 4350 3900 4575
     532 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2
     54         3750 4050 3600 4275
     552 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4
     56         3150 4650 3750 4650 3750 4950 4950 4950
     572 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2
     58         6450 3750 6300 3975
     592 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2
     60         4950 4950 5175 5100
     612 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 9
     62         5250 4950 6450 4950 6450 4050 7050 4050 7050 3750 6450 3750
     63         6450 2850 6150 2850 6150 1650
     642 2 1 1 -1 -1 0 0 -1 4.000 0 0 0 0 0 5
     65         5850 4200 5850 3300 4350 3300 4350 4200 5850 4200
     662 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2
     67        1 1 1.00 60.00 120.00
     68        7 1 1.00 60.00 120.00
     69         5250 3150 5250 2400
     702 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
     71         3150 3150 3750 3150 3750 2850 5700 2850 5700 1650
     722 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
     73         5700 2850 6150 3000
    45742 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
    46          2475 2925 3900 2925 3900 3225 2475 3225 2475 2925
    47 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4
    48          1575 3750 2175 3750 2175 4050 1575 4050
    49 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3
    50          1575 3450 2175 3450 2325 3675
    51 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2
    52          2175 3150 2025 3375
    53 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3
    54          1575 4350 2175 4350 2325 4575
    55 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2
    56          2175 4050 2025 4275
    57 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4
    58          1575 4650 2175 4650 2175 4950 3375 4950
    59 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2
    60          4875 3750 4725 3975
    61 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2
    62          3375 4950 3600 5100
    63 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 9
    64          3675 4950 4875 4950 4875 4050 5475 4050 5475 3750 4875 3750
    65          4875 2850 4575 2850 4575 1650
    66 2 2 1 1 -1 -1 0 0 -1 4.000 0 0 0 0 0 5
    67          4275 4200 4275 3300 2775 3300 2775 4200 4275 4200
    68 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
    69         1 1 1.00 60.00 120.00
    70          3675 3075 3675 2400
    71 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
    72          4125 2850 4575 3000
    73 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
    74          1575 3150 2175 3150 2175 2850 4125 2850 4125 1650
    75 4 1 -1 0 0 0 10 0.0000 2 75 75 4425 2745 a\001
    76 4 1 -1 0 0 0 10 0.0000 2 75 75 4425 2445 c\001
    77 4 1 -1 0 0 0 12 0.0000 2 135 315 3525 5325 exit\001
    78 4 1 -1 0 0 0 12 0.0000 2 135 135 1725 3075 A\001
    79 4 1 -1 0 0 0 12 0.0000 2 135 795 1725 4875 condition\001
    80 4 1 -1 0 0 0 12 0.0000 2 135 135 1725 5100 B\001
    81 4 0 -1 0 0 0 12 0.0000 2 135 420 5025 3675 stack\001
    82 4 0 -1 0 0 0 12 0.0000 2 180 750 5025 3225 acceptor/\001
    83 4 0 -1 0 0 0 12 0.0000 2 180 750 5025 3450 signalled\001
    84 4 1 -1 0 0 0 12 0.0000 2 135 795 1725 2850 condition\001
    85 4 1 -1 0 0 0 12 0.0000 2 165 420 4425 1350 entry\001
    86 4 1 -1 0 0 0 12 0.0000 2 135 495 4425 1575 queue\001
    87 4 0 -1 0 0 0 12 0.0000 2 135 525 4725 2400 arrival\001
    88 4 0 -1 0 0 0 12 0.0000 2 135 630 4725 2175 order of\001
    89 4 1 -1 0 0 0 12 0.0000 2 135 525 3525 3675 shared\001
    90 4 1 -1 0 0 0 12 0.0000 2 135 735 3525 3975 variables\001
    91 4 0 4 50 -1 0 11 0.0000 2 120 135 4150 1875 Y\001
    92 4 0 4 50 -1 0 11 0.0000 2 120 105 4150 2175 Z\001
    93 4 0 4 50 -1 0 11 0.0000 2 120 135 4150 2475 X\001
    94 4 0 4 50 -1 0 11 0.0000 2 120 165 4150 2775 W\001
    95 4 0 -1 0 0 3 12 0.0000 2 150 540 5025 4275 urgent\001
    96 4 1 0 50 -1 0 11 0.0000 2 165 600 3150 3150 accepted\001
     75         5100 1800 5400 1800 5400 2400 5100 2400 5100 1800
     764 1 -1 0 0 0 10 0.0000 2 75 75 6000 2745 a\001
     774 1 -1 0 0 0 10 0.0000 2 75 75 6000 2445 c\001
     784 1 -1 0 0 0 12 0.0000 2 135 315 5100 5325 exit\001
     794 1 -1 0 0 0 12 0.0000 2 135 135 3300 3075 A\001
     804 1 -1 0 0 0 12 0.0000 2 135 795 3300 4875 condition\001
     814 1 -1 0 0 0 12 0.0000 2 135 135 3300 5100 B\001
     824 0 -1 0 0 0 12 0.0000 2 135 420 6600 3675 stack\001
     834 0 -1 0 0 0 12 0.0000 2 180 750 6600 3225 acceptor/\001
     844 0 -1 0 0 0 12 0.0000 2 180 750 6600 3450 signalled\001
     854 1 -1 0 0 0 12 0.0000 2 135 795 3300 2850 condition\001
     864 1 -1 0 0 0 12 0.0000 2 165 420 6000 1350 entry\001
     874 1 -1 0 0 0 12 0.0000 2 135 495 6000 1575 queue\001
     884 0 -1 0 0 0 12 0.0000 2 135 525 6300 2400 arrival\001
     894 0 -1 0 0 0 12 0.0000 2 135 630 6300 2175 order of\001
     904 1 -1 0 0 0 12 0.0000 2 135 525 5100 3675 shared\001
     914 1 -1 0 0 0 12 0.0000 2 135 735 5100 3975 variables\001
     924 0 0 50 -1 0 11 0.0000 2 165 855 4275 3150 Acceptables\001
     934 0 0 50 -1 0 11 0.0000 2 120 165 5775 2700 W\001
     944 0 0 50 -1 0 11 0.0000 2 120 135 5775 2400 X\001
     954 0 0 50 -1 0 11 0.0000 2 120 105 5775 2100 Z\001
     964 0 0 50 -1 0 11 0.0000 2 120 135 5775 1800 Y\001
  • doc/papers/concurrency/figures/monitor.fig

    r63238a4 rd286cf68  
    72722 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4
    7373         3600 1500 3600 2100 4200 2100 4200 900
     742 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4
     75         2700 1500 2700 2100 3300 2100 3300 1500
    74762 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 9
    7577         3600 4200 4800 4200 4800 3300 5400 3300 5400 3000 4800 3000
     
    77792 2 1 1 -1 -1 0 0 -1 4.000 0 0 0 0 0 5
    7880         4200 3450 4200 2550 2700 2550 2700 3450 4200 3450
    79 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4
    80          2700 1500 2700 2100 3300 2100 3300 1500
    81814 1 -1 0 0 0 10 0.0000 2 75 75 4350 1995 a\001
    82824 1 -1 0 0 0 10 0.0000 2 75 75 4350 1695 c\001
     
    89894 0 -1 0 0 0 12 0.0000 2 180 750 4950 2700 signalled\001
    90904 1 -1 0 0 0 12 0.0000 2 135 795 1650 2100 condition\001
    91 4 1 4 0 0 0 12 0.0000 2 135 135 2550 1425 X\001
    92 4 1 4 0 0 0 12 0.0000 2 135 135 3450 1425 Y\001
     914 1 -1 0 0 0 12 0.0000 2 135 135 2550 1425 X\001
     924 1 -1 0 0 0 12 0.0000 2 135 135 3450 1425 Y\001
    93934 1 -1 0 0 0 12 0.0000 2 165 420 4350 600 entry\001
    94944 1 -1 0 0 0 12 0.0000 2 135 495 4350 825 queue\001
     
    1001004 1 -1 0 0 0 10 0.0000 2 75 75 3450 1995 c\001
    1011014 1 -1 0 0 0 12 0.0000 2 135 570 3000 1200 queues\001
    102 4 0 -1 0 0 3 12 0.0000 2 150 540 4950 3525 urgent\001
  • doc/papers/general/Makefile

    r63238a4 rd286cf68  
    5959        dvips ${Build}/$< -o $@
    6060
    61 ${BASE}.dvi : Makefile ${BASE}.out.ps WileyNJD-AMA.bst ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
    62                 ../../bibliography/pl.bib | ${Build}
     61${BASE}.dvi : Makefile ${Build} ${BASE}.out.ps WileyNJD-AMA.bst ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
     62                ../../bibliography/pl.bib
    6363        # Must have *.aux file containing citations for bibtex
    6464        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
     
    7575        mkdir -p ${Build}
    7676
    77 ${BASE}.out.ps : | ${Build}
     77${BASE}.out.ps : ${Build}
    7878        ln -fs ${Build}/Paper.out.ps .
    7979
     
    8484        gnuplot -e Build="'${Build}/'" evaluation/timing.gp
    8585
    86 %.tex : %.fig | ${Build}
     86%.tex : %.fig ${Build}
    8787        fig2dev -L eepic $< > ${Build}/$@
    8888
    89 %.ps : %.fig | ${Build}
     89%.ps : %.fig ${Build}
    9090        fig2dev -L ps $< > ${Build}/$@
    9191
    92 %.pstex : %.fig | ${Build}
     92%.pstex : %.fig ${Build}
    9393        fig2dev -L pstex $< > ${Build}/$@
    9494        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
  • doc/proposals/ctordtor/Makefile

    r63238a4 rd286cf68  
    1 ## Define the configuration variables.
     1## Define the appropriate configuration variables.
    22
    3 Build = build
    4 Figures = figures
    5 Macros = ../../LaTeXmacros
    6 Bib = ../../bibliography
     3MACROS = ../../LaTeXmacros
     4BIB = ../../bibliography
    75
    8 TeXLIB = .:${Macros}:${MACROS}/listings:${MACROS}/enumitem:${Bib}/:
    9 LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build}
     6TeXLIB = .:$(MACROS):$(MACROS)/listings:$(MACROS)/enumitem:$(BIB)/:
     7LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error
    108BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
    11 
    12 MAKEFLAGS = --no-print-directory # --silent
    13 VPATH = ${Build} ${Figures}
    149
    1510## Define the text source files.
     
    3429
    3530DOCUMENT = ctor.pdf
    36 BASE = ${basename ${DOCUMENT}}
    3731
    3832# Directives #
    39 
    40 .PHONY : all clean                                      # not file names
    4133
    4234all : ${DOCUMENT}
    4335
    4436clean :
    45         @rm -frv ${DOCUMENT} ${BASE}.ps ${Build}
     37        rm -f *.bbl *.aux *.dvi *.idx *.ilg *.ind *.brf *.out *.log *.toc *.blg *.pstex_t *.cf \
     38                ${FIGURES} ${PICTURES} ${PROGRAMS} ${GRAPHS} ${basename ${DOCUMENT}}.ps ${DOCUMENT}
    4639
    4740# File Dependencies #
    4841
    49 ${DOCUMENT} : ${BASE}.ps
     42${DOCUMENT} : ${basename ${DOCUMENT}}.ps
    5043        ps2pdf $<
    5144
    52 ${BASE}.ps : ${BASE}.dvi
    53         dvips ${Build}/$< -o $@
     45${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
     46        dvips $< -o $@
    5447
    55 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
    56                 ${Macros}/common.tex ${Macros}/indexstyle ${Bib}/pl.bib | ${Build}
     48${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \
     49                $(MACROS)/common.tex $(MACROS)/indexstyle $(BIB)/cfa.bib
    5750        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    58         #if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi
     51        if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi
    5952        # Must have *.aux file containing citations for bibtex
    6053        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
    61         -${BibTeX} ${Build}/${basename $@}
    62         # Some citations reference others so run again to resolve these citations
     54        -${BibTeX} ${basename $@}
     55        # Some citations reference others so run steps again to resolve these citations
    6356        ${LaTeX} ${basename $@}.tex
    64         -${BibTeX} ${Build}/${basename $@}
     57        -${BibTeX} ${basename $@}
    6558        # Make index from *.aux entries and input index at end of document
    66         #makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx
    67         # Run again to finish citations
     59        makeindex -s $(MACROS)/indexstyle ${basename $@}.idx
    6860        ${LaTeX} ${basename $@}.tex
    6961        # Run again to get index title into table of contents
     
    7567## Define the default recipes.
    7668
    77 ${Build}:
    78         mkdir -p ${Build}
     69%.tex : %.fig
     70        fig2dev -L eepic $< > $@
    7971
    80 %.tex : %.fig | ${Build}
    81         fig2dev -L eepic $< > ${Build}/$@
     72%.ps : %.fig
     73        fig2dev -L ps $< > $@
    8274
    83 %.ps : %.fig | ${Build}
    84         fig2dev -L ps $< > ${Build}/$@
    85 
    86 %.pstex : %.fig | ${Build}
    87         fig2dev -L pstex $< > ${Build}/$@
    88         fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
     75%.pstex : %.fig
     76        fig2dev -L pstex $< > $@
     77        fig2dev -L pstex_t -p $@ $< > $@_t
    8978
    9079# Local Variables: #
  • doc/proposals/ctordtor/ctor.tex

    r63238a4 rd286cf68  
     1% inline code ©...© (copyright symbol) emacs: C-q M-)
     2% red highlighting ®...® (registered trademark symbol) emacs: C-q M-.
     3% blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_
     4% green highlighting ¢...¢ (cent symbol) emacs: C-q M-"
     5% LaTex escape §...§ (section symbol) emacs: C-q M-'
     6% keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^
     7% math escape $...$ (dollar symbol)
     8
    19\documentclass[twoside,11pt]{article}
    210
     
    715\usepackage{textcomp}
    816\usepackage[latin1]{inputenc}
    9 
    1017\usepackage{fullpage,times,comment}
    1118\usepackage{epic,eepic}
    12 \usepackage{upquote}                                    % switch curled `'" to straight
     19\usepackage{upquote}                                                                    % switch curled `'" to straight
    1320\usepackage{calc}
    1421\usepackage{xspace}
    1522\usepackage{graphicx}
    16 \usepackage{varioref}                                   % extended references
    17 \usepackage{listings}                                   % format program code
    18 \usepackage[flushmargin]{footmisc}                      % support label/reference in footnote
     23\usepackage{varioref}                                                                   % extended references
     24\usepackage{listings}                                                                   % format program code
     25\usepackage[flushmargin]{footmisc}                                              % support label/reference in footnote
    1926\usepackage{latexsym}                                   % \Box glyph
    2027\usepackage{mathptmx}                                   % better math font with "times"
     
    2734\renewcommand{\UrlFont}{\small\sf}
    2835
    29 \setlength{\topmargin}{-0.45in}                         % move running title into header
     36\setlength{\topmargin}{-0.45in}                                                 % move running title into header
    3037\setlength{\headsep}{0.25in}
    3138
     
    3643
    3744\interfootnotelinepenalty=10000
    38 
    39 \CFAStyle                                               % use default CFA format-style
    40 % inline code ©...© (copyright symbol) emacs: C-q M-)
    41 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-.
    42 % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_
    43 % green highlighting ¢...¢ (cent symbol) emacs: C-q M-"
    44 % LaTex escape §...§ (section symbol) emacs: C-q M-'
    45 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^
    46 % math escape $...$ (dollar symbol)
    47 
    4845
    4946\title{
     
    8683\thispagestyle{plain}
    8784\pagenumbering{arabic}
     85
    8886
    8987
  • doc/proposals/tuples/Makefile

    r63238a4 rd286cf68  
    1 ## Define the configuration variables.
     1## Define the appropriate configuration variables.
    22
    3 Build = build
    4 Figures = figures
    5 Macros = ../../LaTeXmacros
    6 Bib = ../../bibliography
     3MACROS = ../../LaTeXmacros
     4BIB = ../../bibliography
    75
    8 TeXLIB = .:${Macros}:${MACROS}/listings:${MACROS}/enumitem:${Bib}/:
    9 LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build}
     6TeXLIB = .:$(MACROS):$(MACROS)/listings:$(MACROS)/enumitem:$(BIB)/:
     7LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error
    108BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
    11 
    12 MAKEFLAGS = --no-print-directory --silent #
    13 VPATH = ${Build} ${Figures}
    149
    1510## Define the text source files.
     
    3429
    3530DOCUMENT = tuples.pdf
    36 BASE = ${basename ${DOCUMENT}}
    3731
    3832# Directives #
    39 
    40 .PHONY : all clean                                      # not file names
    4133
    4234all : ${DOCUMENT}
    4335
    4436clean :
    45         @rm -frv ${DOCUMENT} ${BASE}.ps ${Build}
     37        rm -f *.bbl *.aux *.dvi *.idx *.ilg *.ind *.brf *.out *.log *.toc *.blg *.pstex_t *.cf \
     38                ${FIGURES} ${PICTURES} ${PROGRAMS} ${GRAPHS} ${basename ${DOCUMENT}}.ps ${DOCUMENT}
    4639
    4740# File Dependencies #
    4841
    49 ${DOCUMENT} : ${BASE}.ps
     42${DOCUMENT} : ${basename ${DOCUMENT}}.ps
    5043        ps2pdf $<
    5144
    52 ${BASE}.ps : ${BASE}.dvi
    53         dvips ${Build}/$< -o $@
     45${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
     46        dvips $< -o $@
    5447
    55 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
    56                 ${Macros}/common.tex ${Macros}/indexstyle ${Bib}/pl.bib | ${Build}
     48${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \
     49                $(MACROS)/common.tex $(MACROS)/indexstyle $(BIB)/cfa.bib
    5750        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    58         #if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi
     51        if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi
    5952        # Must have *.aux file containing citations for bibtex
    6053        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
    61         -${BibTeX} ${Build}/${basename $@}
    62         # Some citations reference others so run again to resolve these citations
     54        -${BibTeX} ${basename $@}
     55        # Some citations reference others so run steps again to resolve these citations
    6356        ${LaTeX} ${basename $@}.tex
    64         -${BibTeX} ${Build}/${basename $@}
     57        -${BibTeX} ${basename $@}
    6558        # Make index from *.aux entries and input index at end of document
    66         #makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx
    67         # Run again to finish citations
     59        makeindex -s $(MACROS)/indexstyle ${basename $@}.idx
    6860        ${LaTeX} ${basename $@}.tex
    6961        # Run again to get index title into table of contents
     
    7567## Define the default recipes.
    7668
    77 ${Build}:
    78         mkdir -p ${Build}
     69%.tex : %.fig
     70        fig2dev -L eepic $< > $@
    7971
    80 %.tex : %.fig | ${Build}
    81         fig2dev -L eepic $< > ${Build}/$@
     72%.ps : %.fig
     73        fig2dev -L ps $< > $@
    8274
    83 %.ps : %.fig | ${Build}
    84         fig2dev -L ps $< > ${Build}/$@
    85 
    86 %.pstex : %.fig | ${Build}
    87         fig2dev -L pstex $< > ${Build}/$@
    88         fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
     75%.pstex : %.fig
     76        fig2dev -L pstex $< > $@
     77        fig2dev -L pstex_t -p $@ $< > $@_t
    8978
    9079# Local Variables: #
  • doc/proposals/tuples/tuples.tex

    r63238a4 rd286cf68  
     1% inline code ©...© (copyright symbol) emacs: C-q M-)
     2% red highlighting ®...® (registered trademark symbol) emacs: C-q M-.
     3% blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_
     4% green highlighting ¢...¢ (cent symbol) emacs: C-q M-"
     5% LaTex escape §...§ (section symbol) emacs: C-q M-'
     6% keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^
     7% math escape $...$ (dollar symbol)
     8
    19\documentclass[twoside,11pt]{article}
    210
     
    715\usepackage{textcomp}
    816\usepackage[latin1]{inputenc}
    9 
    1017\usepackage{fullpage,times,comment}
    1118\usepackage{epic,eepic}
    12 \usepackage{upquote}                                    % switch curled `'" to straight
     19\usepackage{upquote}                                                                    % switch curled `'" to straight
    1320\usepackage{calc}
    1421\usepackage{xspace}
    1522\usepackage{graphicx}
    16 \usepackage{varioref}                                   % extended references
    17 \usepackage{listings}                                   % format program code
    18 \usepackage[flushmargin]{footmisc}                      % support label/reference in footnote
     23\usepackage{varioref}                                                                   % extended references
     24\usepackage{listings}                                                                   % format program code
     25\usepackage[flushmargin]{footmisc}                                              % support label/reference in footnote
    1926\usepackage{latexsym}                                   % \Box glyph
    2027\usepackage{mathptmx}                                   % better math font with "times"
     
    2734\renewcommand{\UrlFont}{\small\sf}
    2835
    29 \setlength{\topmargin}{-0.45in}                         % move running title into header
     36\setlength{\topmargin}{-0.45in}                                                 % move running title into header
    3037\setlength{\headsep}{0.25in}
    3138
     
    3542
    3643\interfootnotelinepenalty=10000
    37 
    38 \CFAStyle                                               % use default CFA format-style
    39 % inline code ©...© (copyright symbol) emacs: C-q M-)
    40 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-.
    41 % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_
    42 % green highlighting ¢...¢ (cent symbol) emacs: C-q M-"
    43 % LaTex escape §...§ (section symbol) emacs: C-q M-'
    44 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^
    45 % math escape $...$ (dollar symbol)
    46 
    4744
    4845\title{
  • doc/refrat/Makefile

    r63238a4 rd286cf68  
    5353        dvips ${Build}/$< -o $@
    5454
    55 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
    56                 ${Macros}/common.tex ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib | ${Build}
     55${BASE}.dvi : Makefile ${Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
     56                ${Macros}/common.tex ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib
    5757        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    5858        if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi
     
    7878        mkdir -p ${Build}
    7979
    80 %.tex : %.fig | ${Build}
     80%.tex : %.fig ${Build}
    8181        fig2dev -L eepic $< > ${Build}/$@
    8282
    83 %.ps : %.fig | ${Build}
     83%.ps : %.fig ${Build}
    8484        fig2dev -L ps $< > ${Build}/$@
    8585
    86 %.pstex : %.fig | ${Build}
     86%.pstex : %.fig ${Build}
    8787        fig2dev -L pstex $< > ${Build}/$@
    8888        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
  • doc/theses/aaron_moss/comp_II/Makefile

    r63238a4 rd286cf68  
    3232
    3333DOCUMENT = comp_II.pdf
    34 BASE = ${basename ${DOCUMENT}}
    3534
    3635# Directives #
     
    4140
    4241clean :
    43         @rm -frv ${DOCUMENT} ${BASE}.ps ${Build}
     42        @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build}
    4443
    4544# File Dependencies #
    4645
    47 ${DOCUMENT} : ${BASE}.ps
     46${DOCUMENT} : ${basename ${DOCUMENT}}.ps
    4847        ps2pdf $<
    4948
    50 ${BASE}.ps : ${BASE}.dvi
     49${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
    5150        dvips ${Build}/$< -o $@
    5251
    53 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
    54                 ${Macros}/common.tex ${Macros}/indexstyle ../../../bibliography/pl.bib | ${Build}
     52${basename ${DOCUMENT}}.dvi : Makefile ${Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
     53                ${Macros}/common.tex ${Macros}/indexstyle ../../../bibliography/pl.bib
    5554        # Must have *.aux file containing citations for bibtex
    5655        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
     
    6766        mkdir -p ${Build}
    6867
    69 %.tex : %.fig ${Build}
     68%.tex : %.fig
    7069        fig2dev -L eepic $< > ${Build}/$@
    7170
    72 %.ps : %.fig | ${Build}
     71%.ps : %.fig
    7372        fig2dev -L ps $< > ${Build}/$@
    7473
    75 %.pstex : %.fig | ${Build}
     74%.pstex : %.fig
    7675        fig2dev -L pstex $< > ${Build}/$@
    7776        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
  • doc/theses/thierry_delisle/Makefile

    r63238a4 rd286cf68  
    5151
    5252DOCUMENT = thesis.pdf
    53 BASE = ${basename ${DOCUMENT}}
    5453
    5554# Directives #
     
    6059
    6160clean :
    62         @rm -frv ${DOCUMENT} ${BASE}.ps ${Build}
     61        @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build}
    6362
    6463# File Dependencies #
    6564
    66 ${DOCUMENT} : ${BASE}.ps
     65${DOCUMENT} : ${basename ${DOCUMENT}}.ps
    6766        ps2pdf $<
    6867
    69 ${BASE}.ps : ${BASE}.dvi
     68${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
    7069        dvips ${Build}/$< -o $@
    7170
    72 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
    73                 ${Macros}/common.tex ${Macros}/indexstyle annex/local.bib ../../bibliography/pl.bib | ${Build}
     71${basename ${DOCUMENT}}.dvi : Makefile ${Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
     72                ${Macros}/common.tex ${Macros}/indexstyle annex/local.bib ../../bibliography/pl.bib
    7473        # Must have *.aux file containing citations for bibtex
    7574        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
     
    9291        fig2dev -L eepic $< > ${Build}/$@
    9392
    94 %.ps : %.fig | ${Build}
     93%.ps : %.fig ${Build}
    9594        fig2dev -L ps $< > ${Build}/$@
    9695
    97 %.pstex : %.fig | ${Build}
     96%.pstex : %.fig ${Build}
    9897        fig2dev -L pstex $< > ${Build}/$@
    9998        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
  • doc/user/Makefile

    r63238a4 rd286cf68  
    5757        dvips ${Build}/$< -o $@
    5858
    59 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
    60                 ${Macros}/common.tex ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib | ${Build}
     59${BASE}.dvi : Makefile ${Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
     60                ${Macros}/common.tex ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib
    6161        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    6262        if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi
     
    7979        mkdir -p ${Build}
    8080
    81 %.tex : %.fig | ${Build}
     81%.tex : %.fig ${Build}
    8282        fig2dev -L eepic $< > ${Build}/$@
    8383
    84 %.ps : %.fig | ${Build}
     84%.ps : %.fig ${Build}
    8585        fig2dev -L ps $< > ${Build}/$@
    8686
    87 %.pstex : %.fig | ${Build}
     87%.pstex : %.fig ${Build}
    8888        fig2dev -L pstex $< > ${Build}/$@
    8989        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
  • src/Parser/TypedefTable.cc

    r63238a4 rd286cf68  
    1010// Created On       : Sat May 16 15:20:13 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 22 06:14:39 2018
    13 // Update Count     : 206
     12// Last Modified On : Thu Jun  7 13:17:56 2018
     13// Update Count     : 192
    1414//
    1515
     
    7878        debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl );
    7979        auto ret = kindTable.insertAt( scope, identifier, kind );
    80         //if ( ! ret.second ) ret.first->second = kind;         // exists => update
    81         assert( ret.first->second == kind );                            // exists
     80        if ( ! ret.second ) ret.first->second = kind;           // exists => update
    8281} // TypedefTable::addToScope
    8382
    8483void TypedefTable::addToEnclosingScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) {
    85         assert( kindTable.currentScope() >= 1 + level );
    86         auto scope = kindTable.currentScope() - 1 - level;
    87         debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << endl );
     84        assert( kindTable.currentScope() >= 1 );
     85        auto scope = kindTable.currentScope() - 1;
     86        debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl );
    8887        auto ret = kindTable.insertAt( scope, identifier, kind );
    8988        if ( ! ret.second ) ret.first->second = kind;           // exists => update
     
    9291void TypedefTable::enterScope() {
    9392        kindTable.beginScope();
    94         debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl; print() );
     93        debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl );
     94        debugPrint( print() );
    9595} // TypedefTable::enterScope
    9696
    9797void TypedefTable::leaveScope() {
    98         debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl; print() );
     98        debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl );
     99        debugPrint( print() );
    99100        kindTable.endScope();
    100101} // TypedefTable::leaveScope
     
    113114                --scope;
    114115                debugPrint( cerr << endl << "[" << scope << "]" );
    115         } // while
     116        }
    116117        debugPrint( cerr << endl );
    117 } // TypedefTable::print
     118}
    118119
    119120// Local Variables: //
  • src/Parser/TypedefTable.h

    r63238a4 rd286cf68  
    1010// Created On       : Sat May 16 15:24:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 22 05:29:58 2018
    13 // Update Count     : 86
     12// Last Modified On : Thu Jun  7 12:10:17 2018
     13// Update Count     : 85
    1414//
    1515
     
    2525        typedef ScopedMap< std::string, int > KindTable;
    2626        KindTable kindTable;   
    27         unsigned int level = 0;
    2827  public:
    2928        ~TypedefTable();
     
    3837        void leaveScope();
    3938
    40         void up() { level += 1; }
    41         void down() { level -= 1; }
    42 
    4339        void print( void ) const;
    4440}; // TypedefTable
  • src/Parser/lex.ll

    r63238a4 rd286cf68  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Wed Jun 20 09:08:28 2018
    13  * Update Count     : 682
     12 * Last Modified On : Thu Jun  7 08:27:40 2018
     13 * Update Count     : 679
    1414 */
    1515
     
    2525//**************************** Includes and Defines ****************************
    2626
    27 // trigger before each matching rule's action
    28 #define YY_USER_ACTION \
    29         yylloc.first_line = yylineno; \
    30         yylloc.first_column = column; \
    31         column += yyleng; \
    32         yylloc.last_column = column; \
    33         yylloc.last_line = yylineno; \
    34         yylloc.filename = yyfilename ? yyfilename : "";
    3527unsigned int column = 0;                                                                // position of the end of the last token parsed
     28#define YY_USER_ACTION yylloc.first_line = yylineno; yylloc.first_column = column; column += yyleng; yylloc.last_column = column; yylloc.last_line = yylineno; yylloc.filename = yyfilename ? yyfilename : "";                          // trigger before each matching rule's action
    3629
    3730#include <string>
     
    5649#define NUMERIC_RETURN(x)       rm_underscore(); RETURN_VAL( x ) // numeric constant
    5750#define KEYWORD_RETURN(x)       RETURN_CHAR( x )                        // keyword
    58 #define QKEYWORD_RETURN(x)      RETURN_VAL(x);                          // quasi-keyword
     51#define QKEYWORD_RETURN(x)      typedefTable.isKind( yytext ); RETURN_VAL(x); // quasi-keyword
    5952#define IDENTIFIER_RETURN()     RETURN_VAL( typedefTable.isKind( yytext ) )
    6053#define ATTRIBUTE_RETURN()      RETURN_VAL( ATTR_IDENTIFIER )
  • src/Parser/parser.yy

    r63238a4 rd286cf68  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 22 13:59:11 2018
    13 // Update Count     : 3586
     12// Last Modified On : Thu Jun  7 10:07:12 2018
     13// Update Count     : 3527
    1414//
    1515
     
    136136} // build_postfix_name
    137137
    138 bool forall = false, xxx = false, yyy = false;                  // aggregate have one or more forall qualifiers ?
     138bool forall = false, xxx = false;                                               // aggregate have one or more forall qualifiers ?
    139139
    140140// https://www.gnu.org/software/bison/manual/bison.html#Location-Type
     
    304304%type<en> enumerator_value_opt
    305305
    306 %type<decl> external_definition external_definition_list external_definition_list_opt
    307 
    308 %type<decl> exception_declaration
     306%type<decl> exception_declaration external_definition external_definition_list external_definition_list_no_pop_push external_definition_list_opt
    309307
    310308%type<decl> field_declaration field_declaration_list_opt field_declarator_opt field_declaring_list
     
    18231821        ;
    18241822
    1825 fred:
    1826         // empty
    1827                 { yyy = false; }
    1828         ;
    1829 
    18301823aggregate_type:                                                                                 // struct, union
    18311824        aggregate_key attribute_list_opt '{' field_declaration_list_opt '}'
    18321825                { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); }
    1833         | aggregate_key attribute_list_opt no_attr_identifier fred
     1826        | aggregate_key attribute_list_opt no_attr_identifier
    18341827                {
    18351828                        typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname ); // create typedef
     
    18381831                }
    18391832          '{' field_declaration_list_opt '}'
    1840                 { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $7, true )->addQualifiers( $2 ); }
    1841         | aggregate_key attribute_list_opt type_name fred
     1833                { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $6, true )->addQualifiers( $2 ); }
     1834        | aggregate_key attribute_list_opt type_name
    18421835                {
    18431836                        typedefTable.makeTypedef( *$3->type->symbolic.name, forall ? TYPEGENname : TYPEDEFname ); // create typedef
     
    18461839                }
    18471840          '{' field_declaration_list_opt '}'
    1848                 { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, nullptr, $7, true )->addQualifiers( $2 ); }
     1841                { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, nullptr, $6, true )->addQualifiers( $2 ); }
    18491842        | aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list_opt '}' // CFA
    18501843                { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $4, $7, false )->addQualifiers( $2 ); }
     
    18531846
    18541847aggregate_type_nobody:                                                                  // struct, union - {...}
    1855         aggregate_key attribute_list_opt no_attr_identifier fred
     1848        aggregate_key attribute_list_opt no_attr_identifier
    18561849                {
    18571850                        typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname );
     
    18601853                        $$ = DeclarationNode::newAggregate( $1, $3, nullptr, nullptr, false )->addQualifiers( $2 );
    18611854                }
    1862         | aggregate_key attribute_list_opt type_name fred
     1855        | aggregate_key attribute_list_opt type_name
    18631856                {
    18641857                        // Create new generic declaration with same name as previous forward declaration, where the IDENTIFIER is
     
    18741867aggregate_key:
    18751868        STRUCT
    1876                 { yyy = true; $$ = DeclarationNode::Struct; }
     1869                { $$ = DeclarationNode::Struct; }
    18771870        | UNION
    1878                 { yyy = true; $$ = DeclarationNode::Union; }
     1871                { $$ = DeclarationNode::Union; }
    18791872        | EXCEPTION
    1880                 { yyy = true; $$ = DeclarationNode::Exception; }
     1873                { $$ = DeclarationNode::Exception; }
    18811874        | COROUTINE
    1882                 { yyy = true; $$ = DeclarationNode::Coroutine; }
     1875                { $$ = DeclarationNode::Coroutine; }
    18831876        | MONITOR
    1884                 { yyy = true; $$ = DeclarationNode::Monitor; }
     1877                { $$ = DeclarationNode::Monitor; }
    18851878        | THREAD
    1886                 { yyy = true; $$ = DeclarationNode::Thread; }
     1879                { $$ = DeclarationNode::Thread; }
    18871880        ;
    18881881
     
    23292322
    23302323translation_unit:
    2331         // empty, input file
     2324        // empty
     2325                {}                                                                                              // empty input file
    23322326        | external_definition_list
    23332327                { parseTree = parseTree ? parseTree->appendList( $1 ) : $1;     }
     
    23432337        ;
    23442338
     2339        // SKULLDUGGERY: Declarations in extern "X" and distribution need to be added to the current lexical scope.
     2340        // However, external_definition_list creates a new scope around each external_definition, but the pop loses all the
     2341        // types in the extern "X" and distribution at the end of the block. This version of external_definition_list does
     2342
     2343        // not do push/pop for declarations at the level of the extern "X" and distribution block. Any recursive uses of
     2344        // external_definition_list within the extern "X" and distribution block correctly pushes/pops for that scope level.
     2345external_definition_list_no_pop_push:
     2346        external_definition
     2347        | external_definition_list_no_pop_push
     2348                { forall = xxx; }
     2349          external_definition
     2350                { $$ = $1 ? $1->appendList( $3 ) : $3; }
     2351        ;
     2352
    23452353external_definition_list_opt:
    23462354        // empty
    23472355                { $$ = nullptr; }
    2348         | external_definition_list
    2349         ;
    2350 
    2351 up:
    2352                 { typedefTable.up(); }
    2353         ;
    2354 
    2355 down:
    2356                 { typedefTable.down(); }
     2356        | external_definition_list_no_pop_push
    23572357        ;
    23582358
     
    23742374                        linkage = LinkageSpec::linkageUpdate( yylloc, linkage, $2 );
    23752375                }
    2376           '{' up external_definition_list_opt down '}'
     2376          '{' external_definition_list_opt '}'
    23772377                {
    23782378                        linkage = linkageStack.top();
    23792379                        linkageStack.pop();
    2380                         $$ = $6;
     2380                        $$ = $5;
    23812381                }
    23822382        | type_qualifier_list
    2383                 {
    2384                         if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    2385                         if ( $1->type->forall ) xxx = forall = true; // remember generic type
    2386                 }
    2387           '{' up external_definition_list_opt down '}'          // CFA, namespace
    2388                 {
    2389                         for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     2383                { if ( $1->type->forall ) xxx = forall = true; } // remember generic type
     2384          '{' external_definition_list_opt '}'                          // CFA, namespace
     2385                {
     2386                        for ( DeclarationNode * iter = $4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    23902387                                if ( isMangled( iter->linkage ) ) {             // ignore extern "C"
    23912388                                        iter->addQualifiers( $1->clone() );
     
    23942391                        xxx = false;
    23952392                        delete $1;
    2396                         $$ = $5;
     2393                        $$ = $4;
    23972394                }
    23982395        | declaration_qualifier_list
    2399                 {
    2400                         if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    2401                         if ( $1->type->forall ) xxx = forall = true; // remember generic type
    2402                 }
    2403           '{' up external_definition_list_opt down '}'          // CFA, namespace
    2404                 {
    2405                         for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     2396                { if ( $1->type->forall ) xxx = forall = true; } // remember generic type
     2397          '{' external_definition_list_opt '}'                          // CFA, namespace
     2398                {
     2399                        for ( DeclarationNode * iter = $4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    24062400                                if ( isMangled( iter->linkage ) ) {             // ignore extern "C"
    24072401                                        iter->addQualifiers( $1->clone() );
     
    24102404                        xxx = false;
    24112405                        delete $1;
    2412                         $$ = $5;
     2406                        $$ = $4;
    24132407                }
    24142408        | declaration_qualifier_list type_qualifier_list
    24152409                {
    2416                         if ( ($1->type && $1->type->qualifiers.val) || $2->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    2417                         if ( ($1->type && $1->type->forall) || $2->type->forall ) xxx = forall = true; // remember generic type
    2418                 }
    2419           '{' up external_definition_list_opt down '}'          // CFA, namespace
    2420                 {
    2421                         for ( DeclarationNode * iter = $6; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     2410                        // forall must be in the type_qualifier_list
     2411                        if ( $2->type->forall ) xxx = forall = true; // remember generic type
     2412                }
     2413          '{' external_definition_list_opt '}'                          // CFA, namespace
     2414                {
     2415                        for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    24222416                                if ( isMangled( iter->linkage ) && isMangled( $2->linkage ) ) { // ignore extern "C"
    24232417                                        iter->addQualifiers( $1->clone() );
     
    24282422                        delete $1;
    24292423                        delete $2;
    2430                         $$ = $6;
     2424                        $$ = $5;
    24312425                }
    24322426        ;
  • src/SynTree/Type.cc

    r63238a4 rd286cf68  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 22 10:17:19 2018
    13 // Update Count     : 39
     12// Last Modified On : Mon Sep 25 15:16:32 2017
     13// Update Count     : 38
    1414//
    1515#include "Type.h"
     
    6969
    7070// These must remain in the same order as the corresponding bit fields.
    71 const char * Type::FuncSpecifiersNames[] = { "inline", "_Noreturn", "fortran" };
     71const char * Type::FuncSpecifiersNames[] = { "inline", "fortran", "_Noreturn" };
    7272const char * Type::StorageClassesNames[] = { "extern", "static", "auto", "register", "_Thread_local" };
    7373const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic" };
Note: See TracChangeset for help on using the changeset viewer.