Changes in / [3d4b23fa:55a68c3]


Ignore:
Files:
25 added
5 deleted
100 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/common.tex

    r3d4b23fa r55a68c3  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Thu Jul 13 11:44:59 2017
    14 %% Update Count     : 335
     13%% Last Modified On : Sun Jun 18 20:32:32 2017
     14%% Update Count     : 319
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    3636% Names used in the document.
    3737
    38 \newcommand{\CFAIcon}{\textsf{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}\xspace} % Cforall symbolic name
     38\newcommand{\CFAIcon}{\textrm{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}\xspace} % Cforall symbolic name
    3939\newcommand{\CFA}{\protect\CFAIcon} % safe for section/caption
    4040\newcommand{\CFL}{\textrm{Cforall}\xspace} % Cforall symbolic name
     
    5555\setlength{\parindentlnth}{\parindent}
    5656
    57 \newcommand{\LstKeywordStyle}[1]{{\lst@basicstyle{\lst@keywordstyle{#1}}}}
    58 \newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}}
    59 
    6057\newlength{\gcolumnposn}                                % temporary hack because lstlisting does not handle tabs correctly
    6158\newlength{\columnposn}
    6259\setlength{\gcolumnposn}{2.5in}
    6360\setlength{\columnposn}{\gcolumnposn}
    64 \newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\lst@basicstyle{\LstCommentStyle{#2}}}}
     61\newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\lst@commentstyle{#2}}}
    6562\newcommand{\CRT}{\global\columnposn=\gcolumnposn}
    6663
     
    234231basicstyle=\linespread{0.9}\sf,                                                 % reduce line spacing and use sanserif font
    235232stringstyle=\tt,                                                                                % use typewriter font
    236 tabsize=6,                                                                                              % N space tabbing
     233tabsize=4,                                                                                              % 4 space tabbing
    237234xleftmargin=\parindentlnth,                                                             % indent code to paragraph indentation
    238235extendedchars=true,                                                                             % allow ASCII characters in the range 128-255
  • doc/LaTeXmacros/lstlang.sty

    r3d4b23fa r55a68c3  
    88%% Created On       : Sat May 13 16:34:42 2017
    99%% Last Modified By : Peter A. Buhr
    10 %% Last Modified On : Wed Jul 12 22:42:09 2017
    11 %% Update Count     : 12
     10%% Last Modified On : Thu Jun 22 07:40:31 2017
     11%% Update Count     : 10
    1212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1313
     
    112112                finally, forall, ftype, _Generic, _Imaginary, inline, __label__, lvalue, _Noreturn, one_t,
    113113                otype, restrict, _Static_assert, throw, throwResume, trait, try, ttype, typeof, __typeof,
    114                 __typeof__, with, zero_t},
     114                __typeof__, zero_t},
    115115        morekeywords=[2]{
    116116                _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex,
     
    118118        moredirectives={defined,include_next}%
    119119}
    120 
    121 % C++ programming language
    122 \lstdefinelanguage{C++}[ANSI]{C++}{}
    123120
    124121% uC++ programming language, based on ANSI C++
  • doc/bibliography/cfa.bib

    r3d4b23fa r55a68c3  
    22732273@manual{JavaScript,
    22742274    keywords    = {JavaScript},
    2275     contributer = {pabuhr@plg},
     2275    contributer = {pabuhr},
    22762276    title       = {ECMAScript 2015 Language Specification {JavaScript}},
    22772277    organization= {ECAM International},
     
    24462446@manual{Erlang,
    24472447    keywords    = {Erlang},
    2448     contributer = {pabuhr@plg},
     2448    contributer = {pabuhr},
    24492449    title       = {Erlang Reference Manual User's Guide, Vertion 7.0},
    24502450    organization= {Erlang/OTP System Documentation},
     
    27712771    publisher   = {ACM},
    27722772    address     = {New York, NY, USA},
    2773 }
    2774 
    2775 @article{Yang95,
    2776     keywords    = {software solutions, N-thread, mutual exclusions},
    2777     contributer = {pabuhr@plg},
    2778     author      = {Jae-Heon Yang and James H. Anderson},
    2779     title       = {A Fast, Scalable Mutual Exclusion Algorithm},
    2780     journal     = {Distributed Computing},
    2781     publisher   = {Springer-Verlag},
    2782     volume      = {9},
    2783     number      = {1},
    2784     year        = {1995},
    2785     pages       = {51-60},
    27862773}
    27872774
     
    50655052    contributer = {pabuhr@plg},
    50665053    author      = {Kathleen Jensen and Niklaus Wirth},
    5067     title       = {{P}ascal User Manual and Report, ISO Pascal Standard},
     5054    title       = {{P}ascal User Manual and Report},
    50685055    publisher   = {Springer--Verlag},
    5069     year        = 1991,
    5070     edition     = {4th},
    5071     note        = {Revised by Andrew B. Mickel and James F. Miner}
     5056    year        = 1985,
     5057    edition     = {3rd},
     5058    note        = {Revised by Andrew B. Mickel and James F. Miner, ISO Pascal Standard}
    50725059}
    50735060
  • doc/proposals/tagged-struct.txt

    r3d4b23fa r55a68c3  
    7171should be possible to do during linking.
    7272
    73 If a generic/polymorphic type is tagged its tagged would then be shared
    74 between all applications of that generic. Internal tags could be used to
    75 seperate these structures again, however it seems in most cases simply using
    76 the existing type parameters should provide the needed information.
    77 
    7873
    7974Traits:
     
    107102To allow for growth each option would have to be a structure itself.
    108103
    109 Which brings us to "tagged struct union", ie. a union of tagged structures
     104Which brings us to "tagget struct union", ie. a union of tagged structures
    110105as opposed to tagging the union itself. This extention acts as a constraint.
    111106If unions are declared tagged instead of creating a new tagged type, all
    112 possible values of the union must be of that tagged type or a child type. If
    113 the tagged type is omitted then they must all be tagged but of any tagged
    114 type.
    115 
    116 As a short cut union_instance->type might get the type object of the loaded
    117 value. It should always be the same operation regardless so it saves
    118 abritarly picking a branch of the union to get the type object.
     107possible values of the union must be of that tagged type or a child type.
    119108
    120109
    121 Type Objects Fields (Extention):
     110Custom Type Objects (Extention):
    122111
    123 Adding fields to the type object allows data to be shared between instances
    124 of the same type. Such behaviour could be mimiced by creating a lookup
    125 function on the type object pointer, but this may be cleaner and more
    126 efficient.
     112Some method to define type objects used within a tree of types. One option is
     113to allow the tree's type object to be specified by the tree root. It would
     114then have to be filled in for each type in the tree, including the root.
    127115
    128 The type object fields follow similar rules to the fields on the tagged
    129 objects themselves, they must be additive. So any fields present on a
    130 type object will be present (and in the same place) on all of its children.
     116The only required field is the parent field, a pointer to the type object's
     117type. (This is also the only required field on the tagged structure itself.)
    131118
    132 This does mean that many type object structure types will have to be auto
    133 generated, and traversing up the tree might get a little wierd. That could
    134 be symplified by only allowing the root type to specify fields on the type
    135 object, so that the type object is consistant throughout that particular tree.
    136 And hence the type_object pointers would also be consistant as the type they
    137 point to would never change.
    138 
    139 struct Example tagged {
    140         tagged char const * const type_name = "Example";
    141         int data;
    142 };
    143 
    144 Creates a tagged structure that has no parent, stores an integer and the type
    145 object also has an extra field that stores a string on the type object.
    146 This can be accessed by using member access on the type object, as a regular
    147 structure.
    148 
    149 Type object fields will have to allow initialization on their declaration,
    150 and declarations of children as well, as they are not assotiated with the
    151 later instances of the tagged structure.
    152 
    153         ...
    154         tagged void (*dtor)(tagged Example * this);
    155         ...
    156 
    157 Sub-Extention, not sure how it would work but some way to have a "dynamic"
    158 field that is considered the type of the current tagged struct might be useful
    159 for things like specifying a deconstructor. In this case, the following code
    160 will clean up any child type of Example:
    161 
    162 Example * ex = get_some_example();
    163 ex->type->dtor(ex);
     119A further extention could allow expanding type objects, so child types could
     120append fields to their parent's feild list. They might need their own type
     121objects at that point, or maybe static checks will be enough to see the
     122minimum field list.
  • doc/user/Makefile

    r3d4b23fa r55a68c3  
    11## Define the appropriate configuration variables.
    22
    3 TeXLIB = .:../LaTeXmacros:../bibliography/:
     3TeXLIB = .:../LaTeXmacros:../LaTeXmacros/listings:../LaTeXmacros/enumitem:../bibliography/:
    44LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error
    55BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
  • doc/user/user.tex

    r3d4b23fa r55a68c3  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Thu Jul 13 11:44:57 2017
    14 %% Update Count     : 2690
     13%% Last Modified On : Sun Jul  2 09:49:56 2017
     14%% Update Count     : 2503
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    5757\CFAStyle                                                                                               % use default CFA format-style
    5858
    59 \lstnewenvironment{C++}[1][]
    60 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{®}{®}#1}}
    61 {}
    62 
    6359% inline code ©...© (copyright symbol) emacs: C-q M-)
    6460% red highlighting ®...® (registered trademark symbol) emacs: C-q M-.
     
    141137
    142138\CFA{}\index{cforall@\CFA}\footnote{Pronounced ``\Index*{C-for-all}'', and written \CFA, CFA, or \CFL.} is a modern general-purpose programming-language, designed as an evolutionary step forward for the C programming language.
    143 The syntax of \CFA builds from C and should look immediately familiar to C/\Index*[C++]{\CC{}} programmers.
     139The syntax of the \CFA language builds from C, and should look immediately familiar to C/\Index*[C++]{\CC{}} programmers.
    144140% Any language feature that is not described here can be assumed to be using the standard \Celeven syntax.
    145 \CFA adds many modern programming-language features that directly lead to increased \emph{\Index{safety}} and \emph{\Index{productivity}}, while maintaining interoperability with existing C programs and achieving similar performance.
    146 Like C, \CFA is a statically typed, procedural (non-\Index{object-oriented}) language with a low-overhead runtime, meaning there is no global \Index{garbage-collection}, but \Index{regional garbage-collection}\index{garbage-collection!regional} is possible.
     141\CFA adds many modern programming-language features that directly lead to increased \emph{\Index{safety}} and \emph{\Index{productivity}}, while maintaining interoperability with existing C programs and achieving C performance.
     142Like C, \CFA is a statically typed, procedural language with a low-overhead runtime, meaning there is no global \Index{garbage-collection}, but \Index{regional garbage-collection}\index{garbage-collection!regional} is possible.
    147143The primary new features include parametric-polymorphic routines and types, exceptions, concurrency, and modules.
    148144
    149 One of the main design philosophies of \CFA is to ``\Index{describe not prescribe}'', which means \CFA tries to provide a pathway from low-level C programming to high-level \CFA programming, but it does not force programmers to ``do the right thing''.
    150 Programmers can cautiously add \CFA extensions to their C programs in any order and at any time to incrementally move towards safer, higher-level programming.
    151 A programmer is always free to reach back to C from \CFA, for any reason, and in many cases, new \CFA features can be locally switched back to there C counterpart.
    152 There is no notion or requirement for \emph{rewriting} a legacy C program in \CFA;
    153 instead, a programmer evolves a legacy program into \CFA by incrementally incorporating \CFA features.
    154 As well, new programs can be written in \CFA using a combination of C and \CFA features.
    155 
    156 \Index*[C++]{\CC{}} had a similar goal 30 years ago, allowing object-oriented programming to be incrementally added to C.
    157 However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that cannot be updated, and active divergence of the language model from C, all of which requires significant effort and training to incrementally add \CC to a C-based project.
     145One of the main design philosophies of \CFA is to ``describe not prescribe'', which means \CFA tries to provide a pathway from low-level C programming to high-level \CFA programming, but it does not force programmers to ``do the right thing''.
     146Programmers can cautiously add \CFA extensions to their C programs in any order and at any time to incrementally move towards safer, higher-level programming features.
     147A programmer is always free to reach back to C from \CFA for any reason, and in many cases, new \CFA features have a fallback to a C mechanism.
     148There is no notion or requirement for rewriting a legacy C program in \CFA;
     149instead, a programmer evolves an existing C program into \CFA by incrementally incorporating \CFA features.
     150New programs can be written in \CFA using a combination of C and \CFA features.
     151\Index*[C++]{\CC{}} had a similar goal 30 years ago, but currently has the disadvantages of multiple legacy design-choices that cannot be updated and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project.
    158152In contrast, \CFA has 30 years of hindsight and a clean starting point.
    159153
     
    162156\begin{quote2}
    163157\begin{tabular}{@{}l@{\hspace{1.5em}}l@{\hspace{1.5em}}l@{}}
    164 \multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{\CC}}      \\
    165 \begin{cfa}
     158\multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{\CFA}}      & \multicolumn{1}{c}{\textbf{C}}        & \multicolumn{1}{c}{\textbf{\CC}}      \\
     159\begin{cfa}
     160#include <fstream>§\indexc{fstream}§
     161
     162int main( void ) {
     163        int x = 0, y = 1, z = 2;
     164        ®sout | x | y | z | endl;®
     165}
     166\end{cfa}
     167&
     168\begin{lstlisting}
    166169#include <stdio.h>§\indexc{stdio.h}§
    167170
     
    170173        ®printf( "%d %d %d\n", x, y, z );®
    171174}
    172 \end{cfa}
     175\end{lstlisting}
    173176&
    174 \begin{cfa}
    175 #include <fstream>§\indexc{fstream}§
    176 
    177 int main( void ) {
    178         int x = 0, y = 1, z = 2;
    179         ®sout | x | y | z | endl;®§\indexc{sout}§
    180 }
    181 \end{cfa}
    182 &
    183 \begin{cfa}
     177\begin{lstlisting}
    184178#include <iostream>§\indexc{iostream}§
    185179using namespace std;
     
    188182        ®cout<<x<<" "<<y<<" "<<z<<endl;®
    189183}
    190 \end{cfa}
     184\end{lstlisting}
    191185\end{tabular}
    192186\end{quote2}
    193187While the \CFA I/O looks similar to the \Index*[C++]{\CC{}} output style, there are important differences, such as automatic spacing between variables as in \Index*{Python} (see~\VRef{s:IOLibrary}).
    194188
    195 \subsection{Background}
    196 
    197189This document is a programmer reference-manual for the \CFA programming language.
    198190The manual covers the core features of the language and runtime-system, with simple examples illustrating syntax and semantics of each feature.
    199191The manual does not teach programming, i.e., how to combine the new constructs to build complex programs.
    200 A reader should already have an intermediate knowledge of control flow, data structures, and concurrency issues to understand the ideas presented, as well as some experience programming in C/\CC.
    201 Implementers should refer to the \CFA Programming Language Specification for details about the language syntax and semantics.
     192A reader should already have an intermediate knowledge of control flow, data structures, and concurrency issues to understand the ideas presented as well as some experience programming in C/\CC.
     193Implementers may refer to the \CFA Programming Language Specification for details about the language syntax and semantics.
    202194Changes to the syntax and additional features are expected to be included in later revisions.
    203195
     
    208200This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more.
    209201Even with all its problems, C continues to be popular because it allows writing software at virtually any level in a computer system without restriction.
    210 For system programming, where direct access to hardware, storage management, and real-time issues are a requirement, C is usually the only language of choice.
     202For system programming, where direct access to hardware and dealing with real-time issues is a requirement, C is usually the language of choice.
    211203The TIOBE index~\cite{TIOBE} for March 2016 showed the following programming-language popularity: \Index*{Java} 20.5\%, C 14.5\%, \Index*[C++]{\CC{}} 6.7\%, \Csharp 4.3\%, \Index*{Python} 4.3\%, where the next 50 languages are less than 3\% each with a long tail.
    212204As well, for 30 years, C has been the number 1 and 2 most popular programming language:
     
    224216\end{center}
    225217Hence, C is still an extremely important programming language, with double the usage of \Index*[C++]{\CC{}}; in many cases, \CC is often used solely as a better C.
    226 Love it or hate it, C has been an important and influential part of computer science for 40 years and its appeal is not diminishing.
    227 Unfortunately, C has many problems and omissions that make it an unacceptable programming language for modern needs.
    228 
    229 As stated, the goal of the \CFA project is to engineer modern language-features into C in an evolutionary rather than revolutionary way.
     218Love it or hate it, C has been an important and influential part of computer science for 40 years and sit appeal is not diminishing.
     219Unfortunately, C has too many problems and omissions to make it an acceptable programming language for modern needs.
     220
     221As stated, the goal of the \CFA project is to engineer modern language features into C in an evolutionary rather than revolutionary way.
    230222\CC~\cite{C++14,C++} is an example of a similar project;
    231 however, it largely extended the C language, and did not address most of C's existing problems.\footnote{%
     223however, it largely extended the language, and did not address many existing problems.\footnote{%
    232224Two important existing problems addressed were changing the type of character literals from ©int© to ©char© and enumerator from ©int© to the type of its enumerators.}
    233 \Index*{Fortran}~\cite{Fortran08}, \Index*{Ada}~\cite{Ada12}, and \Index*{Cobol}~\cite{Cobol14} are examples of programming languages that took an evolutionary approach, where modern language-features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language.
     225\Index*{Fortran}~\cite{Fortran08}, \Index*{Ada}~\cite{Ada12}, and \Index*{Cobol}~\cite{Cobol14} are examples of programming languages that took an evolutionary approach, where modern language features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language.
    234226\Index*{Java}~\cite{Java8}, \Index*{Go}~\cite{Go}, \Index*{Rust}~\cite{Rust} and \Index*{D}~\cite{D} are examples of the revolutionary approach for modernizing C/\CC, resulting in a new language rather than an extension of the descendent.
    235 These languages have different syntax and semantics from C, do not interoperate directly with C, and are not systems languages because of restrictive memory-management or garbage collection.
     227These languages have different syntax and semantics from C, and do not interoperate directly with C, largely because of garbage collection.
    236228As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten.
    237 These costs can be prohibitive for many companies with a large software-base in C/\CC, and a significant number of programmers require retraining to the new programming language.
    238 
    239 The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fixes many of the well known C problems while containing modern language-features.
     229These costs can be prohibitive for many companies with a large software base in C/\CC, and a significant number of programmers requiring retraining to a new programming language.
     230
     231The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fixing some of the well known C problems and containing many modern language features.
    240232Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers;
    241233as a result, it will fade into disuse.
    242234Considering the large body of existing C code and programmers, there is significant impetus to ensure C is transformed into a modern programming language.
    243 While \Index*[C11]{\Celeven{}} made a few simple extensions to the language, nothing was added to address existing problems in the language or to augment the language with modern language-features.
    244 While some may argue that modern language-features may make C complex and inefficient, it is clear a language without modern capabilities is insufficient for the advanced programming problems existing today.
     235While \Index*[C11]{\Celeven{}} made a few simple extensions to the language, nothing was added to address existing problems in the language or to augment the language with modern language features.
     236While some may argue that modern language features may make C complex and inefficient, it is clear a language without modern capabilities is insufficient for the advanced programming problems existing today.
    245237
    246238
    247239\section{History}
    248240
    249 The \CFA project started with \Index*{K-W C}~\cite{Buhr94a,Till89}, which extended C with new declaration syntax, multiple return values from routines, and advanced assignment capabilities using the notion of tuples.
     241The \CFA project started with \Index*{K-W C}~\cite{Buhr94a,Till89}, which extended C with new declaration syntax, multiple return values from routines, and extended assignment capabilities using the notion of tuples.
    250242(See~\cite{Werther96} for similar work in \Index*[C++]{\CC{}}.)
    251 The first \CFA implementation of these extensions was by Esteves~\cite{Esteves04}.
    252 
    253 The signature feature of \CFA is \Index{overload}able \Index{parametric-polymorphic} functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a ©forall© clause (giving the language its name):
     243A first \CFA implementation of these extensions was by Esteves~\cite{Esteves04}.
     244The signature feature of \CFA is parametric-polymorphic functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a ©forall© clause (giving the language its name):
    254245\begin{lstlisting}
    255246®forall( otype T )® T identity( T val ) { return val; }
     
    259250\CFA{}\hspace{1pt}'s polymorphism was originally formalized by Ditchfiled~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}.
    260251However, at that time, there was little interesting in extending C, so work did not continue.
    261 As the saying goes, ``\Index*{What goes around, comes around.}'', and there is now renewed interest in the C programming language because of legacy code-bases, so the \CFA project has been restarted.
     252As the saying goes, ``What goes around, comes around.'', and there is now renewed interest in the C programming language because of legacy code-bases, so the \CFA project has been restarted.
    262253
    263254
     
    266257
    267258\CFA is designed to integrate directly with existing C programs and libraries.
    268 The most important feature of \Index{interoperability} is using the same \Index{calling convention}s, so there is no complex interface or overhead to call existing C routines.
     259The most important feature of \Index{interoperability} is using the same \Index{calling convention}s, so there is no overhead to call existing C routines.
    269260This feature allows \CFA programmers to take advantage of the existing panoply of C libraries to access thousands of external software features.
    270261Language developers often state that adequate \Index{library support} takes more work than designing and implementing the language itself.
    271262Fortunately, \CFA, like \Index*[C++]{\CC{}}, starts with immediate access to all exiting C libraries, and in many cases, can easily wrap library routines with simpler and safer interfaces, at very low cost.
    272 Hence, \CFA begins by leveraging the large repository of C libraries at little cost.
     263Hence, \CFA begins by leveraging the large repository of C libraries with little cost.
    273264
    274265\begin{comment}
     
    313304\end{comment}
    314305
    315 However, it is necessary to differentiate between C and \CFA code because of name \Index{overload}ing, as for \CC.
     306However, it is necessary to differentiate between C and \CFA code because of name overloading, as for \CC.
    316307For example, the C math-library provides the following routines for computing the absolute value of the basic types: ©abs©, ©labs©, ©llabs©, ©fabs©, ©fabsf©, ©fabsl©, ©cabsf©, ©cabs©, and ©cabsl©.
    317 Whereas, \CFA wraps each of these routines into ones with the overloaded name ©abs©:
     308Whereas, \CFA wraps each of these routines into ones with the common name ©abs©:
    318309\begin{cfa}
    319310char abs( char );
     
    335326Hence, there is the same need as in \CC, to know if a name is a C or \CFA name, so it can be correctly formed.
    336327There is no way around this problem, other than C's approach of creating unique names for each pairing of operation and type.
    337 This example strongly illustrates a core idea in \CFA: \emph{the \Index{power of a name}}.
     328This example strongly illustrates a core idea in \CFA: \emph{the power of a name}.
    338329The name ``©abs©'' evokes the notion of absolute value, and many mathematical types provide the notion of absolute value.
    339 Hence, knowing the name ©abs© is sufficient to apply it to any type where it is applicable.
    340 The time savings and safety of using one name uniformly versus $N$ unique names cannot be underestimated.
    341 
    342 
    343 \section[Compiling a CFA Program]{Compiling a \CFA Program}
     330Hence, knowing the name ©abs© should be sufficient to apply it to any type where it is applicable.
     331The time savings and safety of using one name uniformly versus $N$ unique names should not be underestimated.
     332
     333
     334\section[Compiling CFA Program]{Compiling \CFA Program}
    344335
    345336The command ©cfa© is used to compile \CFA program(s), and is based on the GNU \Indexc{gcc} command, \eg:
    346337\begin{cfa}
    347 cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA{}§-files [ assembler/loader-files ]
     338cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA§-files [ assembler/loader-files ]
    348339\end{cfa}
    349340\CFA programs having the following ©gcc© flags turned on:
     
    368359\Indexc{-debug}\index{compilation option!-debug@©-debug©}
    369360The program is linked with the debugging version of the runtime system.
    370 The debug version performs runtime checks to help during the debugging phase of a \CFA program, but can substantially slow program execution.
     361The debug version performs runtime checks to help during the debugging phase of a \CFA program, but substantially slows the execution of the program.
    371362The runtime checks should only be removed after the program is completely debugged.
    372363\textbf{This option is the default.}
     
    424415\end{description}
    425416These preprocessor variables allow conditional compilation of programs that must work differently in these situations.
    426 For example, to toggle between C and \CFA extensions, use the following:
     417For example, to toggle between C and \CFA extensions, using the following:
    427418\begin{cfa}
    428419#ifndef __CFORALL__
     
    435426
    436427
    437 \section{Constant Underscores}
    438 
    439 Numeric constants are extended to allow \Index{underscore}s\index{constant!underscore}, \eg:
     428\section{Constants Underscores}
     429
     430Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, \eg:
    440431\begin{cfa}
    4414322®_®147®_®483®_®648;                                    §\C{// decimal constant}§
     
    450441L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§;     §\C{// wide character constant}§
    451442\end{cfa}
    452 The rules for placement of underscores are:
    453 \begin{enumerate}[topsep=5pt,itemsep=5pt,parsep=0pt]
     443The rules for placement of underscores is as follows:
     444\begin{enumerate}
    454445\item
    455446A sequence of underscores is disallowed, \eg ©12__34© is invalid.
     
    472463\label{s:BackquoteIdentifiers}
    473464
    474 \CFA introduces in new keywords (see \VRef{s:CFAKeywords}) that can clash with existing C variable-names in legacy code.
    475 Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism:
     465\CFA accommodates keyword clashes with existing C variable-names by syntactic transformations using the \CFA backquote escape-mechanism:
    476466\begin{cfa}
    477467int ®`®otype®`® = 3;                    §\C{// make keyword an identifier}§
     
    501491
    502492
    503 \section{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break}}{Labelled continue / break}}
     493\section{Labelled Continue/Break}
    504494
    505495While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure.
    506496Unfortunately, this restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting.
    507 To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@\lstinline $continue$!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@\lstinline $break$!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85}.
     497To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@\lstinline $continue$!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@\lstinline $break$!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85,Java}.
    508498For both ©continue© and ©break©, the target label must be directly associated with a ©for©, ©while© or ©do© statement;
    509499for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement.
    510500\VRef[Figure]{f:MultiLevelResumeTermination} shows the labelled ©continue© and ©break©, specifying which control structure is the target for exit, and the corresponding C program using only ©goto©.
    511501The innermost loop has 7 exit points, which cause resumption or termination of one or more of the 7 \Index{nested control-structure}s.
    512 Java supports both labelled ©continue© and ©break© statements.
    513502
    514503\begin{figure}
     
    633622
    634623
    635 \section{\texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}}
     624\section{Switch Statement}
    636625
    637626C allows a number of questionable forms for the ©switch© statement:
     
    674663        ®// open input file
    675664®} else if ( argc == 2 ) {
    676         ®// open input file (duplicate)
     665        ®// open input file
    677666
    678667®} else {
     
    687676\begin{cfa}
    688677switch ( i ) {
    689   ®case 1: case 3: case 5:®     // odd values
    690         // odd action
     678  case 1: case 3: case 5:       // odd values
     679        // same action
    691680        break;
    692   ®case 2: case 4: case 6:®     // even values
    693         // even action
     681  case 2: case 4: case 6:       // even values
     682        // same action
    694683        break;
    695684}
     
    697686However, this situation is handled in other languages without fall-through by allowing a list of case values.
    698687While fall-through itself is not a problem, the problem occurs when fall-through is the default, as this semantics is unintuitive to many programmers and is different from virtually all other programming languages with a ©switch© statement.
    699 Hence, default fall-through semantics results in a large number of programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through.
     688Hence, default fall-through semantics results in a large number of programming errors as programmers often forget the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through.
    700689
    701690\item
     
    781770and there is only a medium amount of fall-through from one ©case© clause to the next, and most of these result from a list of case values executing common code, rather than a sequence of case actions that compound.
    782771\end{itemize}
    783 These observations put into perspective the \CFA changes to the ©switch©.
     772These observations help to put the \CFA changes to the ©switch© into perspective.
    784773\begin{enumerate}
    785774\item
     
    802791  case 7:
    803792        ...
    804         ®break®                                         §\C{// redundant explicit end of switch}§
     793        ®break®                                         §\C{// explicit end of switch}§
    805794  default:
    806795        j = 3;
     
    808797\end{cfa}
    809798Like the ©switch© statement, the ©choose© statement retains the fall-through semantics for a list of ©case© clauses;
    810 An implicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause.
    811 An explicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement.
     799the implicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause.
     800The explicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement.
    812801As well, allowing an explicit ©break© from the ©choose© is a carry over from the ©switch© statement, and expected by C programmers.
    813802\item
     
    838827
    839828
    840 \section{\texorpdfstring{\LstKeywordStyle{case} Clause}{case Clause}}
     829\section{Case Clause}
    841830
    842831C restricts the ©case© clause of a ©switch© statement to a single value.
     
    911900\begin{cfa}
    912901case ®1~5, 12~21, 35~42®:
    913 \end{cfa}
    914 
    915 
    916 \section{\texorpdfstring{\LstKeywordStyle{with} Clause / Statement}{with Clause / Statement}}
    917 \label{s:WithClauseStatement}
    918 
    919 In \Index{object-oriented} programming, there is an implicit first parameter, often names \textbf{©self©} or \textbf{©this©}, which is elided.
    920 \begin{C++}
    921 class C {
    922         int i, j;
    923         int mem() {              ®// implicit "this" parameter
    924                 i = 1;          ®// this->i
    925 ®               j = 3;          ®// this->j
    926 ®       }
    927 }
    928 \end{C++}
    929 Since CFA is non-object-oriented, the equivalent object-oriented program looks like:
    930 \begin{cfa}
    931 struct C {
    932         int i, j;
    933 };
    934 int mem( C &this ) {    // explicit "this" parameter
    935         ®this.®i = 1;                     // "this" is not elided
    936         ®this.®j = 2;
    937 }
    938 \end{cfa}
    939 but it is cumbersome having to write "©this.©" many times in a member.
    940 \CFA provides a ©with© clause/statement to elided the "©this.©".
    941 \begin{cfa}
    942 int mem( C &this ) ®with this® {
    943         i = 1;                  ®// this.i
    944 ®       j = 2;                  ®// this.j
    945 ®}
    946 \end{cfa}
    947 which extends to multiple routine parameters:
    948 \begin{cfa}
    949 struct D {
    950         double m, n;
    951 };
    952 int mem2( C &this1, D &this2 ) ®with this1, this2® {
    953         i = 1; j = 2;
    954         m = 1.0; n = 2.0;
    955 }
    956 \end{cfa}
    957 The ©with© clause/statement comes from Pascal~\cite[\S~4.F]{Pascal}.
    958 
    959 The statement form is used within a block:
    960 \begin{cfa}
    961 int foo() {
    962         struct S1 { ... } s1;
    963         struct S2 { ... } s2;
    964         ®with s1® {
    965                 // access fields of s1 without qualification
    966                 ®with s2® {  // nesting
    967                         // access fields of s2 without qualification
    968                 }
    969         }
    970         ®with s1, s2® {
    971                 // access unambiguous fields of s1 and s2 without qualification
    972         }
    973 }
    974 \end{cfa}
    975 
    976 Names clashes when opening multiple structures are ambiguous.
    977 \begin{cfa}
    978 struct A { int i; int j; } a, c;
    979 struct B { int i; int k; } b, c;
    980 ®with a, b® {
    981         j + k;                                          §\C{// unambiguous}§
    982         i;                                                      §\C{// ambiguous}§
    983         a.i + b.i;                                      §\C{// unambiguous}§
    984 }
    985 ®with c® {                                              §\C{// ambiguous}§
    986         // ...
    987 }
    988902\end{cfa}
    989903
     
    12221136
    12231137
    1224 \section{Pointer / Reference}
     1138\section{Pointer/Reference}
    12251139
    12261140C provides a \newterm{pointer type};
     
    25362450\end{cfa}
    25372451\\
    2538 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     2452\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    253924531® ®2® ®3
    25402454\end{cfa}
    25412455&
    2542 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     2456\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    254324571 2 3
    25442458\end{cfa}
     
    25472461The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators.
    25482462Similar simplification occurs for \Index{tuple} I/O, which prints all tuple values separated by ``\lstinline[showspaces=true]@, @''.
    2549 \begin{cfa}
    2550 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
     2463\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2464[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
    25512465sout | t1 | t2 | endl;                                  §\C{// print tuples}§
    25522466\end{cfa}
    2553 \begin{cfa}[showspaces=true,aboveskip=0pt]
    2554 1®, ®2®, ®3 4®, ®5®, ®6
     2467\begin{cfa}[mathescape=off,showspaces=true,belowskip=0pt]
     24681®, ®2®, ®3 3®, ®4®, ®5
    25552469\end{cfa}
    25562470Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority overloadable operator, other than assignment.
     
    25712485\\
    25722486&
    2573 \begin{cfa}[showspaces=true,aboveskip=0pt]
     2487\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    257424883 3 12 0 3 1 2
    25752489\end{cfa}
     
    25892503sout | 1 | 2 | 3 | endl;
    25902504\end{cfa}
    2591 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     2505\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    259225061 2 3
    25932507\end{cfa}
     
    26562570\subsection{Manipulator}
    26572571
    2658 The following \CC-style \Index{manipulator}s and routines control implicit seperation.
     2572The following routines and \CC-style \Index{manipulator}s control implicit seperation.
    26592573\begin{enumerate}
    26602574\item
    2661 Routines \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep}\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string.
     2575Routines \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string.
    26622576The separator string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters).
    2663 \begin{cfa}[mathescape=off,belowskip=0pt]
     2577\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    26642578sepSet( sout, ", $" );                                          §\C{// set separator from " " to ", \$"}§
    2665 sout | 1 | 2 | 3 | " \"" | ®sep® | "\"" | endl;
     2579sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\"" | endl;
    26662580\end{cfa}
    26672581%$
     
    26702584\end{cfa}
    26712585%$
    2672 \begin{cfa}[belowskip=0pt]
     2586\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    26732587sepSet( sout, " " );                                            §\C{// reset separator to " "}§
    26742588sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\"" | endl;
    26752589\end{cfa}
    2676 \begin{cfa}[showspaces=true,aboveskip=0pt]
     2590\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
    267725911® ®2® ®3 ®" "®
    26782592\end{cfa}
    2679 ©sepGet© can be used to store a separator and then restore it:
    2680 \begin{cfa}[belowskip=0pt]
    2681 char store[®sepSize®];                                          §\C{// sepSize is the maximum separator size}§
    2682 strcpy( store, sepGet( sout ) );
    2683 sepSet( sout, "_" );
    2684 sout | 1 | 2 | 3 | endl;
    2685 \end{cfa}
    2686 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    2687 1®_®2®_®3
    2688 \end{cfa}
    2689 \begin{cfa}[belowskip=0pt]
    2690 sepSet( sout, store );
    2691 sout | 1 | 2 | 3 | endl;
    2692 \end{cfa}
    2693 \begin{cfa}[showspaces=true,aboveskip=0pt]
    2694 1® ®2® ®3
    2695 \end{cfa}
    2696 
    2697 \item
    2698 Routine \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepTuple}\index{manipulator!sepTuple@©sepTuple©}/\Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string.
     2593
     2594\item
     2595Routine \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string.
    26992596The tuple separator-string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters).
    2700 \begin{cfa}[belowskip=0pt]
     2597\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    27012598sepSetTuple( sout, " " );                                       §\C{// set tuple separator from ", " to " "}§
    2702 sout | t1 | t2 | " \"" | ®sepTuple® | "\"" | endl;
    2703 \end{cfa}
    2704 \begin{cfa}[showspaces=true,aboveskip=0pt]
    2705 1 2 3 4 5 6 ®" "®
    2706 \end{cfa}
    2707 \begin{cfa}[belowskip=0pt]
     2599sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\"" | endl;
     2600\end{cfa}
     2601\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
     26021 2 3 4 ®" "®
     2603\end{cfa}
     2604\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    27082605sepSetTuple( sout, ", " );                                      §\C{// reset tuple separator to ", "}§
    27092606sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\"" | endl;
    27102607\end{cfa}
    2711 \begin{cfa}[showspaces=true,aboveskip=0pt]
    2712 1, 2, 3 4, 5, 6 ®", "®
    2713 \end{cfa}
    2714 As for ©sepGet©, ©sepGetTuple© can be use to store a tuple separator and then restore it.
    2715 
    2716 \item
    2717 Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items.
    2718 \begin{cfa}[belowskip=0pt]
    2719 sout | sepDisable | 1 | 2 | 3 | endl;           §\C{// globally turn off implicit separator}§
    2720 \end{cfa}
    2721 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     2608\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
     26091, 2, 3, 4 ®", "®
     2610\end{cfa}
     2611
     2612\item
     2613Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item.
     2614\begin{cfa}[mathescape=off,belowskip=0pt]
     2615sout | sepOn | 1 | 2 | 3 | sepOn | endl;        §\C{// separator at start/end of line}§
     2616\end{cfa}
     2617\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2618® ®1 2 3® ®
     2619\end{cfa}
     2620\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2621sout | 1 | sepOff | 2 | 3 | endl;                       §\C{// locally turn off implicit separator}§
     2622\end{cfa}
     2623\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     262412 3
     2625\end{cfa}
     2626The tuple separator also responses to being turned on and off.
     2627\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2628sout | sepOn | t1 | sepOff | t2 | endl;         §\C{// locally turn on/off implicit separation}§
     2629\end{cfa}
     2630\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2631, 1, 23, 4
     2632\end{cfa}
     2633Notice a tuple seperator starts the line because the next item is a tuple.
     2634
     2635\item
     2636Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items, unless locally adjusted.
     2637\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2638sout | sepDisable | 1 | 2 | 3 | endl;           §\C{// globally turn off implicit separation}§
     2639\end{cfa}
     2640\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    27222641123
    27232642\end{cfa}
    2724 \begin{cfa}[belowskip=0pt]
    2725 sout | sepEnable | 1 | 2 | 3 | endl;            §\C{// globally turn on implicit separator}§
     2643\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2644sout | 1 | ®sepOn® | 2 | 3 | endl;                      §\C{// locally turn on implicit separator}§
     2645\end{cfa}
     2646\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     26471® ®23
     2648\end{cfa}
     2649\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2650sout | sepEnable | 1 | 2 | 3 | endl;            §\C{// globally turn on implicit separation}§
    27262651\end{cfa}
    27272652\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    272826531 2 3
    27292654\end{cfa}
    2730 
    2731 \item
    2732 Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item.
    2733 \begin{cfa}[belowskip=0pt]
    2734 sout | 1 | sepOff | 2 | 3 | endl;                       §\C{// locally turn off implicit separator}§
    2735 \end{cfa}
    2736 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    2737 12 3
    2738 \end{cfa}
    2739 \begin{cfa}[belowskip=0pt]
    2740 sout | sepDisable | 1 | sepOn | 2 | 3 | endl; §\C{// locally turn on implicit separator}§
    2741 \end{cfa}
    2742 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    2743 1 23
    2744 \end{cfa}
    2745 The tuple separator also responses to being turned on and off.
    2746 \begin{cfa}[belowskip=0pt]
    2747 sout | t1 | sepOff | t2 | endl;                         §\C{// locally turn on/off implicit separator}§
    2748 \end{cfa}
    2749 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    2750 1, 2, 34, 5, 6
    2751 \end{cfa}
    2752 ©sepOn© \emph{cannot} be used to start/end a line with a separator because separators do not appear at the start/end of a line;
    2753 use ©sep© to accomplish this functionality.
    2754 \begin{cfa}[belowskip=0pt]
    2755 sout | sepOn | 1 | 2 | 3 | sepOn | endl ;       §\C{// sepOn does nothing at start/end of line}§
    2756 \end{cfa}
    2757 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    2758 1 2 3
    2759 \end{cfa}
    2760 \begin{cfa}[belowskip=0pt]
    2761 sout | sep | 1 | 2 | 3 | sep | endl ;           §\C{// use sep to print separator at start/end of line}§
    2762 \end{cfa}
    2763 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    2764 ® ®1 2 3® ®
    2765 \end{cfa}
    27662655\end{enumerate}
    27672656
    27682657\begin{comment}
    27692658#include <fstream>
    2770 #include <string.h>                                                                             // strcpy
    27712659
    27722660int main( void ) {
    27732661        int x = 1, y = 2, z = 3;
    27742662        sout | x | y | z | endl;
    2775         [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
     2663        [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
    27762664        sout | t1 | t2 | endl;                                          // print tuples
    27772665        sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
     
    27872675
    27882676        sepSet( sout, ", $" );                                          // set separator from " " to ", $"
    2789         sout | 1 | 2 | 3 | " \"" | sep | "\"" | endl;
     2677        sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
    27902678        sepSet( sout, " " );                                            // reset separator to " "
    27912679        sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
    27922680
    2793         char store[sepSize];
    2794         strcpy( store, sepGet( sout ) );
    2795         sepSet( sout, "_" );
    2796         sout | 1 | 2 | 3 | endl;
    2797         sepSet( sout, store );
    2798         sout | 1 | 2 | 3 | endl;
     2681        sout | sepOn | 1 | 2 | 3 | sepOn | endl;        // separator at start of line
     2682        sout | 1 | sepOff | 2 | 3 | endl;                       // locally turn off implicit separator
     2683
     2684        sout | sepDisable | 1 | 2 | 3 | endl;           // globally turn off implicit separation
     2685        sout | 1 | sepOn | 2 | 3 | endl;                        // locally turn on implicit separator
     2686        sout | sepEnable | 1 | 2 | 3 | endl;            // globally turn on implicit separation
    27992687
    28002688        sepSetTuple( sout, " " );                                       // set tuple separator from ", " to " "
    2801         sout | t1 | t2 | " \"" | sepTuple | "\"" | endl;
     2689        sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
    28022690        sepSetTuple( sout, ", " );                                      // reset tuple separator to ", "
    28032691        sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
    28042692
    2805         sout | sepDisable | 1 | 2 | 3 | endl;           // globally turn off implicit separator
    2806         sout | sepEnable | 1 | 2 | 3 | endl;            // globally turn on implicit separator
    2807        
    2808         sout | 1 | sepOff | 2 | 3 | endl;                       // locally turn on implicit separator
    2809         sout | sepDisable | 1 | sepOn | 2 | 3 | endl; // globally turn off implicit separator
    2810         sout | sepEnable;
    2811         sout | t1 | sepOff | t2 | endl;                         // locally turn on/off implicit separator
    2812 
    2813         sout | sepOn | 1 | 2 | 3 | sepOn | endl ;       // sepOn does nothing at start/end of line
    2814         sout | sep | 1 | 2 | 3 | sep | endl ;           // use sep to print separator at start/end of line
     2693        sout | t1 | t2 | endl;                                          // print tuple
     2694        sout | sepOn | t1 | sepOff | t2 | endl;         // locally turn on/off implicit separation
    28152695}
    28162696
     
    53445224
    53455225
    5346 \section{\texorpdfstring{\CFA Keywords}{Cforall Keywords}}
     5226\section{\CFA Keywords}
    53475227\label{s:CFAKeywords}
    53485228
    5349 \CFA introduces the following new keywords.
    5350 
    53515229\begin{quote2}
    5352 \begin{tabular}{lllll}
     5230\begin{tabular}{llll}
    53535231\begin{tabular}{@{}l@{}}
    5354 ©_At©                   \\
     5232©_AT©                   \\
    53555233©catch©                 \\
    53565234©catchResume©   \\
    53575235©choose©                \\
    53585236©coroutine©             \\
     5237©disable©               \\
    53595238\end{tabular}
    53605239&
    53615240\begin{tabular}{@{}l@{}}
    5362 ©disable©               \\
    53635241©dtype©                 \\
    53645242©enable©                \\
    53655243©fallthrough©   \\
    53665244©fallthru©              \\
     5245©finally©               \\
     5246©forall©                \\
    53675247\end{tabular}
    53685248&
    53695249\begin{tabular}{@{}l@{}}
    5370 ©finally©               \\
    5371 ©forall©                \\
    53725250©ftype©                 \\
    53735251©lvalue©                \\
    53745252©monitor©               \\
     5253©mutex©                 \\
     5254©one_t©                 \\
     5255©otype©                 \\
    53755256\end{tabular}
    53765257&
    53775258\begin{tabular}{@{}l@{}}
    5378 ©mutex©                 \\
    5379 ©one_t©                 \\
    5380 ©otype©                 \\
    53815259©throw©                 \\
    53825260©throwResume©   \\
    5383 \end{tabular}
    5384 &
    5385 \begin{tabular}{@{}l@{}}
    53865261©trait©                 \\
    53875262©try©                   \\
    53885263©ttype©                 \\
    53895264©zero_t©                \\
    5390                                 \\
    53915265\end{tabular}
    53925266\end{tabular}
     
    56745548// C unsafe allocation
    56755549extern "C" {
    5676 void * malloc( size_t size );§\indexc{memset}§
     5550void * mallac( size_t size );§\indexc{memset}§
    56775551void * calloc( size_t dim, size_t size );§\indexc{calloc}§
    56785552void * realloc( void * ptr, size_t size );§\indexc{realloc}§
  • src/CodeGen/CodeGenerator.cc

    r3d4b23fa r55a68c3  
    1414//
    1515
    16 #include <cassert>                   // for assert, assertf
    17 #include <list>                      // for _List_iterator, list, list<>::it...
     16#include <algorithm>
     17#include <iostream>
     18#include <cassert>
     19#include <list>
     20
     21#include "Parser/ParseNode.h"
     22
     23#include "SynTree/Declaration.h"
     24#include "SynTree/Expression.h"
     25#include "SynTree/Initializer.h"
     26#include "SynTree/Statement.h"
     27#include "SynTree/Type.h"
     28#include "SynTree/Attribute.h"
     29
     30#include "Common/utility.h"
     31#include "Common/UnimplementedError.h"
    1832
    1933#include "CodeGenerator.h"
    20 #include "Common/SemanticError.h"    // for SemanticError
    21 #include "Common/UniqueName.h"       // for UniqueName
    22 #include "Common/utility.h"          // for CodeLocation, toString
    23 #include "GenType.h"                 // for genType
    24 #include "InitTweak/InitTweak.h"     // for getPointerBase
    25 #include "OperatorTable.h"           // for OperatorInfo, operatorLookup
    26 #include "Parser/LinkageSpec.h"      // for Spec, Intrinsic
    27 #include "SynTree/Attribute.h"       // for Attribute
    28 #include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
    29 #include "SynTree/Constant.h"        // for Constant
    30 #include "SynTree/Declaration.h"     // for DeclarationWithType, TypeDecl
    31 #include "SynTree/Expression.h"      // for Expression, UntypedExpr, Applica...
    32 #include "SynTree/Initializer.h"     // for Initializer, ListInit, Designation
    33 #include "SynTree/Label.h"           // for Label, operator<<
    34 #include "SynTree/Statement.h"       // for Statement, AsmStmt, BranchStmt
    35 #include "SynTree/Type.h"            // for Type, Type::StorageClasses, Func...
     34#include "OperatorTable.h"
     35#include "GenType.h"
     36
     37#include "InitTweak/InitTweak.h"
    3638
    3739using namespace std;
  • src/CodeGen/CodeGenerator.h

    r3d4b23fa r55a68c3  
    1717#define CODEGENV_H
    1818
    19 #include <list>                   // for list
    20 #include <ostream>                // for ostream, operator<<
    21 #include <string>                 // for string
     19#include <list>
    2220
    23 #include "SynTree/Declaration.h"  // for DeclarationWithType (ptr only), Fun...
    24 #include "SynTree/Visitor.h"      // for Visitor
    25 #include "SynTree/SynTree.h"      // for Visitor Nodes
     21#include "SynTree/Declaration.h"
     22#include "SynTree/SynTree.h"
     23#include "SynTree/Visitor.h"
     24
     25#include "SymTab/Indexer.h"
     26
     27#include "Common/Indenter.h"
     28#include "Common/utility.h"
    2629
    2730namespace CodeGen {
  • src/CodeGen/FixMain.cc

    r3d4b23fa r55a68c3  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixMain.cc --
     7// FixMain.cc -- 
    88//
    99// Author           : Thierry Delisle
    1010// Created On       : Thr Jan 12 14:11:09 2017
    11 // Last Modified By :
    12 // Last Modified On :
     11// Last Modified By : 
     12// Last Modified On : 
    1313// Update Count     : 0
    1414//
    1515
    1616
    17 #include "FixMain.h"
     17#include "FixMain.h"   
    1818
    19 #include <cassert>                 // for assert, assertf
    20 #include <fstream>                 // for operator<<, basic_ostream::operator<<
    21 #include <list>                    // for list
    22 #include <string>                  // for operator<<
     19#include <fstream>
     20#include <iostream>
    2321
    24 #include "Common/SemanticError.h"  // for SemanticError
    25 #include "SynTree/Declaration.h"   // for FunctionDecl, operator<<
    26 #include "SynTree/Type.h"          // for FunctionType
     22#include "Common/SemanticError.h"
     23#include "SynTree/Declaration.h"
    2724
    2825namespace CodeGen {
    2926        bool FixMain::replace_main = false;
    3027        std::unique_ptr<FunctionDecl> FixMain::main_signature = nullptr;
    31 
    32         void FixMain::registerMain(FunctionDecl* functionDecl)
     28       
     29        void FixMain::registerMain(FunctionDecl* functionDecl) 
    3330        {
    34                 if(main_signature) {
    35                         throw SemanticError("Multiple definition of main routine\n", functionDecl);
     31                if(main_signature) { 
     32                        throw SemanticError("Multiple definition of main routine\n", functionDecl); 
    3633                }
    3734                main_signature.reset( functionDecl->clone() );
  • src/CodeGen/FixNames.cc

    r3d4b23fa r55a68c3  
    1414//
    1515
     16#include <memory>
     17
    1618#include "FixNames.h"
    17 
    18 #include <memory>                  // for unique_ptr
    19 #include <string>                  // for string, operator!=, operator==
    20 
    21 #include "Common/SemanticError.h"  // for SemanticError
    22 #include "FixMain.h"               // for FixMain
    23 #include "Parser/LinkageSpec.h"    // for Cforall, isMangled
    24 #include "SymTab/Mangler.h"        // for Mangler
    25 #include "SynTree/Constant.h"      // for Constant
    26 #include "SynTree/Declaration.h"   // for FunctionDecl, ObjectDecl, Declarat...
    27 #include "SynTree/Expression.h"    // for ConstantExpr
    28 #include "SynTree/Label.h"         // for Label, noLabels
    29 #include "SynTree/Statement.h"     // for ReturnStmt, CompoundStmt
    30 #include "SynTree/Type.h"          // for Type, BasicType, Type::Qualifiers
    31 #include "SynTree/Visitor.h"       // for Visitor, acceptAll
     19#include "SynTree/Declaration.h"
     20#include "SynTree/Expression.h"
     21#include "SynTree/Visitor.h"
     22#include "SymTab/Mangler.h"
     23#include "OperatorTable.h"
     24#include "FixMain.h"
    3225
    3326namespace CodeGen {
     
    4942                                                                                                                                   main_type = new FunctionType( Type::Qualifiers(), true ), nullptr )
    5043                                };
    51                 main_type->get_returnVals().push_back(
     44                main_type->get_returnVals().push_back( 
    5245                        new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )
    5346                );
     
    5952        std::string mangle_main_args() {
    6053                FunctionType* main_type;
    61                 std::unique_ptr<FunctionDecl> mainDecl { new FunctionDecl( "main", Type::StorageClasses(), LinkageSpec::Cforall,
     54                std::unique_ptr<FunctionDecl> mainDecl { new FunctionDecl( "main", Type::StorageClasses(), LinkageSpec::Cforall, 
    6255                                                                                                                                   main_type = new FunctionType( Type::Qualifiers(), false ), nullptr )
    6356                                };
    64                 main_type->get_returnVals().push_back(
     57                main_type->get_returnVals().push_back( 
    6558                        new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )
    6659                );
    6760
    68                 mainDecl->get_functionType()->get_parameters().push_back(
     61                mainDecl->get_functionType()->get_parameters().push_back( 
    6962                        new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )
    7063                );
    7164
    72                 mainDecl->get_functionType()->get_parameters().push_back(
    73                         new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0,
    74                         new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Char ) ) ),
     65                mainDecl->get_functionType()->get_parameters().push_back( 
     66                        new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, 
     67                        new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Char ) ) ), 
    7568                        nullptr )
    7669                );
     
    8275
    8376        bool is_main(const std::string& name) {
    84                 static std::string mains[] = {
    85                         mangle_main(),
     77                static std::string mains[] = { 
     78                        mangle_main(), 
    8679                        mangle_main_args()
    8780                };
     
    119112                        int nargs = functionDecl->get_functionType()->get_parameters().size();
    120113                        if( !(nargs == 0 || nargs == 2 || nargs == 3) ) {
    121                                 throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", functionDecl);
     114                                throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", functionDecl); 
    122115                        }
    123116                        functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new ConstantExpr( Constant::from_int( 0 ) ) ) );
  • src/CodeGen/FixNames.h

    r3d4b23fa r55a68c3  
    1717#define FIXNAMES_H
    1818
    19 #include <list>  // for list
    20 
    21 class Declaration;
     19#include "SynTree/SynTree.h"
    2220
    2321namespace CodeGen {
  • src/CodeGen/GenType.cc

    r3d4b23fa r55a68c3  
    1414//
    1515
    16 #include <cassert>                // for assert, assertf
    17 #include <list>                   // for _List_iterator, _List_const_iterator
    18 #include <sstream>                // for operator<<, ostringstream, basic_os...
    19 
    20 #include "CodeGenerator.h"        // for CodeGenerator
     16#include <sstream>
     17#include <cassert>
     18
    2119#include "GenType.h"
    22 #include "SynTree/Declaration.h"  // for DeclarationWithType
    23 #include "SynTree/Expression.h"   // for Expression
    24 #include "SynTree/Type.h"         // for PointerType, Type, FunctionType
    25 #include "SynTree/Visitor.h"      // for Visitor
     20#include "CodeGenerator.h"
     21
     22#include "SynTree/Declaration.h"
     23#include "SynTree/Expression.h"
     24#include "SynTree/Type.h"
     25#include "SynTree/Visitor.h"
    2626
    2727namespace CodeGen {
  • src/CodeGen/GenType.h

    r3d4b23fa r55a68c3  
    1717#define _GENTYPE_H
    1818
    19 #include <string>  // for string
    20 
    21 class Type;
     19#include <string>
     20#include "SynTree/SynTree.h"
    2221
    2322namespace CodeGen {
  • src/CodeGen/Generate.cc

    r3d4b23fa r55a68c3  
    1414//
    1515
    16 #include <iostream>                  // for ostream, endl, operator<<
    17 #include <list>                      // for list
    18 #include <string>                    // for operator<<
     16#include <algorithm>
     17#include <iostream>
     18#include <cassert>
     19#include <list>
    1920
    20 #include "CodeGenerator.h"           // for CodeGenerator, doSemicolon, oper...
    21 #include "GenType.h"                 // for genPrettyType
    2221#include "Generate.h"
    23 #include "Parser/LinkageSpec.h"      // for isBuiltin, isGeneratable
    24 #include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
    25 #include "SynTree/Declaration.h"     // for Declaration
    26 #include "SynTree/Type.h"            // for Type
     22#include "SynTree/Declaration.h"
     23#include "CodeGenerator.h"
     24#include "GenType.h"
     25#include "SynTree/SynTree.h"
     26#include "SynTree/Type.h"
     27#include "SynTree/BaseSyntaxNode.h"
     28// #include "Tuples/Tuples.h"
    2729
    2830using namespace std;
  • src/CodeGen/Generate.h

    r3d4b23fa r55a68c3  
    1717#define GENERATE_H
    1818
    19 #include <iostream>  // for ostream
    20 #include <list>      // for list
     19#include <list>
     20#include <iostream>
    2121
    22 class BaseSyntaxNode;
    23 class Declaration;
     22#include "SynTree/SynTree.h"
    2423
    2524namespace CodeGen {
  • src/CodeGen/OperatorTable.cc

    r3d4b23fa r55a68c3  
    1414//
    1515
    16 #include <map>      // for map, _Rb_tree_const_iterator, map<>::const_iterator
    17 #include <utility>  // for pair
    18 
     16#include <map>
    1917#include "OperatorTable.h"
    2018
  • src/CodeTools/DeclStats.cc

    r3d4b23fa r55a68c3  
    1616#include "DeclStats.h"
    1717
    18 #include <iostream>                // for operator<<, basic_ostream, cout
    19 #include <map>                     // for map
    20 #include <string>                  // for string, operator+, operator<<, cha...
    21 #include <unordered_map>           // for unordered_map
    22 #include <unordered_set>           // for unordered_set
    23 #include <utility>                 // for pair, make_pair
    24 
    25 #include "Common/SemanticError.h"  // for SemanticError
    26 #include "Common/VectorMap.h"      // for VectorMap
    27 #include "GenPoly/GenPoly.h"       // for hasPolyBase
    28 #include "Parser/LinkageSpec.h"    // for ::NoOfSpecs, Spec
    29 #include "SynTree/Declaration.h"   // for FunctionDecl, TypeDecl, Declaration
    30 #include "SynTree/Expression.h"    // for UntypedExpr, Expression
    31 #include "SynTree/Statement.h"     // for CompoundStmt
    32 #include "SynTree/Type.h"          // for Type, FunctionType, PointerType
    33 #include "SynTree/Visitor.h"       // for maybeAccept, Visitor, acceptAll
     18#include <iostream>
     19#include <map>
     20#include <sstream>
     21#include <string>
     22#include <unordered_map>
     23#include <unordered_set>
     24
     25#include "Common/VectorMap.h"
     26#include "GenPoly/GenPoly.h"
     27#include "Parser/LinkageSpec.h"
     28#include "SynTree/Declaration.h"
     29#include "SynTree/Visitor.h"
    3430
    3531namespace CodeTools {
    36 
     32       
    3733        class DeclStats : public Visitor {
    3834                template<typename T>
     
    7975                                sum(n_types, o.n_types);
    8076                                sum(p_new, o.p_new);
    81 
     77                               
    8278                                return *this;
    8379                        }
    8480                };
    85 
     81               
    8682                struct Stats {
    8783                        unsigned n_decls;     ///< Total number of declarations
     
    10298                        /// Stats for the return list
    10399                        ArgPackStats returns;
    104 
     100                       
    105101                        /// Count of declarations with each number of assertions
    106102                        std::map<unsigned, unsigned> n_assns;
     
    109105                        /// Stats for the assertions' return types
    110106                        ArgPackStats assn_returns;
    111 
     107                       
    112108                        Stats() : n_decls(0), n_type_params(), by_name(), basic_type_names(), compound_type_names(), basic_type_decls(), compound_type_decls(), params(), returns(), n_assns(), assn_params(), assn_returns() {}
    113109
     
    126122                                sum( assn_params, o.assn_params );
    127123                                sum( assn_returns, o.assn_returns );
    128 
     124                               
    129125                                return *this;
    130126                        }
     
    148144
    149145                                n += dt->size();
    150 
     146                               
    151147                                std::stringstream ss;
    152148                                dt->print( ss );
     
    180176                        ++pstats.n_types.at( types.size() );
    181177                }
    182 
     178               
    183179                void analyzeFunc( FunctionType* fnTy, Stats& stats, ArgPackStats& params, ArgPackStats& returns ) {
    184180                        std::unordered_set<std::string> seen;
     
    190186                        auto& args = expr->get_args();
    191187                        unsigned fanout = args.size();
    192 
     188                       
    193189                        ++exprs_by_fanout_at_depth[ std::make_pair(depth, fanout) ];
    194190                        for ( Expression* arg : args ) {
     
    209205                                return;
    210206                        }
    211 
     207                       
    212208                        Stats& stats = for_linkage[ decl->get_linkage() ];
    213209
     
    327323                }
    328324
    329                 void printPairMap( const std::string& name,
     325                void printPairMap( const std::string& name, 
    330326                                   const std::map<std::pair<unsigned, unsigned>, unsigned>& map ) {
    331327                        for ( const auto& entry : map ) {
    332328                                const auto& key = entry.first;
    333                                 std::cout << "\"" << name << "\"," << key.first << "," << key.second << ","
     329                                std::cout << "\"" << name << "\"," << key.first << "," << key.second << "," 
    334330                                          << entry.second << std::endl;
    335331                        }
    336332                }
    337 
     333               
    338334        public:
    339335                void print() {
     
    370366                stats.print();
    371367        }
    372 
     368       
    373369} // namespace CodeTools
    374370
  • src/CodeTools/DeclStats.h

    r3d4b23fa r55a68c3  
    1717#define DECLSTATS_H
    1818
    19 #include <list>  // for list
    20 
    21 class Declaration;
     19#include "SynTree/SynTree.h"
    2220
    2321namespace CodeTools {
  • src/CodeTools/TrackLoc.cc

    r3d4b23fa r55a68c3  
    1616#include "TrackLoc.h"
    1717
    18 #include <cstdlib>                    // for size_t, exit, EXIT_FAILURE
    19 #include <iostream>                   // for operator<<, ostream, basic_ostream
    20 #include <iterator>                   // for back_inserter, inserter
    21 #include <stack>                      // for stack
    22 #include <string>                     // for operator<<, string
    23 #include <typeindex>                  // for type_index
     18#include <cstdlib>
    2419
    25 #include "Common/PassVisitor.h"       // for PassVisitor
    26 #include "Common/PassVisitor.impl.h"  // for acceptAll
    27 #include "Common/SemanticError.h"     // for SemanticError
    28 #include "Common/utility.h"           // for CodeLocation
    29 #include "SynTree/BaseSyntaxNode.h"   // for BaseSyntaxNode
    30 #include "SynTree/Mutator.h"          // for mutateAll
    31 #include "SynTree/Visitor.h"          // for acceptAll
     20#include <iostream>
     21#include <sstream>
     22#include <stack>
     23#include <string>
     24#include <typeindex>
    3225
    33 class Declaration;
     26#include "Common/utility.h"
     27#include "Common/PassVisitor.h"
     28#include "Common/VectorMap.h"
     29#include "GenPoly/GenPoly.h"
     30#include "Parser/LinkageSpec.h"
     31#include "SynTree/Declaration.h"
     32#include "SynTree/Initializer.h"
    3433
    3534namespace CodeTools {
  • src/CodeTools/TrackLoc.h

    r3d4b23fa r55a68c3  
    1717#define TRACKLOC_H
    1818
    19 #include <cstddef>   // for size_t
    20 #include <list>      // for list
    21 
    22 class Declaration;
     19#include "SynTree/SynTree.h"
    2320
    2421namespace CodeTools {
  • src/Common/Assert.cc

    r3d4b23fa r55a68c3  
    1414//
    1515
    16 #include <cstdarg>  // for va_end, va_list, va_start
    17 #include <cstdio>   // for fprintf, stderr, vfprintf
    18 #include <cstdlib>  // for abort
     16#include <assert.h>
     17#include <cstdarg>                                                                              // varargs
     18#include <cstdio>                                                                               // fprintf
     19#include <cstdlib>                                                                              // abort
    1920
    2021extern const char * __progname;                                                 // global name of running executable (argv[0])
  • src/Common/SemanticError.cc

    r3d4b23fa r55a68c3  
    1414//
    1515
    16 #include <cstdio>            // for fileno, stderr
    17 #include <unistd.h>          // for isatty
    18 #include <iostream>          // for basic_ostream, operator<<, ostream
    19 #include <list>              // for list, _List_iterator
    20 #include <string>            // for string, operator<<, operator+, to_string
     16#include <iostream>
     17#include <list>
     18#include <string>
     19#include <algorithm>
     20#include <iterator>
    2121
    22 #include "Common/utility.h"  // for to_string, CodeLocation (ptr only)
    2322#include "SemanticError.h"
     23
     24#include <unistd.h>
    2425
    2526inline const std::string& error_str() {
  • src/Common/SemanticError.h

    r3d4b23fa r55a68c3  
    1717#define SEMANTICERROR_H
    1818
    19 #include <exception>  // for exception
    20 #include <iostream>   // for ostream
    21 #include <list>       // for list
    22 #include <string>     // for string
     19#include <exception>
     20#include <string>
     21#include <sstream>
     22#include <list>
     23#include <iostream>
    2324
    24 #include "utility.h"  // for CodeLocation, toString
     25#include "utility.h"
    2526
    2627struct error {
  • src/Concurrency/Keywords.cc

    r3d4b23fa r55a68c3  
    1717#include "Concurrency/Keywords.h"
    1818
    19 #include <cassert>                 // for assert
    20 #include <string>                  // for string, operator==
    21 
    22 #include "Common/SemanticError.h"  // for SemanticError
    23 #include "Common/utility.h"        // for deleteAll, map_range
    24 #include "InitTweak/InitTweak.h"   // for isConstructor
    25 #include "Parser/LinkageSpec.h"    // for Cforall
    26 #include "SymTab/AddVisit.h"       // for acceptAndAdd
    27 #include "SynTree/Constant.h"      // for Constant
    28 #include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
    29 #include "SynTree/Expression.h"    // for VariableExpr, ConstantExpr, Untype...
    30 #include "SynTree/Initializer.h"   // for SingleInit, ListInit, Initializer ...
    31 #include "SynTree/Label.h"         // for Label
    32 #include "SynTree/Statement.h"     // for CompoundStmt, DeclStmt, ExprStmt
    33 #include "SynTree/Type.h"          // for StructInstType, Type, PointerType
    34 #include "SynTree/Visitor.h"       // for Visitor, acceptAll
    35 
    36 class Attribute;
     19#include "InitTweak/InitTweak.h"
     20#include "SymTab/AddVisit.h"
     21#include "SynTree/Declaration.h"
     22#include "SynTree/Expression.h"
     23#include "SynTree/Initializer.h"
     24#include "SynTree/Statement.h"
     25#include "SynTree/Type.h"
     26#include "SynTree/Visitor.h"
    3727
    3828namespace Concurrency {
     
    332322                if( needs_main ) {
    333323                        FunctionType * main_type = new FunctionType( noQualifiers, false );
    334 
     324                       
    335325                        main_type->get_parameters().push_back( this_decl->clone() );
    336326
     
    371361        void ConcurrentSueKeyword::addRoutines( ObjectDecl * field, FunctionDecl * func ) {
    372362                CompoundStmt * statement = new CompoundStmt( noLabels );
    373                 statement->push_back(
     363                statement->push_back( 
    374364                        new ReturnStmt(
    375365                                noLabels,
     
    396386        //=============================================================================================
    397387        void MutexKeyword::visit(FunctionDecl* decl) {
    398                 Visitor::visit(decl);
     388                Visitor::visit(decl);           
    399389
    400390                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
     
    520510        void ThreadStarter::visit(FunctionDecl * decl) {
    521511                Visitor::visit(decl);
    522 
     512               
    523513                if( ! InitTweak::isConstructor(decl->get_name()) ) return;
    524514
     
    538528                if( ! stmt ) return;
    539529
    540                 stmt->push_back(
     530                stmt->push_back( 
    541531                        new ExprStmt(
    542532                                noLabels,
  • src/Concurrency/Keywords.h

    r3d4b23fa r55a68c3  
    1818#define KEYWORDS_H
    1919
    20 #include <list>  // for list
     20#include <list>
    2121
    22 class Declaration;
     22#include "SynTree/Declaration.h"
    2323
    2424namespace Concurrency {
  • src/ControlStruct/ExceptTranslate.cc

    r3d4b23fa r55a68c3  
    1010// Created On       : Wed Jun 14 16:49:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul 12 15:07:00 2017
    13 // Update Count     : 3
     12// Last Modified On : Fri Jun 30 13:30:00 2017
     13// Update Count     : 1
    1414//
    1515
     
    157157        Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
    158158                // { int NAME = EXPR; __throw_terminate( &NAME ); }
    159                 return create_given_throw( "__cfaehm__throw_terminate", throwStmt );
     159                return create_given_throw( "__cfaehm__throw_termination", throwStmt );
    160160        }
    161161        Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) {
     
    164164                Statement * result = new ExprStmt(
    165165                        throwStmt->get_labels(),
    166                         new UntypedExpr( new NameExpr( "__cfaehm__rethrow_terminate" ) )
     166                        new UntypedExpr( new NameExpr( "__cfaehm__rethrow_termination" ) )
    167167                        );
    168168                delete throwStmt;
     
    171171        Statement * create_resume_throw( ThrowStmt *throwStmt ) {
    172172                // __throw_resume( EXPR );
    173                 return create_given_throw( "__cfaehm__throw_resume", throwStmt );
     173                return create_given_throw( "__cfaehm__throw_resumption", throwStmt );
    174174        }
    175175        Statement * create_resume_rethrow( ThrowStmt *throwStmt ) {
     
    593593
    594594                PassVisitor<ExceptionMutatorCore> translator;
    595                 mutateAll( translationUnit, translator );
     595                for ( Declaration * decl : translationUnit ) {
     596                        decl->acceptMutator( translator );
     597                }
    596598        }
    597599}
  • src/GenPoly/InstantiateGeneric.cc

    r3d4b23fa r55a68c3  
    171171                Type* postmutate( UnionInstType *inst );
    172172
    173                 void premutate( __attribute__((unused)) FunctionType * ftype ) {
     173                void premutate( FunctionType * ftype ) {
    174174                        GuardValue( inFunctionType );
    175175                        inFunctionType = true;
  • src/InitTweak/GenInit.cc

    r3d4b23fa r55a68c3  
    7171                // that need to be constructed or destructed
    7272                void previsit( StructDecl *aggregateDecl );
    73                 void previsit( __attribute__((unused)) UnionDecl    * aggregateDecl ) { visit_children = false; }
    74                 void previsit( __attribute__((unused)) EnumDecl     * aggregateDecl ) { visit_children = false; }
    75                 void previsit( __attribute__((unused)) TraitDecl    * aggregateDecl ) { visit_children = false; }
    76                 void previsit( __attribute__((unused)) TypeDecl     * typeDecl )      { visit_children = false; }
    77                 void previsit( __attribute__((unused)) TypedefDecl  * typeDecl )      { visit_children = false; }
    78                 void previsit( __attribute__((unused)) FunctionType * funcType )      { visit_children = false; }
     73                void previsit( UnionDecl *aggregateDecl ) { visit_children = false; }
     74                void previsit( EnumDecl *aggregateDecl ) { visit_children = false; }
     75                void previsit( TraitDecl *aggregateDecl ) { visit_children = false; }
     76                void previsit( TypeDecl *typeDecl ) { visit_children = false; }
     77                void previsit( TypedefDecl *typeDecl ) { visit_children = false; }
     78
     79                void previsit( FunctionType *funcType ) { visit_children = false; }
    7980
    8081                void previsit( CompoundStmt * compoundStmt );
     
    335336        }
    336337
    337         void CtorDtor::previsit( __attribute__((unused)) CompoundStmt * compoundStmt ) {
     338        void CtorDtor::previsit( CompoundStmt * compoundStmt ) {
    338339                GuardScope( managedTypes );
    339340        }
  • src/MakeLibCfa.cc

    r3d4b23fa r55a68c3  
    1515
    1616#include "MakeLibCfa.h"
    17 
    18 #include <cassert>                 // for assert
    19 #include <string>                   // for operator==, string
    20 
    21 #include "CodeGen/OperatorTable.h"  // for OperatorInfo, operatorLookup, Ope...
    22 #include "Common/SemanticError.h"   // for SemanticError
    23 #include "Common/UniqueName.h"      // for UniqueName
    24 #include "Parser/LinkageSpec.h"     // for Spec, Intrinsic, C
    25 #include "SynTree/Declaration.h"    // for FunctionDecl, ObjectDecl, Declara...
    26 #include "SynTree/Expression.h"     // for NameExpr, UntypedExpr, VariableExpr
    27 #include "SynTree/Initializer.h"    // for SingleInit
    28 #include "SynTree/Label.h"          // for Label
    29 #include "SynTree/Statement.h"      // for CompoundStmt, ReturnStmt
    30 #include "SynTree/Type.h"           // for FunctionType
    31 #include "SynTree/Visitor.h"        // for acceptAll, Visitor
     17#include "SynTree/Visitor.h"
     18#include "SynTree/Declaration.h"
     19#include "SynTree/Type.h"
     20#include "SynTree/Expression.h"
     21#include "SynTree/Statement.h"
     22#include "SynTree/Initializer.h"
     23#include "CodeGen/OperatorTable.h"
     24#include "Common/UniqueName.h"
    3225
    3326namespace LibCfa {
  • src/MakeLibCfa.h

    r3d4b23fa r55a68c3  
    1717#define LIBCFA_MAKELIBCFA_H
    1818
    19 #include <list>  // for list
    20 
    21 class Declaration;
     19#include <list>
     20#include <SynTree/SynTree.h>
    2221
    2322namespace LibCfa {
  • src/Makefile.am

    r3d4b23fa r55a68c3  
    4343driver_cfa_cpp_SOURCES = ${SRC}
    4444driver_cfa_cpp_LDADD = ${LEXLIB} -ldl                   # yywrap
    45 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14
     45driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14
    4646driver_cfa_cpp_LDFLAGS = -Xlinker -export-dynamic
    4747
  • src/Makefile.in

    r3d4b23fa r55a68c3  
    544544driver_cfa_cpp_SOURCES = ${SRC}
    545545driver_cfa_cpp_LDADD = ${LEXLIB} -ldl                   # yywrap
    546 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14
     546driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14
    547547driver_cfa_cpp_LDFLAGS = -Xlinker -export-dynamic
    548548all: $(BUILT_SOURCES)
     
    560560          esac; \
    561561        done; \
    562         echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
     562        echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
    563563        $(am__cd) $(top_srcdir) && \
    564           $(AUTOMAKE) --foreign src/Makefile
     564          $(AUTOMAKE) --gnu src/Makefile
    565565Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    566566        @case '$?' in \
  • src/Parser/LinkageSpec.cc

    r3d4b23fa r55a68c3  
    1010// Created On       : Sat May 16 13:22:09 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul  7 11:11:00 2017
    13 // Update Count     : 25
     12// Last Modified On : Wed Jun 28 11:51:00 2017
     13// Update Count     : 24
    1414//
    1515
     
    2222#include "Common/SemanticError.h"
    2323
    24 namespace LinkageSpec {
    25 
    26 Spec linkageCheck( const string * spec ) {
    27         assert( spec );
     24LinkageSpec::Spec LinkageSpec::linkageCheck( const string * spec ) {
    2825        unique_ptr<const string> guard( spec ); // allocated by lexer
    2926        if ( *spec == "\"Cforall\"" ) {
     
    3835}
    3936
    40 Spec linkageUpdate( Spec old_spec, const string * cmd ) {
    41         assert( cmd );
    42         unique_ptr<const string> guard( cmd ); // allocated by lexer
    43         if ( *cmd == "\"Cforall\"" ) {
    44                 old_spec.is_mangled = true;
    45                 return old_spec;
    46         } else if ( *cmd == "\"C\"" ) {
    47                 old_spec.is_mangled = false;
    48                 return old_spec;
    49         } else {
    50                 throw SemanticError( "Invalid linkage specifier " + *cmd );
    51         } // if
     37string LinkageSpec::linkageName( LinkageSpec::Spec linkage ) {
     38        assert( 0 <= linkage && linkage < LinkageSpec::NoOfSpecs );
     39        static const char *linkageKinds[LinkageSpec::NoOfSpecs] = {
     40                "intrinsic", "Cforall", "C", "automatically generated", "compiler built-in", "cfa built-in", "c built-in",
     41        };
     42        return linkageKinds[linkage];
    5243}
    5344
    54 std::string linkageName( Spec linkage ) {
    55     switch ( linkage ) {
    56     case Intrinsic:
    57         return "intrinsic";
    58     case C:
    59         return "C";
    60     case Cforall:
    61         return "Cforall";
    62     case AutoGen:
    63         return "autogenerated cfa";
    64     case Compiler:
    65         return "compiler built-in";
    66     case BuiltinCFA:
    67         return "cfa built-in";
    68     case BuiltinC:
    69         return "c built-in";
    70     default:
    71         return "<unnamed linkage spec>";
    72     }
     45bool LinkageSpec::isMangled( Spec spec ) {
     46        assert( 0 <= spec && spec < LinkageSpec::NoOfSpecs );
     47        static bool decoratable[LinkageSpec::NoOfSpecs] = {
     48                //      Intrinsic,      Cforall,        C,              AutoGen,        Compiler,
     49                        true,           true,           false,  true,           false,
     50                //      Builtin,        BuiltinC,
     51                        true,           false,
     52        };
     53        return decoratable[spec];
    7354}
    7455
    75 } // LinkageSpec
     56bool LinkageSpec::isGeneratable( Spec spec ) {
     57        assert( 0 <= spec && spec < LinkageSpec::NoOfSpecs );
     58        static bool generatable[LinkageSpec::NoOfSpecs] = {
     59                //      Intrinsic,      Cforall,        C,              AutoGen,        Compiler,
     60                        true,           true,           true,   true,           false,
     61                //      Builtin,        BuiltinC,
     62                        true,           true,
     63        };
     64        return generatable[spec];
     65}
     66
     67bool LinkageSpec::isOverridable( Spec spec ) {
     68        assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs );
     69        static bool overridable[LinkageSpec::NoOfSpecs] = {
     70                //      Intrinsic,      Cforall,        C,              AutoGen,        Compiler,
     71                        true,           false,          false,  true,           false,
     72                //      Builtin,        BuiltinC,
     73                        false,          false,
     74        };
     75        return overridable[spec];
     76}
     77
     78bool LinkageSpec::isBuiltin( Spec spec ) {
     79        assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs );
     80        static bool builtin[LinkageSpec::NoOfSpecs] = {
     81                //      Intrinsic,      Cforall,        C,              AutoGen,        Compiler,
     82                        true,           false,          false,  false,          true,
     83                //      Builtin,        BuiltinC,
     84                        true,           true,
     85        };
     86        return builtin[spec];
     87}
    7688
    7789// Local Variables: //
  • src/Parser/LinkageSpec.h

    r3d4b23fa r55a68c3  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // LinkageSpec.h --
     7// LinkageSpec.h -- 
    88//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:24:28 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul  7 11:03:00 2017
    13 // Update Count     : 13
     12// Last Modified On : Wed Jun 28 11:50:00 2017
     13// Update Count     : 12
    1414//
    1515
     
    1919#include <string>
    2020
    21 namespace LinkageSpec {
    22         // All linkage specs are some combination of these flags:
    23         enum {
    24                 Mangle = 1 << 0,
    25                 Generate = 1 << 1,
    26                 Overrideable = 1 << 2,
    27                 Builtin = 1 << 3,
    28 
    29                 NoOfSpecs = 1 << 4,
     21struct LinkageSpec {
     22        enum Spec {
     23                Intrinsic,                                                                              // C built-in defined in prelude
     24                Cforall,                                                                                // ordinary
     25                C,                                                                                              // not overloadable, not mangled
     26                AutoGen,                                                                                // built by translator (struct assignment)
     27                Compiler,                                                                               // gcc internal
     28                Builtin,                                                                                // mangled builtins
     29                BuiltinC,                                                                               // non-mangled builtins
     30                NoOfSpecs
    3031        };
    31 
    32         union Spec {
    33                 unsigned int val;
    34                 struct {
    35                         bool is_mangled : 1;
    36                         bool is_generatable : 1;
    37                         bool is_overridable : 1;
    38                         bool is_builtin : 1;
    39                 };
    40                 constexpr Spec( unsigned int val ) : val( val ) {}
    41                 constexpr Spec( Spec const &other ) : val( other.val ) {}
    42                 // Operators may go here.
    43                 // Supports == and !=
    44                 constexpr operator unsigned int () const { return val; }
    45         };
    46 
    47 
    48         Spec linkageCheck( const std::string * );
    49         // Returns the Spec with the given name (limited to C, Cforall & BuiltinC)
    50         Spec linkageUpdate( Spec old_spec, const std::string * cmd );
    51         /* If cmd = "C" returns a Spec that is old_spec with is_mangled = false
    52          * If cmd = "Cforall" returns old_spec Spec with is_mangled = true
    53          */
    54 
    55         std::string linkageName( Spec );
    56 
    57         // To Update: LinkageSpec::isXyz( cur_spec ) -> cur_spec.is_xyz
    58         inline bool isMangled( Spec spec ) { return spec.is_mangled; }
    59         inline bool isGeneratable( Spec spec ) { return spec.is_generatable; }
    60         inline bool isOverridable( Spec spec ) { return spec.is_overridable; }
    61         inline bool isBuiltin( Spec spec ) { return spec.is_builtin; }
    62 
    63         // Pre-defined flag combinations:
    64         // C built-in defined in prelude
    65         constexpr Spec const Intrinsic = { Mangle | Generate | Overrideable | Builtin };
    66         // ordinary
    67         constexpr Spec const Cforall = { Mangle | Generate };
    68         // not overloadable, not mangled
    69         constexpr Spec const C = { Generate };
    70         // built by translator (struct assignment)
    71         constexpr Spec const AutoGen = { Mangle | Generate | Overrideable };
    72         // gcc internal
    73         constexpr Spec const Compiler = { Builtin };
    74         // mangled builtins
    75         constexpr Spec const BuiltinCFA = { Mangle | Generate | Builtin };
    76         // non-mangled builtins
    77         constexpr Spec const BuiltinC = { Generate | Builtin };
     32 
     33        static Spec linkageCheck( const std::string * );
     34        static std::string linkageName( Spec );
     35 
     36        static bool isMangled( Spec );
     37        static bool isGeneratable( Spec );
     38        static bool isOverridable( Spec );
     39        static bool isBuiltin( Spec );
    7840};
    7941
  • src/Parser/StatementNode.cc

    r3d4b23fa r55a68c3  
    1010// Created On       : Sat May 16 14:59:41 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 11 21:23:15 2017
    13 // Update Count     : 331
     12// Last Modified On : Wed Jun 28 21:08:37 2017
     13// Update Count     : 330
    1414//
    1515
     
    9393        std::list< Statement * > branches;
    9494        buildMoveList< Statement, StatementNode >( stmt, branches );
    95         // branches.size() == 0 for switch (...) {}, i.e., no declaration or statements
     95        assert( branches.size() >= 0 );                                         // size == 0 for switch (...) {}, i.e., no declaration or statements
    9696        return new SwitchStmt( noLabels, maybeMoveBuild< Expression >(ctl), branches );
    9797}
  • src/Parser/lex.ll

    r3d4b23fa r55a68c3  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Wed Jul 12 18:04:44 2017
    13  * Update Count     : 535
     12 * Last Modified On : Wed Jun 28 21:03:45 2017
     13 * Update Count     : 529
    1414 */
    1515
     
    5959}
    6060
    61 // Stop warning due to incorrectly generated flex code.
    62 #pragma GCC diagnostic ignored "-Wsign-compare"
    6361%}
    6462
     
    274272__volatile__    { KEYWORD_RETURN(VOLATILE); }                   // GCC
    275273while                   { KEYWORD_RETURN(WHILE); }
    276 with                    { KEYWORD_RETURN(WITH); }                               // CFA
    277274zero_t                  { NUMERIC_RETURN(ZERO_T); }                             // CFA
    278275
  • src/Parser/parser.yy

    r3d4b23fa r55a68c3  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep  1 20:22:55 2001
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 12 18:23:36 2017
    13 // Update Count     : 2426
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Jun 30 15:38:00 2017
     13// Update Count     : 2415
    1414//
    1515
     
    129129%token ATTRIBUTE EXTENSION                                                              // GCC
    130130%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
    131 %token CHOOSE DISABLE ENABLE FALLTHRU TRY CATCH CATCHRESUME FINALLY THROW THROWRESUME AT WITH   // CFA
     131%token CHOOSE DISABLE ENABLE FALLTHRU TRY CATCH CATCHRESUME FINALLY THROW THROWRESUME AT        // CFA
    132132%token ASM                                                                                              // C99, extension ISO/IEC 9899:1999 Section J.5.10(1)
    133133%token ALIGNAS ALIGNOF GENERIC STATICASSERT                             // C11
     
    184184// statements
    185185%type<sn> labeled_statement                             compound_statement                      expression_statement            selection_statement
    186 %type<sn> iteration_statement                   jump_statement
    187 %type<sn> with_statement                                exception_statement                     asm_statement
     186%type<sn> iteration_statement                   jump_statement                          exception_statement                     asm_statement
    188187%type<sn> fall_through_opt                              fall_through
    189188%type<sn> statement                                             statement_list
    190189%type<sn> block_item_list                               block_item
    191 %type<sn> with_clause_opt
     190%type<sn> case_clause
    192191%type<en> case_value
    193 %type<sn> case_clause                                   case_value_list                         case_label                                      case_label_list
     192%type<sn> case_value_list                               case_label                                      case_label_list
    194193%type<sn> switch_clause_list_opt                switch_clause_list                      choose_clause_list_opt          choose_clause_list
    195194%type<sn> /* handler_list */                    handler_clause                          finally_clause
     
    730729        | iteration_statement
    731730        | jump_statement
    732         | with_statement
    733731        | exception_statement
    734732        | asm_statement
     
    936934        | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume
    937935                { $$ = new StatementNode( build_resume_at( $2, $4 ) ); }
    938         ;
    939 
    940 with_statement:
    941         WITH identifier_list compound_statement
    942                 { $$ = (StatementNode *)0; }                                    // FIX ME
    943936        ;
    944937
     
    21832176                {
    21842177                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    2185                         linkage = LinkageSpec::linkageUpdate( linkage, $2 );
     2178                        linkage = LinkageSpec::linkageCheck( $2 );
    21862179                }
    21872180          '{' external_definition_list_opt '}'
     
    22192212        ;
    22202213
    2221 with_clause_opt:
    2222         // empty
    2223                 { $$ = (StatementNode *)0; }                                    // FIX ME
    2224         | WITH identifier_list
    2225                 { $$ = (StatementNode *)0; }                                    // FIX ME
    2226         ;
    2227 
    22282214function_definition:
    2229         cfa_function_declaration with_clause_opt compound_statement     // CFA
     2215        cfa_function_declaration compound_statement                     // CFA
    22302216                {
    22312217                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22322218                        typedefTable.leaveScope();
    2233                         $$ = $1->addFunctionBody( $3 );
    2234                 }
    2235         | declaration_specifier function_declarator with_clause_opt compound_statement
     2219                        $$ = $1->addFunctionBody( $2 );
     2220                }
     2221        | declaration_specifier function_declarator compound_statement
    22362222                {
    22372223                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22382224                        typedefTable.leaveScope();
    2239                         $$ = $2->addFunctionBody( $4 )->addType( $1 );
    2240                 }
    2241         | type_qualifier_list function_declarator with_clause_opt compound_statement
     2225                        $$ = $2->addFunctionBody( $3 )->addType( $1 );
     2226                }
     2227        | type_qualifier_list function_declarator compound_statement
    22422228                {
    22432229                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22442230                        typedefTable.leaveScope();
    2245                         $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 );
    2246                 }
    2247         | declaration_qualifier_list function_declarator with_clause_opt compound_statement
     2231                        $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
     2232                }
     2233        | declaration_qualifier_list function_declarator compound_statement
    22482234                {
    22492235                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22502236                        typedefTable.leaveScope();
    2251                         $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 );
    2252                 }
    2253         | declaration_qualifier_list type_qualifier_list function_declarator with_clause_opt compound_statement
     2237                        $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
     2238                }
     2239        | declaration_qualifier_list type_qualifier_list function_declarator compound_statement
    22542240                {
    22552241                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22562242                        typedefTable.leaveScope();
    2257                         $$ = $3->addFunctionBody( $5 )->addQualifiers( $2 )->addQualifiers( $1 );
     2243                        $$ = $3->addFunctionBody( $4 )->addQualifiers( $2 )->addQualifiers( $1 );
    22582244                }
    22592245
    22602246                // Old-style K&R function definition, OBSOLESCENT (see 4)
    2261         | declaration_specifier KR_function_declarator push KR_declaration_list_opt with_clause_opt compound_statement
     2247        | declaration_specifier KR_function_declarator push KR_declaration_list_opt compound_statement
    22622248                {
    22632249                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22642250                        typedefTable.leaveScope();
    2265                         $$ = $2->addOldDeclList( $4 )->addFunctionBody( $6 )->addType( $1 );
    2266                 }
    2267         | type_qualifier_list KR_function_declarator push KR_declaration_list_opt with_clause_opt compound_statement
     2251                        $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addType( $1 );
     2252                }
     2253        | type_qualifier_list KR_function_declarator push KR_declaration_list_opt compound_statement
    22682254                {
    22692255                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22702256                        typedefTable.leaveScope();
    2271                         $$ = $2->addOldDeclList( $4 )->addFunctionBody( $6 )->addQualifiers( $1 );
     2257                        $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
    22722258                }
    22732259
    22742260                // Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4)
    2275         | declaration_qualifier_list KR_function_declarator push KR_declaration_list_opt with_clause_opt compound_statement
     2261        | declaration_qualifier_list KR_function_declarator push KR_declaration_list_opt compound_statement
    22762262                {
    22772263                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22782264                        typedefTable.leaveScope();
    2279                         $$ = $2->addOldDeclList( $4 )->addFunctionBody( $6 )->addQualifiers( $1 );
    2280                 }
    2281         | declaration_qualifier_list type_qualifier_list KR_function_declarator push KR_declaration_list_opt with_clause_opt compound_statement
     2265                        $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
     2266                }
     2267        | declaration_qualifier_list type_qualifier_list KR_function_declarator push KR_declaration_list_opt compound_statement
    22822268                {
    22832269                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22842270                        typedefTable.leaveScope();
    2285                         $$ = $3->addOldDeclList( $5 )->addFunctionBody( $7 )->addQualifiers( $2 )->addQualifiers( $1 );
     2271                        $$ = $3->addOldDeclList( $5 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 );
    22862272                }
    22872273        ;
     
    23462332        | TYPEGENname
    23472333        | CONST
    2348                 { $$ = Token{ new string( "__const__" ), { nullptr, -1 } }; }
     2334                { $$ = Token{ new string( "__const__" ) }; }
    23492335        ;
    23502336
  • src/ResolvExpr/CurrentObject.cc

    r3d4b23fa r55a68c3  
    114114                }
    115115
    116                 virtual void print( std::ostream & out, __attribute__((unused)) Indenter indent ) const {
     116                virtual void print( std::ostream & out, Indenter indent ) const {
    117117                        out << "SimpleIterator(" << type << ")";
    118118                }
  • src/benchmark/CorCtxSwitch.c

    r3d4b23fa r55a68c3  
    3131
    3232        StartTime = Time();
     33        // for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) {
     34        //      resume( this_coroutine() );
     35        //      // resume( &s );       
     36        // }
    3337        resumer( &s, NoOfTimes );
    3438        EndTime = Time();
  • src/benchmark/Makefile.am

    r3d4b23fa r55a68c3  
    2020CC = @CFA_BINDIR@/@CFA_NAME@
    2121
    22 noinst_PROGRAMS = bench$(EXEEXT) ctxswitch-coroutine$(EXEEXT) ctxswitch-thread$(EXEEXT) sched-int$(EXEEXT) monitor$(EXEEXT) csv-data$(EXEEXT)
     22noinst_PROGRAMS = bench ctxswitch-coroutine ctxswitch-thread
    2323
    24 bench$(EXEEXT) :
     24bench :
    2525        @for ccflags in "-debug" "-nodebug"; do \
    2626                echo ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -lrt bench.c;\
     
    3030        rm -f ./a.out ;
    3131
    32 ctxswitch-coroutine$(EXEEXT):
     32ctxswitch-coroutine:
    3333        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 CorCtxSwitch.c
    3434        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    3737        @rm -f ./a.out
    3838
    39 ctxswitch-thread$(EXEEXT):
     39ctxswitch-thread:
    4040        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 ThrdCtxSwitch.c
    4141        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    4444        @rm -f ./a.out
    4545
    46 sched-int$(EXEEXT):
     46sched-int:
    4747        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c
    4848        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    5151        @rm -f ./a.out
    5252
    53 monitor$(EXEEXT):
     53monitor:
    5454        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c
    5555        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    5858        @rm -f ./a.out
    5959
    60 csv-data$(EXEEXT):
     60csv-data:
    6161        @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c
    6262        @./a.out
  • src/benchmark/Makefile.in

    r3d4b23fa r55a68c3  
    9292build_triplet = @build@
    9393host_triplet = @host@
     94noinst_PROGRAMS = bench$(EXEEXT) ctxswitch-coroutine$(EXEEXT) \
     95        ctxswitch-thread$(EXEEXT)
    9496subdir = src/benchmark
    9597ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
     
    106108bench_OBJECTS = bench.$(OBJEXT)
    107109bench_LDADD = $(LDADD)
    108 csv_data_SOURCES = csv-data.c
    109 csv_data_OBJECTS = csv-data.$(OBJEXT)
    110 csv_data_LDADD = $(LDADD)
    111110ctxswitch_coroutine_SOURCES = ctxswitch-coroutine.c
    112111ctxswitch_coroutine_OBJECTS = ctxswitch-coroutine.$(OBJEXT)
     
    115114ctxswitch_thread_OBJECTS = ctxswitch-thread.$(OBJEXT)
    116115ctxswitch_thread_LDADD = $(LDADD)
    117 monitor_SOURCES = monitor.c
    118 monitor_OBJECTS = monitor.$(OBJEXT)
    119 monitor_LDADD = $(LDADD)
    120 sched_int_SOURCES = sched-int.c
    121 sched_int_OBJECTS = sched-int.$(OBJEXT)
    122 sched_int_LDADD = $(LDADD)
    123116AM_V_P = $(am__v_P_@AM_V@)
    124117am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
     
    149142am__v_CCLD_0 = @echo "  CCLD    " $@;
    150143am__v_CCLD_1 =
    151 SOURCES = bench.c csv-data.c ctxswitch-coroutine.c ctxswitch-thread.c \
    152         monitor.c sched-int.c
    153 DIST_SOURCES = bench.c csv-data.c ctxswitch-coroutine.c \
    154         ctxswitch-thread.c monitor.c sched-int.c
     144SOURCES = bench.c ctxswitch-coroutine.c ctxswitch-thread.c
     145DIST_SOURCES = bench.c ctxswitch-coroutine.c ctxswitch-thread.c
    155146am__can_run_installinfo = \
    156147  case $$AM_UPDATE_INFO_DIR in \
     
    302293top_srcdir = @top_srcdir@
    303294AM_CFLAGS = -g -Wall -Wno-unused-function -O2
    304 noinst_PROGRAMS = bench$(EXEEXT) ctxswitch-coroutine$(EXEEXT) ctxswitch-thread$(EXEEXT) sched-int$(EXEEXT) monitor$(EXEEXT) csv-data$(EXEEXT)
    305295all: all-am
    306296
     
    316306          esac; \
    317307        done; \
    318         echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/benchmark/Makefile'; \
     308        echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/benchmark/Makefile'; \
    319309        $(am__cd) $(top_srcdir) && \
    320           $(AUTOMAKE) --foreign src/benchmark/Makefile
     310          $(AUTOMAKE) --gnu src/benchmark/Makefile
    321311Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    322312        @case '$?' in \
     
    347337
    348338@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bench.Po@am__quote@
    349 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csv-data.Po@am__quote@
    350339@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctxswitch-coroutine.Po@am__quote@
    351340@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctxswitch-thread.Po@am__quote@
    352 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor.Po@am__quote@
    353 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sched-int.Po@am__quote@
    354341
    355342.c.o:
     
    572559
    573560
    574 bench$(EXEEXT) :
     561bench :
    575562        @for ccflags in "-debug" "-nodebug"; do \
    576563                echo ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -lrt bench.c;\
     
    580567        rm -f ./a.out ;
    581568
    582 ctxswitch-coroutine$(EXEEXT):
     569ctxswitch-coroutine:
    583570        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 CorCtxSwitch.c
    584571        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    587574        @rm -f ./a.out
    588575
    589 ctxswitch-thread$(EXEEXT):
     576ctxswitch-thread:
    590577        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 ThrdCtxSwitch.c
    591578        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    594581        @rm -f ./a.out
    595582
    596 sched-int$(EXEEXT):
     583sched-int:
    597584        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c
    598585        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    601588        @rm -f ./a.out
    602589
    603 monitor$(EXEEXT):
     590monitor:
    604591        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c
    605592        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    608595        @rm -f ./a.out
    609596
    610 csv-data$(EXEEXT):
     597csv-data:
    611598        @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c
    612599        @./a.out
  • src/benchmark/bench.h

    r3d4b23fa r55a68c3  
    2626#define N 10000000
    2727#endif
    28 
    29 unsigned int default_preemption() {
    30         return 0;
    31 }
  • src/benchmark/create_pthrd.c

    r3d4b23fa r55a68c3  
    1717
    1818        for (size_t i = 0; i < n; i++) {
    19                 pthread_t thread;
    20                 if (pthread_create(&thread, NULL, foo, NULL) < 0) {
     19                pthread_attr_t attr;
     20                if (pthread_attr_init(&attr) < 0) {
    2121                        return 1;
    2222                }
    23 
    24                 if (pthread_join( thread, NULL) < 0) {
     23                if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) < 0) {
     24                        return 1;
     25                }
     26                pthread_t thread;
     27                if (pthread_create(&thread, &attr, foo, NULL) < 0) {
    2528                        return 1;
    2629                }
  • src/benchmark/csv-data.c

    r3d4b23fa r55a68c3  
    2525}
    2626
     27#ifndef N
     28#define N 100000000
     29#endif
     30
    2731//-----------------------------------------------------------------------------
    2832// coroutine context switch
     
    3438
    3539        StartTime = Time();
     40        // for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) {
     41        //      resume( this_coroutine() );
     42        //      // resume( &s );
     43        // }
    3644        resumer( &s, NoOfTimes );
    3745        EndTime = Time();
     
    96104mon_t mon1;
    97105
    98 condition cond1a;
     106condition cond1a; 
    99107condition cond1b;
    100108
     
    144152mon_t mon2;
    145153
    146 condition cond2a;
     154condition cond2a; 
    147155condition cond2b;
    148156
  • src/driver/Makefile.in

    r3d4b23fa r55a68c3  
    315315          esac; \
    316316        done; \
    317         echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/driver/Makefile'; \
     317        echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/driver/Makefile'; \
    318318        $(am__cd) $(top_srcdir) && \
    319           $(AUTOMAKE) --foreign src/driver/Makefile
     319          $(AUTOMAKE) --gnu src/driver/Makefile
    320320Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    321321        @case '$?' in \
  • src/examples/Makefile.in

    r3d4b23fa r55a68c3  
    319319          esac; \
    320320        done; \
    321         echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/examples/Makefile'; \
     321        echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/examples/Makefile'; \
    322322        $(am__cd) $(top_srcdir) && \
    323           $(AUTOMAKE) --foreign src/examples/Makefile
     323          $(AUTOMAKE) --gnu src/examples/Makefile
    324324Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    325325        @case '$?' in \
  • src/include/assert.h

    r3d4b23fa r55a68c3  
    1515
    1616#pragma once
    17 // Pragmas for header cleanup tool
    18 // IWYU pragma: private, include <cassert>
    1917
    2018#include_next <assert.h>
  • src/libcfa/Makefile.am

    r3d4b23fa r55a68c3  
    1717# create object files in directory with source files
    1818AUTOMAKE_OPTIONS = subdir-objects
    19 ARFLAGS = cr
    2019
    2120libdir = ${CFA_LIBDIR}
  • src/libcfa/Makefile.in

    r3d4b23fa r55a68c3  
    142142LIBRARIES = $(lib_LIBRARIES)
    143143AR = ar
     144ARFLAGS = cru
    144145AM_V_AR = $(am__v_AR_@AM_V@)
    145146am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
     
    408409# create object files in directory with source files
    409410AUTOMAKE_OPTIONS = subdir-objects
    410 ARFLAGS = cr
    411411lib_LIBRARIES = $(am__append_1) $(am__append_2)
    412412EXTRA_FLAGS = -g -Wall -Werror -Wno-unused-function -I${abs_top_srcdir}/src/libcfa/libhdr -imacros libcfa-prelude.c @CFA_FLAGS@
     
    439439          esac; \
    440440        done; \
    441         echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/libcfa/Makefile'; \
     441        echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcfa/Makefile'; \
    442442        $(am__cd) $(top_srcdir) && \
    443           $(AUTOMAKE) --foreign src/libcfa/Makefile
     443          $(AUTOMAKE) --gnu src/libcfa/Makefile
    444444Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    445445        @case '$?' in \
  • src/libcfa/concurrency/CtxSwitch-i386.S

    r3d4b23fa r55a68c3  
    9898        ret
    9999
     100.text
     101        .align 2
     102.globl  CtxGet
     103CtxGet:
     104        movl %esp,SP_OFFSET(%eax)
     105        movl %ebp,FP_OFFSET(%eax)
     106
     107        ret
     108
    100109// Local Variables: //
    101110// compile-command: "make install" //
  • src/libcfa/concurrency/CtxSwitch-x86_64.S

    r3d4b23fa r55a68c3  
    1 //                               -*- Mode: Asm -*-
     1//                               -*- Mode: Asm -*- 
    22//
    33// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     
    1818// Free Software  Foundation; either  version 2.1 of  the License, or  (at your
    1919// option) any later version.
    20 //
     20// 
    2121// This library is distributed in the  hope that it will be useful, but WITHOUT
    2222// ANY  WARRANTY;  without even  the  implied  warranty  of MERCHANTABILITY  or
    2323// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
    2424// for more details.
    25 //
     25// 
    2626// You should  have received a  copy of the  GNU Lesser General  Public License
    2727// along  with this library.
    28 //
     28// 
    2929
    3030// This context switch routine depends on the fact that the stack of a new
     
    9393.globl  CtxInvokeStub
    9494CtxInvokeStub:
    95         movq %rbx, %rdi
     95        movq %rbx, %rdi 
    9696        jmp *%r12
     97
     98.text
     99        .align 2
     100.globl  CtxGet
     101CtxGet:
     102        movq %rsp,SP_OFFSET(%rdi)
     103        movq %rbp,FP_OFFSET(%rdi)
     104
     105        ret
    97106
    98107// Local Variables: //
  • src/libcfa/concurrency/alarm.c

    r3d4b23fa r55a68c3  
    1616
    1717extern "C" {
    18 #include <errno.h>
    19 #include <stdio.h>
    20 #include <string.h>
    2118#include <time.h>
    22 #include <unistd.h>
    2319#include <sys/time.h>
    2420}
    25 
    26 #include "libhdr.h"
    2721
    2822#include "alarm.h"
     
    3731        timespec curr;
    3832        clock_gettime( CLOCK_REALTIME, &curr );
    39         __cfa_time_t curr_time = ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;
    40         // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : current time is %lu\n", curr_time );
    41         return curr_time;
     33        return ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;
    4234}
    4335
    4436void __kernel_set_timer( __cfa_time_t alarm ) {
    45         LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : set timer to %lu\n", (__cfa_time_t)alarm );
    4637        itimerval val;
    4738        val.it_value.tv_sec = alarm / TIMEGRAN;                 // seconds
     
    8071}
    8172
    82 LIB_DEBUG_DO( bool validate( alarm_list_t * this ) {
    83         alarm_node_t ** it = &this->head;
    84         while( (*it) ) {
    85                 it = &(*it)->next;
    86         }
    87 
    88         return it == this->tail;
    89 })
    90 
    9173static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) {
    92         verify( !n->next );
     74        assert( !n->next );
    9375        if( p == this->tail ) {
    9476                this->tail = &n->next;
     
    9880        }
    9981        *p = n;
    100 
    101         verify( validate( this ) );
    10282}
    10383
     
    10989
    11090        insert_at( this, n, it );
    111 
    112         verify( validate( this ) );
    11391}
    11492
     
    122100                head->next = NULL;
    123101        }
    124         verify( validate( this ) );
    125102        return head;
    126103}
     
    128105static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
    129106        verify( it );
    130         verify( (*it) == n );
     107        verify( (*it)->next == n );
    131108
    132         (*it) = n->next;
     109        (*it)->next = n->next;
    133110        if( !n-> next ) {
    134111                this->tail = it;
    135112        }
    136113        n->next = NULL;
    137 
    138         verify( validate( this ) );
    139114}
    140115
    141116static inline void remove( alarm_list_t * this, alarm_node_t * n ) {
    142117        alarm_node_t ** it = &this->head;
    143         while( (*it) && (*it) != n ) {
     118        while( (*it) && (*it)->next != n ) {
    144119                it = &(*it)->next;
    145120        }
    146121
    147         verify( validate( this ) );
    148 
    149122        if( *it ) { remove_at( this, n, it ); }
    150 
    151         verify( validate( this ) );
    152123}
    153124
    154125void register_self( alarm_node_t * this ) {
    155126        disable_interrupts();
    156         verify( !systemProcessor->pending_alarm );
    157         lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
     127        assert( !systemProcessor->pending_alarm );
     128        lock( &systemProcessor->alarm_lock );
    158129        {
    159                 verify( validate( &systemProcessor->alarms ) );
    160                 bool first = !systemProcessor->alarms.head;
    161 
    162130                insert( &systemProcessor->alarms, this );
    163131                if( systemProcessor->pending_alarm ) {
    164132                        tick_preemption();
    165133                }
    166                 if( first ) {
    167                         __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() );
    168                 }
    169134        }
    170135        unlock( &systemProcessor->alarm_lock );
    171136        this->set = true;
    172         enable_interrupts( DEBUG_CTX );
     137        enable_interrupts();
    173138}
    174139
    175140void unregister_self( alarm_node_t * this ) {
    176         // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : unregister %p start\n", this );
    177141        disable_interrupts();
    178         lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
    179         {
    180                 verify( validate( &systemProcessor->alarms ) );
    181                 remove( &systemProcessor->alarms, this );
    182         }
     142        lock( &systemProcessor->alarm_lock );
     143        remove( &systemProcessor->alarms, this );
    183144        unlock( &systemProcessor->alarm_lock );
    184         enable_interrupts( DEBUG_CTX );
     145        disable_interrupts();
    185146        this->set = false;
    186         // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Kernel : unregister %p end\n", this );
    187147}
  • src/libcfa/concurrency/coroutine

    r3d4b23fa r55a68c3  
    6363
    6464// Get current coroutine
    65 extern volatile thread_local coroutine_desc * this_coroutine;
     65coroutine_desc * this_coroutine(void);
    6666
    6767// Private wrappers for context switch and stack creation
     
    7171// Suspend implementation inlined for performance
    7272static inline void suspend() {
    73         coroutine_desc * src = this_coroutine;          // optimization
     73        coroutine_desc * src = this_coroutine();                // optimization
    7474
    7575        assertf( src->last != 0,
     
    8888forall(dtype T | is_coroutine(T))
    8989static inline void resume(T * cor) {
    90         coroutine_desc * src = this_coroutine;          // optimization
     90        coroutine_desc * src = this_coroutine();                // optimization
    9191        coroutine_desc * dst = get_coroutine(cor);
    9292
     
    112112
    113113static inline void resume(coroutine_desc * dst) {
    114         coroutine_desc * src = this_coroutine;          // optimization
     114        coroutine_desc * src = this_coroutine();                // optimization
    115115
    116116        // not resuming self ?
  • src/libcfa/concurrency/coroutine.c

    r3d4b23fa r55a68c3  
    3232#include "invoke.h"
    3333
    34 extern volatile thread_local processor * this_processor;
     34extern thread_local processor * this_processor;
    3535
    3636//-----------------------------------------------------------------------------
     
    4444// Coroutine ctors and dtors
    4545void ?{}(coStack_t* this) {
    46         this->size              = 65000;        // size of stack
     46        this->size              = 10240;        // size of stack
    4747        this->storage   = NULL; // pointer to stack
    4848        this->limit             = NULL; // stack grows towards stack limit
     
    5050        this->context   = NULL; // address of cfa_context_t
    5151        this->top               = NULL; // address of top of storage
    52         this->userStack = false;
     52        this->userStack = false;       
    5353}
    5454
     
    106106
    107107        // set state of current coroutine to inactive
    108         src->state = src->state == Halted ? Halted : Inactive;
     108        src->state = Inactive;
    109109
    110110        // set new coroutine that task is executing
    111         this_coroutine = dst;
     111        this_processor->current_coroutine = dst;
    112112
    113113        // context switch to specified coroutine
    114         assert( src->stack.context );
    115114        CtxSwitch( src->stack.context, dst->stack.context );
    116         // when CtxSwitch returns we are back in the src coroutine
     115        // when CtxSwitch returns we are back in the src coroutine             
    117116
    118117        // set state of new coroutine to active
     
    132131                this->size = libCeiling( storageSize, 16 );
    133132                // use malloc/memalign because "new" raises an exception for out-of-memory
    134 
     133               
    135134                // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment
    136135                LIB_DEBUG_DO( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) );
  • src/libcfa/concurrency/invoke.c

    r3d4b23fa r55a68c3  
    2929
    3030extern void __suspend_internal(void);
    31 extern void __leave_thread_monitor( struct thread_desc * this );
    32 extern void disable_interrupts();
    33 extern void enable_interrupts( DEBUG_CTX_PARAM );
     31extern void __leave_monitor_desc( struct monitor_desc * this );
    3432
    3533void CtxInvokeCoroutine(
    36       void (*main)(void *),
    37       struct coroutine_desc *(*get_coroutine)(void *),
     34      void (*main)(void *), 
     35      struct coroutine_desc *(*get_coroutine)(void *), 
    3836      void *this
    3937) {
     
    5856
    5957void CtxInvokeThread(
    60       void (*dtor)(void *),
    61       void (*main)(void *),
    62       struct thread_desc *(*get_thread)(void *),
     58      void (*dtor)(void *), 
     59      void (*main)(void *), 
     60      struct thread_desc *(*get_thread)(void *), 
    6361      void *this
    6462) {
    65       // First suspend, once the thread arrives here,
    66       // the function pointer to main can be invalidated without risk
    6763      __suspend_internal();
    6864
    69       // Fetch the thread handle from the user defined thread structure
    7065      struct thread_desc* thrd = get_thread( this );
     66      struct coroutine_desc* cor = &thrd->cor;
     67      struct monitor_desc* mon = &thrd->mon;
     68      cor->state = Active;
    7169
    72       // Officially start the thread by enabling preemption
    73       enable_interrupts( DEBUG_CTX );
    74 
    75       // Call the main of the thread
     70      // LIB_DEBUG_PRINTF("Invoke Thread : invoking main %p (args %p)\n", main, this);
    7671      main( this );
    7772
    78       // To exit a thread we must :
    79       // 1 - Mark it as halted
    80       // 2 - Leave its monitor
    81       // 3 - Disable the interupts
    82       // 4 - Final suspend
    83       // The order of these 4 operations is very important
     73      __leave_monitor_desc( mon );
     74
    8475      //Final suspend, should never return
    85       __leave_thread_monitor( thrd );
     76      __suspend_internal();
    8677      abortf("Resumed dead thread");
    8778}
     
    8980
    9081void CtxStart(
    91       void (*main)(void *),
    92       struct coroutine_desc *(*get_coroutine)(void *),
    93       void *this,
     82      void (*main)(void *), 
     83      struct coroutine_desc *(*get_coroutine)(void *), 
     84      void *this, 
    9485      void (*invoke)(void *)
    9586) {
     
    117108        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke;
    118109      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
    119       ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
     110      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7 
    120111
    121112#elif defined( __x86_64__ )
     
    137128      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke;
    138129      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
    139       ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
     130      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7 
    140131#else
    141132      #error Only __i386__ and __x86_64__ is supported for threads in cfa
  • src/libcfa/concurrency/invoke.h

    r3d4b23fa r55a68c3  
    3131      struct spinlock {
    3232            volatile int lock;
    33             #ifdef __CFA_DEBUG__
    34                   const char * prev_name;
    35                   void* prev_thrd;
    36             #endif
    3733      };
    3834
     
    8783            struct __thread_queue_t entry_queue;      // queue of threads that are blocked waiting for the monitor
    8884            struct __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
     85            struct monitor_desc * stack_owner;        // if bulk acquiring was used we need to synchronize signals with an other monitor
    8986            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
    9087      };
     
    10299#ifndef _INVOKE_PRIVATE_H_
    103100#define _INVOKE_PRIVATE_H_
    104 
     101     
    105102      struct machine_context_t {
    106103            void *SP;
     
    112109      extern void CtxInvokeStub( void );
    113110      void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
    114 
    115       #if   defined( __x86_64__ )
    116       #define CtxGet( ctx ) __asm__ ( \
    117                   "movq %%rsp,%0\n"   \
    118                   "movq %%rbp,%1\n"   \
    119             : "=rm" (ctx.SP), "=rm" (ctx.FP) )
    120       #elif defined( __i386__ )
    121       #define CtxGet( ctx ) __asm__ ( \
    122                   "movl %%esp,%0\n"   \
    123                   "movl %%ebp,%1\n"   \
    124             : "=rm" (ctx.SP), "=rm" (ctx.FP) )
    125       #endif
     111      void CtxGet( void * this ) asm ("CtxGet");
    126112
    127113#endif //_INVOKE_PRIVATE_H_
  • src/libcfa/concurrency/kernel

    r3d4b23fa r55a68c3  
    2828//-----------------------------------------------------------------------------
    2929// Locks
    30 bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );
    31 void lock      ( spinlock * DEBUG_CTX_PARAM2 );
    32 void lock_yield( spinlock * DEBUG_CTX_PARAM2 );
    33 void unlock    ( spinlock * );
     30bool try_lock( spinlock * );
     31void lock( spinlock * );
     32void unlock( spinlock * );
    3433
    35 struct semaphore {
    36         spinlock lock;
    37         int count;
    38         __thread_queue_t waiting;
     34struct signal_once {
     35        volatile bool cond;
     36        struct spinlock lock;
     37        struct __thread_queue_t blocked;
    3938};
    4039
    41 void  ?{}(semaphore * this, int count = 1);
    42 void ^?{}(semaphore * this);
    43 void P(semaphore * this);
    44 void V(semaphore * this);
     40void ?{}(signal_once * this);
     41void ^?{}(signal_once * this);
    4542
     43void wait( signal_once * );
     44void signal( signal_once * );
    4645
    4746//-----------------------------------------------------------------------------
     
    6968        unsigned short thrd_count;
    7069};
    71 static inline void ?{}(FinishAction * this) {
     70static inline void ?{}(FinishAction * this) { 
    7271        this->action_code = No_Action;
    7372        this->thrd = NULL;
     
    7978        struct processorCtx_t * runner;
    8079        cluster * cltr;
     80        coroutine_desc * current_coroutine;
     81        thread_desc * current_thread;
    8182        pthread_t kernel_thread;
    82 
    83         semaphore terminated;
     83       
     84        signal_once terminated;
    8485        volatile bool is_terminated;
    8586
     
    8990        unsigned int preemption;
    9091
     92        unsigned short disable_preempt_count;
     93
    9194        bool pending_preemption;
    92 
    93         char * last_enable;
    9495};
    9596
  • src/libcfa/concurrency/kernel.c

    r3d4b23fa r55a68c3  
    1515//
    1616
    17 #include "libhdr.h"
     17#include "startup.h"
     18
     19//Start and stop routine for the kernel, declared first to make sure they run first
     20void kernel_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
     21void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
     22
     23//Header
     24#include "kernel_private.h"
    1825
    1926//C Includes
     
    2835
    2936//CFA Includes
    30 #include "kernel_private.h"
     37#include "libhdr.h"
    3138#include "preemption.h"
    32 #include "startup.h"
    3339
    3440//Private includes
     
    3642#include "invoke.h"
    3743
    38 //Start and stop routine for the kernel, declared first to make sure they run first
    39 void kernel_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
    40 void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
    41 
    4244//-----------------------------------------------------------------------------
    4345// Kernel storage
    44 #define KERNEL_STORAGE(T,X) static char X##Storage[sizeof(T)]
     46#define KERNEL_STORAGE(T,X) static char X##_storage[sizeof(T)]
    4547
    4648KERNEL_STORAGE(processorCtx_t, systemProcessorCtx);
     
    4850KERNEL_STORAGE(system_proc_t, systemProcessor);
    4951KERNEL_STORAGE(thread_desc, mainThread);
    50 KERNEL_STORAGE(machine_context_t, mainThreadCtx);
     52KERNEL_STORAGE(machine_context_t, mainThread_context);
    5153
    5254cluster * systemCluster;
     
    5759// Global state
    5860
    59 volatile thread_local processor * this_processor;
    60 volatile thread_local coroutine_desc * this_coroutine;
    61 volatile thread_local thread_desc * this_thread;
    62 volatile thread_local bool preemption_in_progress = 0;
    63 volatile thread_local unsigned short disable_preempt_count = 1;
     61thread_local processor * this_processor;
     62
     63coroutine_desc * this_coroutine(void) {
     64        return this_processor->current_coroutine;
     65}
     66
     67thread_desc * this_thread(void) {
     68        return this_processor->current_thread;
     69}
    6470
    6571//-----------------------------------------------------------------------------
    6672// Main thread construction
    6773struct current_stack_info_t {
    68         machine_context_t ctx;
     74        machine_context_t ctx; 
    6975        unsigned int size;              // size of stack
    7076        void *base;                             // base of stack
     
    7682
    7783void ?{}( current_stack_info_t * this ) {
    78         CtxGet( this->ctx );
     84        CtxGet( &this->ctx );
    7985        this->base = this->ctx.FP;
    8086        this->storage = this->ctx.SP;
     
    8591
    8692        this->limit = (void *)(((intptr_t)this->base) - this->size);
    87         this->context = &mainThreadCtxStorage;
     93        this->context = &mainThread_context_storage;
    8894        this->top = this->base;
    8995}
     
    100106
    101107void ?{}( coroutine_desc * this, current_stack_info_t * info) {
    102         (&this->stack){ info };
     108        (&this->stack){ info }; 
    103109        this->name = "Main Thread";
    104110        this->errno_ = 0;
     
    130136void ?{}(processor * this, cluster * cltr) {
    131137        this->cltr = cltr;
    132         (&this->terminated){ 0 };
     138        this->current_coroutine = NULL;
     139        this->current_thread = NULL;
     140        (&this->terminated){};
    133141        this->is_terminated = false;
    134142        this->preemption_alarm = NULL;
    135143        this->preemption = default_preemption();
     144        this->disable_preempt_count = 1;                //Start with interrupts disabled
    136145        this->pending_preemption = false;
    137146
     
    141150void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) {
    142151        this->cltr = cltr;
    143         (&this->terminated){ 0 };
     152        this->current_coroutine = NULL;
     153        this->current_thread = NULL;
     154        (&this->terminated){};
    144155        this->is_terminated = false;
    145         this->preemption_alarm = NULL;
    146         this->preemption = default_preemption();
     156        this->disable_preempt_count = 0;
    147157        this->pending_preemption = false;
    148         this->kernel_thread = pthread_self();
    149158
    150159        this->runner = runner;
    151         LIB_DEBUG_PRINT_SAFE("Kernel : constructing system processor context %p\n", runner);
     160        LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner);
    152161        runner{ this };
    153162}
    154 
    155 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )
    156163
    157164void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) {
     
    161168
    162169        (&this->proc){ cltr, runner };
    163 
    164         verify( validate( &this->alarms ) );
    165170}
    166171
     
    169174                LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this);
    170175                this->is_terminated = true;
    171                 P( &this->terminated );
    172                 pthread_join( this->kernel_thread, NULL );
     176                wait( &this->terminated );
    173177        }
    174178}
     
    180184
    181185void ^?{}(cluster * this) {
    182 
     186       
    183187}
    184188
     
    199203
    200204                thread_desc * readyThread = NULL;
    201                 for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ )
     205                for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ ) 
    202206                {
    203207                        readyThread = nextThread( this->cltr );
     
    205209                        if(readyThread)
    206210                        {
    207                                 verify( disable_preempt_count > 0 );
    208 
    209211                                runThread(this, readyThread);
    210 
    211                                 verify( disable_preempt_count > 0 );
    212212
    213213                                //Some actions need to be taken from the kernel
     
    225225        }
    226226
    227         V( &this->terminated );
    228 
     227        signal( &this->terminated );
    229228        LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this);
    230229}
    231230
    232 // runThread runs a thread by context switching
    233 // from the processor coroutine to the target thread
     231// runThread runs a thread by context switching 
     232// from the processor coroutine to the target thread 
    234233void runThread(processor * this, thread_desc * dst) {
    235234        coroutine_desc * proc_cor = get_coroutine(this->runner);
    236235        coroutine_desc * thrd_cor = get_coroutine(dst);
    237 
     236       
    238237        //Reset the terminating actions here
    239238        this->finish.action_code = No_Action;
    240239
    241240        //Update global state
    242         this_thread = dst;
     241        this->current_thread = dst;
    243242
    244243        // Context Switch to the thread
     
    247246}
    248247
    249 // Once a thread has finished running, some of
     248// Once a thread has finished running, some of 
    250249// its final actions must be executed from the kernel
    251250void finishRunning(processor * this) {
     
    257256        }
    258257        else if( this->finish.action_code == Release_Schedule ) {
    259                 unlock( this->finish.lock );
     258                unlock( this->finish.lock );           
    260259                ScheduleThread( this->finish.thrd );
    261260        }
     
    290289        processor * proc = (processor *) arg;
    291290        this_processor = proc;
    292         this_coroutine = NULL;
    293         this_thread = NULL;
    294         disable_preempt_count = 1;
    295291        // SKULLDUGGERY: We want to create a context for the processor coroutine
    296292        // which is needed for the 2-step context switch. However, there is no reason
    297         // to waste the perfectly valid stack create by pthread.
     293        // to waste the perfectly valid stack create by pthread. 
    298294        current_stack_info_t info;
    299295        machine_context_t ctx;
     
    304300
    305301        //Set global state
    306         this_coroutine = &proc->runner->__cor;
    307         this_thread = NULL;
     302        proc->current_coroutine = &proc->runner->__cor;
     303        proc->current_thread = NULL;
    308304
    309305        //We now have a proper context from which to schedule threads
    310306        LIB_DEBUG_PRINT_SAFE("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx);
    311307
    312         // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't
    313         // resume it to start it like it normally would, it will just context switch
    314         // back to here. Instead directly call the main since we already are on the
     308        // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't 
     309        // resume it to start it like it normally would, it will just context switch 
     310        // back to here. Instead directly call the main since we already are on the 
    315311        // appropriate stack.
    316312        proc_cor_storage.__cor.state = Active;
     
    319315
    320316        // Main routine of the core returned, the core is now fully terminated
    321         LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner);
     317        LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner); 
    322318
    323319        return NULL;
     
    326322void start(processor * this) {
    327323        LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this);
    328 
     324       
    329325        pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );
    330326
    331         LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);
     327        LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);       
    332328}
    333329
     
    335331// Scheduler routines
    336332void ScheduleThread( thread_desc * thrd ) {
    337         // if( !thrd ) return;
    338         assert( thrd );
    339         assert( thrd->cor.state != Halted );
    340 
    341         verify( disable_preempt_count > 0 );
     333        if( !thrd ) return;
    342334
    343335        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    344 
    345         lock( &systemProcessor->proc.cltr->lock DEBUG_CTX2 );
     336       
     337        lock( &systemProcessor->proc.cltr->lock );
    346338        append( &systemProcessor->proc.cltr->ready_queue, thrd );
    347339        unlock( &systemProcessor->proc.cltr->lock );
    348 
    349         verify( disable_preempt_count > 0 );
    350340}
    351341
    352342thread_desc * nextThread(cluster * this) {
    353         verify( disable_preempt_count > 0 );
    354         lock( &this->lock DEBUG_CTX2 );
     343        lock( &this->lock );
    355344        thread_desc * head = pop_head( &this->ready_queue );
    356345        unlock( &this->lock );
    357         verify( disable_preempt_count > 0 );
    358346        return head;
    359347}
    360348
    361 void BlockInternal() {
    362         disable_interrupts();
    363         verify( disable_preempt_count > 0 );
     349void ScheduleInternal() {
    364350        suspend();
    365         verify( disable_preempt_count > 0 );
    366         enable_interrupts( DEBUG_CTX );
    367 }
    368 
    369 void BlockInternal( spinlock * lock ) {
    370         disable_interrupts();
     351}
     352
     353void ScheduleInternal( spinlock * lock ) {
    371354        this_processor->finish.action_code = Release;
    372355        this_processor->finish.lock = lock;
    373 
    374         verify( disable_preempt_count > 0 );
    375356        suspend();
    376         verify( disable_preempt_count > 0 );
    377 
    378         enable_interrupts( DEBUG_CTX );
    379 }
    380 
    381 void BlockInternal( thread_desc * thrd ) {
    382         disable_interrupts();
    383         assert( thrd->cor.state != Halted );
     357}
     358
     359void ScheduleInternal( thread_desc * thrd ) {
    384360        this_processor->finish.action_code = Schedule;
    385361        this_processor->finish.thrd = thrd;
    386 
    387         verify( disable_preempt_count > 0 );
    388362        suspend();
    389         verify( disable_preempt_count > 0 );
    390 
    391         enable_interrupts( DEBUG_CTX );
    392 }
    393 
    394 void BlockInternal( spinlock * lock, thread_desc * thrd ) {
    395         disable_interrupts();
     363}
     364
     365void ScheduleInternal( spinlock * lock, thread_desc * thrd ) {
    396366        this_processor->finish.action_code = Release_Schedule;
    397367        this_processor->finish.lock = lock;
    398368        this_processor->finish.thrd = thrd;
    399 
    400         verify( disable_preempt_count > 0 );
    401369        suspend();
    402         verify( disable_preempt_count > 0 );
    403 
    404         enable_interrupts( DEBUG_CTX );
    405 }
    406 
    407 void BlockInternal(spinlock ** locks, unsigned short count) {
    408         disable_interrupts();
     370}
     371
     372void ScheduleInternal(spinlock ** locks, unsigned short count) {
    409373        this_processor->finish.action_code = Release_Multi;
    410374        this_processor->finish.locks = locks;
    411375        this_processor->finish.lock_count = count;
    412 
    413         verify( disable_preempt_count > 0 );
    414376        suspend();
    415         verify( disable_preempt_count > 0 );
    416 
    417         enable_interrupts( DEBUG_CTX );
    418 }
    419 
    420 void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
    421         disable_interrupts();
     377}
     378
     379void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
    422380        this_processor->finish.action_code = Release_Multi_Schedule;
    423381        this_processor->finish.locks = locks;
     
    425383        this_processor->finish.thrds = thrds;
    426384        this_processor->finish.thrd_count = thrd_count;
    427 
    428         verify( disable_preempt_count > 0 );
    429         suspend();
    430         verify( disable_preempt_count > 0 );
    431 
    432         enable_interrupts( DEBUG_CTX );
    433 }
    434 
    435 void LeaveThread(spinlock * lock, thread_desc * thrd) {
    436         verify( disable_preempt_count > 0 );
    437         this_processor->finish.action_code = thrd ? Release_Schedule : Release;
    438         this_processor->finish.lock = lock;
    439         this_processor->finish.thrd = thrd;
    440 
    441385        suspend();
    442386}
     
    448392// Kernel boot procedures
    449393void kernel_startup(void) {
    450         LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n");
     394        LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n");   
    451395
    452396        // Start by initializing the main thread
    453         // SKULLDUGGERY: the mainThread steals the process main thread
     397        // SKULLDUGGERY: the mainThread steals the process main thread 
    454398        // which will then be scheduled by the systemProcessor normally
    455         mainThread = (thread_desc *)&mainThreadStorage;
     399        mainThread = (thread_desc *)&mainThread_storage;
    456400        current_stack_info_t info;
    457401        mainThread{ &info };
     
    459403        LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n");
    460404
     405        // Enable preemption
     406        kernel_start_preemption();
     407
    461408        // Initialize the system cluster
    462         systemCluster = (cluster *)&systemClusterStorage;
     409        systemCluster = (cluster *)&systemCluster_storage;
    463410        systemCluster{};
    464411
     
    467414        // Initialize the system processor and the system processor ctx
    468415        // (the coroutine that contains the processing control flow)
    469         systemProcessor = (system_proc_t *)&systemProcessorStorage;
    470         systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtxStorage };
    471 
    472         // Add the main thread to the ready queue
     416        systemProcessor = (system_proc_t *)&systemProcessor_storage;
     417        systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtx_storage };
     418
     419        // Add the main thread to the ready queue 
    473420        // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread
    474421        ScheduleThread(mainThread);
     
    476423        //initialize the global state variables
    477424        this_processor = &systemProcessor->proc;
    478         this_thread = mainThread;
    479         this_coroutine = &mainThread->cor;
    480         disable_preempt_count = 1;
    481 
    482         // Enable preemption
    483         kernel_start_preemption();
     425        this_processor->current_thread = mainThread;
     426        this_processor->current_coroutine = &mainThread->cor;
    484427
    485428        // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX
    486429        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    487         // mainThread is on the ready queue when this call is made.
     430        // mainThread is on the ready queue when this call is made. 
    488431        resume( systemProcessor->proc.runner );
    489432
     
    492435        // THE SYSTEM IS NOW COMPLETELY RUNNING
    493436        LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");
    494 
    495         enable_interrupts( DEBUG_CTX );
    496437}
    497438
    498439void kernel_shutdown(void) {
    499440        LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n");
    500 
    501         disable_interrupts();
    502441
    503442        // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.
     
    509448        // THE SYSTEM IS NOW COMPLETELY STOPPED
    510449
    511         // Disable preemption
    512         kernel_stop_preemption();
    513 
    514450        // Destroy the system processor and its context in reverse order of construction
    515451        // These were manually constructed so we need manually destroy them
     
    521457        ^(mainThread){};
    522458
    523         LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n");
     459        LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n");   
    524460}
    525461
     
    531467        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
    532468        // the globalAbort flag is true.
    533         lock( &kernel_abort_lock DEBUG_CTX2 );
     469        lock( &kernel_abort_lock );
    534470
    535471        // first task to abort ?
     
    537473                kernel_abort_called = true;
    538474                unlock( &kernel_abort_lock );
    539         }
     475        } 
    540476        else {
    541477                unlock( &kernel_abort_lock );
    542 
     478               
    543479                sigset_t mask;
    544480                sigemptyset( &mask );
     
    546482                sigaddset( &mask, SIGUSR1 );                    // block SIGUSR1 signals
    547483                sigsuspend( &mask );                            // block the processor to prevent further damage during abort
    548                 _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it
    549         }
    550 
    551         return this_thread;
     484                _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it             
     485        }
     486
     487        return this_thread();
    552488}
    553489
     
    558494        __lib_debug_write( STDERR_FILENO, abort_text, len );
    559495
    560         if ( thrd != this_coroutine ) {
    561                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine );
     496        if ( thrd != this_coroutine() ) {
     497                len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine()->name, this_coroutine() );
    562498                __lib_debug_write( STDERR_FILENO, abort_text, len );
    563         }
     499        } 
    564500        else {
    565501                __lib_debug_write( STDERR_FILENO, ".\n", 2 );
     
    569505extern "C" {
    570506        void __lib_debug_acquire() {
    571                 lock( &kernel_debug_lock DEBUG_CTX2 );
     507                lock(&kernel_debug_lock);
    572508        }
    573509
    574510        void __lib_debug_release() {
    575                 unlock( &kernel_debug_lock );
     511                unlock(&kernel_debug_lock);
    576512        }
    577513}
     
    589525}
    590526
    591 bool try_lock( spinlock * this DEBUG_CTX_PARAM2 ) {
     527bool try_lock( spinlock * this ) {
    592528        return this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0;
    593529}
    594530
    595 void lock( spinlock * this DEBUG_CTX_PARAM2 ) {
     531void lock( spinlock * this ) {
    596532        for ( unsigned int i = 1;; i += 1 ) {
    597                 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; }
    598         }
    599         LIB_DEBUG_DO(
    600                 this->prev_name = caller;
    601                 this->prev_thrd = this_thread;
    602         )
    603 }
    604 
    605 void lock_yield( spinlock * this DEBUG_CTX_PARAM2 ) {
    606         for ( unsigned int i = 1;; i += 1 ) {
    607                 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; }
    608                 yield();
    609         }
    610         LIB_DEBUG_DO(
    611                 this->prev_name = caller;
    612                 this->prev_thrd = this_thread;
    613         )
    614 }
    615 
     533                if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) break;
     534        }
     535}
    616536
    617537void unlock( spinlock * this ) {
     
    619539}
    620540
    621 void  ?{}( semaphore * this, int count = 1 ) {
    622         (&this->lock){};
    623         this->count = count;
    624         (&this->waiting){};
    625 }
    626 void ^?{}(semaphore * this) {}
    627 
    628 void P(semaphore * this) {
    629         lock( &this->lock DEBUG_CTX2 );
    630         this->count -= 1;
    631         if ( this->count < 0 ) {
    632                 // queue current task
    633                 append( &this->waiting, (thread_desc *)this_thread );
    634 
    635                 // atomically release spin lock and block
    636                 BlockInternal( &this->lock );
    637         }
    638         else {
    639             unlock( &this->lock );
    640         }
    641 }
    642 
    643 void V(semaphore * this) {
    644         thread_desc * thrd = NULL;
    645         lock( &this->lock DEBUG_CTX2 );
    646         this->count += 1;
    647         if ( this->count <= 0 ) {
    648                 // remove task at head of waiting list
    649                 thrd = pop_head( &this->waiting );
    650         }
    651 
     541void ?{}( signal_once * this ) {
     542        this->cond = false;
     543}
     544void ^?{}( signal_once * this ) {
     545
     546}
     547
     548void wait( signal_once * this ) {
     549        lock( &this->lock );
     550        if( !this->cond ) {
     551                append( &this->blocked, this_thread() );
     552                ScheduleInternal( &this->lock );
     553                lock( &this->lock );
     554        }
    652555        unlock( &this->lock );
    653 
    654         // make new owner
    655         WakeThread( thrd );
     556}
     557
     558void signal( signal_once * this ) {
     559        lock( &this->lock );
     560        {
     561                this->cond = true;
     562
     563                thread_desc * it;
     564                while( it = pop_head( &this->blocked) ) {
     565                        ScheduleThread( it );
     566                }
     567        }
     568        unlock( &this->lock );
    656569}
    657570
     
    677590                }
    678591                head->next = NULL;
    679         }
     592        }       
    680593        return head;
    681594}
     
    696609                this->top = top->next;
    697610                top->next = NULL;
    698         }
     611        }       
    699612        return top;
    700613}
  • src/libcfa/concurrency/kernel_private.h

    r3d4b23fa r55a68c3  
    1818#define KERNEL_PRIVATE_H
    1919
    20 #include "libhdr.h"
    21 
    2220#include "kernel"
    2321#include "thread"
     
    2523#include "alarm.h"
    2624
     25#include "libhdr.h"
    2726
    2827//-----------------------------------------------------------------------------
    2928// Scheduler
    30 
    31 extern "C" {
    32         void disable_interrupts();
    33         void enable_interrupts_noRF();
    34         void enable_interrupts( DEBUG_CTX_PARAM );
    35 }
    36 
    3729void ScheduleThread( thread_desc * );
    38 static inline void WakeThread( thread_desc * thrd ) {
    39         if( !thrd ) return;
    40 
    41         disable_interrupts();
    42         ScheduleThread( thrd );
    43         enable_interrupts( DEBUG_CTX );
    44 }
    4530thread_desc * nextThread(cluster * this);
    4631
    47 void BlockInternal(void);
    48 void BlockInternal(spinlock * lock);
    49 void BlockInternal(thread_desc * thrd);
    50 void BlockInternal(spinlock * lock, thread_desc * thrd);
    51 void BlockInternal(spinlock ** locks, unsigned short count);
    52 void BlockInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
    53 void LeaveThread(spinlock * lock, thread_desc * thrd);
     32void ScheduleInternal(void);
     33void ScheduleInternal(spinlock * lock);
     34void ScheduleInternal(thread_desc * thrd);
     35void ScheduleInternal(spinlock * lock, thread_desc * thrd);
     36void ScheduleInternal(spinlock ** locks, unsigned short count);
     37void ScheduleInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
    5438
    5539//-----------------------------------------------------------------------------
     
    7660extern cluster * systemCluster;
    7761extern system_proc_t * systemProcessor;
    78 extern volatile thread_local processor * this_processor;
    79 extern volatile thread_local coroutine_desc * this_coroutine;
    80 extern volatile thread_local thread_desc * this_thread;
    81 extern volatile thread_local bool preemption_in_progress;
    82 extern volatile thread_local unsigned short disable_preempt_count;
     62extern thread_local processor * this_processor;
     63
     64static inline void disable_interrupts() {
     65        __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, 1, __ATOMIC_SEQ_CST );
     66        assert( prev != (unsigned short) -1 );
     67}
     68
     69static inline void enable_interrupts_noRF() {
     70        __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     71        verify( prev != (unsigned short) 0 );
     72}
     73
     74static inline void enable_interrupts() {
     75        __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     76        verify( prev != (unsigned short) 0 );
     77        if( prev == 1 && this_processor->pending_preemption ) {
     78                ScheduleInternal( this_processor->current_thread );
     79                this_processor->pending_preemption = false;
     80        }
     81}
    8382
    8483//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/monitor

    r3d4b23fa r55a68c3  
    2626static inline void ?{}(monitor_desc * this) {
    2727        this->owner = NULL;
     28        this->stack_owner = NULL;
    2829        this->recursion = 0;
    2930}
  • src/libcfa/concurrency/monitor.c

    r3d4b23fa r55a68c3  
    1919#include <stdlib>
    2020
     21#include "kernel_private.h"
    2122#include "libhdr.h"
    22 #include "kernel_private.h"
    2323
    2424//-----------------------------------------------------------------------------
     
    4444
    4545extern "C" {
    46         void __enter_monitor_desc( monitor_desc * this ) {
    47                 lock_yield( &this->lock DEBUG_CTX2 );
    48                 thread_desc * thrd = this_thread;
    49 
    50                 // LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
     46        void __enter_monitor_desc(monitor_desc * this) {
     47                lock( &this->lock );
     48                thread_desc * thrd = this_thread();
     49
     50                LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
    5151
    5252                if( !this->owner ) {
     
    6262                        //Some one else has the monitor, wait in line for it
    6363                        append( &this->entry_queue, thrd );
    64                         // LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);
    65                         BlockInternal( &this->lock );
    66 
    67                         //BlockInternal will unlock spinlock, no need to unlock ourselves
    68                         return;
     64                        LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);
     65                        ScheduleInternal( &this->lock );
     66
     67                        //ScheduleInternal will unlock spinlock, no need to unlock ourselves
     68                        return; 
    6969                }
    7070
     
    7575        // leave pseudo code :
    7676        //      TODO
    77         void __leave_monitor_desc( monitor_desc * this ) {
    78                 lock_yield( &this->lock DEBUG_CTX2 );
    79 
    80                 // LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i). ", this_thread, this, this->owner, this->recursion);
    81                 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion );
     77        void __leave_monitor_desc(monitor_desc * this) {
     78                lock( &this->lock );
     79
     80                LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
     81                verifyf( this_thread() == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread(), this->owner, this->recursion );
    8282
    8383                //Leaving a recursion level, decrement the counter
     
    9696                unlock( &this->lock );
    9797
    98                 // LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
     98                LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
    9999
    100100                //We need to wake-up the thread
    101                 WakeThread( new_owner );
    102         }
    103 
    104         void __leave_thread_monitor( thread_desc * thrd ) {
    105                 monitor_desc * this = &thrd->mon;
    106                 lock_yield( &this->lock DEBUG_CTX2 );
    107 
    108                 disable_interrupts();
    109 
    110                 thrd->cor.state = Halted;
    111 
    112                 verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion );
    113 
    114                 //Leaving a recursion level, decrement the counter
    115                 this->recursion -= 1;
    116 
    117                 //If we haven't left the last level of recursion
    118                 //it means we don't need to do anything
    119                 if( this->recursion != 0) {
    120                         unlock( &this->lock );
    121                         return;
    122                 }
    123 
    124                 thread_desc * new_owner = next_thread( this );
    125 
    126                 LeaveThread( &this->lock, new_owner );
     101                ScheduleThread( new_owner );
    127102        }
    128103}
     
    146121        enter( this->m, this->count );
    147122
    148         this->prev_mntrs = this_thread->current_monitors;
    149         this->prev_count = this_thread->current_monitor_count;
    150 
    151         this_thread->current_monitors      = m;
    152         this_thread->current_monitor_count = count;
     123        this->prev_mntrs = this_thread()->current_monitors;
     124        this->prev_count = this_thread()->current_monitor_count;
     125
     126        this_thread()->current_monitors      = m;
     127        this_thread()->current_monitor_count = count;
    153128}
    154129
     
    156131        leave( this->m, this->count );
    157132
    158         this_thread->current_monitors      = this->prev_mntrs;
    159         this_thread->current_monitor_count = this->prev_count;
     133        this_thread()->current_monitors      = this->prev_mntrs;
     134        this_thread()->current_monitor_count = this->prev_count;
    160135}
    161136
     
    184159// Internal scheduling
    185160void wait( condition * this, uintptr_t user_info = 0 ) {
    186         // LIB_DEBUG_PRINT_SAFE("Waiting\n");
     161        LIB_DEBUG_PRINT_SAFE("Waiting\n");
    187162
    188163        brand_condition( this );
     
    195170        unsigned short count = this->monitor_count;
    196171        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    197         spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
    198 
    199         // LIB_DEBUG_PRINT_SAFE("count %i\n", count);
    200 
    201         __condition_node_t waiter = { (thread_desc*)this_thread, count, user_info };
     172        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to ScheduleInternal
     173
     174        LIB_DEBUG_PRINT_SAFE("count %i\n", count);
     175
     176        __condition_node_t waiter = { this_thread(), count, user_info };
    202177
    203178        __condition_criterion_t criteria[count];
    204179        for(int i = 0; i < count; i++) {
    205180                (&criteria[i]){ this->monitors[i], &waiter };
    206                 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     181                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    207182        }
    208183
     
    226201        }
    227202
    228         // LIB_DEBUG_PRINT_SAFE("Will unblock: ");
     203        LIB_DEBUG_PRINT_SAFE("Will unblock: ");
    229204        for(int i = 0; i < thread_count; i++) {
    230                 // LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
    231         }
    232         // LIB_DEBUG_PRINT_SAFE("\n");
     205                LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
     206        }
     207        LIB_DEBUG_PRINT_SAFE("\n");
    233208
    234209        // Everything is ready to go to sleep
    235         BlockInternal( locks, count, threads, thread_count );
     210        ScheduleInternal( locks, count, threads, thread_count );
    236211
    237212
     
    247222bool signal( condition * this ) {
    248223        if( is_empty( this ) ) {
    249                 // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
     224                LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    250225                return false;
    251226        }
     
    256231
    257232        unsigned short count = this->monitor_count;
    258 
     233       
    259234        //Some more checking in debug
    260235        LIB_DEBUG_DO(
    261                 thread_desc * this_thrd = this_thread;
     236                thread_desc * this_thrd = this_thread();
    262237                if ( this->monitor_count != this_thrd->current_monitor_count ) {
    263238                        abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count );
     
    273248        //Lock all the monitors
    274249        lock_all( this->monitors, NULL, count );
    275         // LIB_DEBUG_PRINT_SAFE("Signalling");
     250        LIB_DEBUG_PRINT_SAFE("Signalling");
    276251
    277252        //Pop the head of the waiting queue
     
    281256        for(int i = 0; i < count; i++) {
    282257                __condition_criterion_t * crit = &node->criteria[i];
    283                 // LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
     258                LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
    284259                assert( !crit->ready );
    285260                push( &crit->target->signal_stack, crit );
    286261        }
    287262
    288         // LIB_DEBUG_PRINT_SAFE("\n");
     263        LIB_DEBUG_PRINT_SAFE("\n");
    289264
    290265        //Release
     
    306281        unsigned short count = this->monitor_count;
    307282        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    308         spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
     283        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to ScheduleInternal
    309284
    310285        lock_all( this->monitors, locks, count );
    311286
    312287        //create creteria
    313         __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };
     288        __condition_node_t waiter = { this_thread(), count, 0 };
    314289
    315290        __condition_criterion_t criteria[count];
    316291        for(int i = 0; i < count; i++) {
    317292                (&criteria[i]){ this->monitors[i], &waiter };
    318                 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     293                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    319294                push( &criteria[i].target->signal_stack, &criteria[i] );
    320295        }
     
    334309
    335310        //Everything is ready to go to sleep
    336         BlockInternal( locks, count, &signallee, 1 );
     311        ScheduleInternal( locks, count, &signallee, 1 );
    337312
    338313
     
    350325
    351326uintptr_t front( condition * this ) {
    352         verifyf( !is_empty(this),
     327        verifyf( !is_empty(this), 
    353328                "Attempt to access user data on an empty condition.\n"
    354329                "Possible cause is not checking if the condition is empty before reading stored data."
     
    360335// Internal scheduling
    361336void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) {
    362         // thread_desc * this = this_thread;
     337        // thread_desc * this = this_thread();
    363338
    364339        // unsigned short count = this->current_monitor_count;
    365340        // unsigned int recursions[ count ];            //Save the current recursion levels to restore them later
    366         // spinlock *   locks     [ count ];            //We need to pass-in an array of locks to BlockInternal
     341        // spinlock *   locks     [ count ];            //We need to pass-in an array of locks to ScheduleInternal
    367342
    368343        // lock_all( this->current_monitors, locks, count );
     
    373348
    374349        // // // Everything is ready to go to sleep
    375         // // BlockInternal( locks, count, threads, thread_count );
     350        // // ScheduleInternal( locks, count, threads, thread_count );
    376351
    377352
     
    418393static inline void lock_all( spinlock ** locks, unsigned short count ) {
    419394        for( int i = 0; i < count; i++ ) {
    420                 lock_yield( locks[i] DEBUG_CTX2 );
     395                lock( locks[i] );
    421396        }
    422397}
     
    425400        for( int i = 0; i < count; i++ ) {
    426401                spinlock * l = &source[i]->lock;
    427                 lock_yield( l DEBUG_CTX2 );
     402                lock( l );
    428403                if(locks) locks[i] = l;
    429404        }
     
    468443        for(    int i = 0; i < count; i++ ) {
    469444
    470                 // LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
     445                LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
    471446                if( &criteria[i] == target ) {
    472447                        criteria[i].ready = true;
    473                         // LIB_DEBUG_PRINT_SAFE( "True\n" );
     448                        LIB_DEBUG_PRINT_SAFE( "True\n" );
    474449                }
    475450
     
    477452        }
    478453
    479         // LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
     454        LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
    480455        return ready2run ? node->waiting_thread : NULL;
    481456}
    482457
    483458static inline void brand_condition( condition * this ) {
    484         thread_desc * thrd = this_thread;
     459        thread_desc * thrd = this_thread();
    485460        if( !this->monitors ) {
    486                 // LIB_DEBUG_PRINT_SAFE("Branding\n");
     461                LIB_DEBUG_PRINT_SAFE("Branding\n");
    487462                assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors );
    488463                this->monitor_count = thrd->current_monitor_count;
  • src/libcfa/concurrency/preemption.c

    r3d4b23fa r55a68c3  
    1515//
    1616
    17 #include "libhdr.h"
    1817#include "preemption.h"
    1918
    2019extern "C" {
    21 #include <errno.h>
    22 #include <execinfo.h>
    23 #define __USE_GNU
    2420#include <signal.h>
    25 #undef __USE_GNU
    26 #include <stdio.h>
    27 #include <string.h>
    28 #include <unistd.h>
    2921}
    3022
    31 
    32 #ifdef __USE_STREAM__
    33 #include "fstream"
    34 #endif
    35 
    36 #define __CFA_DEFAULT_PREEMPTION__ 10000
     23#define __CFA_DEFAULT_PREEMPTION__ 10
    3724
    3825__attribute__((weak)) unsigned int default_preemption() {
     
    4027}
    4128
    42 #define __CFA_SIGCXT__ ucontext_t *
    43 #define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt
    44 
    4529static void preempt( processor   * this );
    4630static void timeout( thread_desc * this );
    47 
    48 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );
    49 void sigHandler_alarm    ( __CFA_SIGPARMS__ );
    50 void sigHandler_segv     ( __CFA_SIGPARMS__ );
    51 void sigHandler_abort    ( __CFA_SIGPARMS__ );
    52 
    53 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
    54 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )
    55 
    56 #ifdef __x86_64__
    57 #define CFA_REG_IP REG_RIP
    58 #else
    59 #define CFA_REG_IP REG_EIP
    60 #endif
    61 
    6231
    6332//=============================================================================================
     
    6534//=============================================================================================
    6635
     36void kernel_start_preemption() {
     37
     38}
     39
    6740void tick_preemption() {
    68         // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Ticking preemption\n" );
    69 
    7041        alarm_list_t * alarms = &systemProcessor->alarms;
    7142        __cfa_time_t currtime = __kernel_get_time();
    7243        while( alarms->head && alarms->head->alarm < currtime ) {
    7344                alarm_node_t * node = pop(alarms);
    74                 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking %p\n", node );
    75 
    7645                if( node->kernel_alarm ) {
    7746                        preempt( node->proc );
     
    8150                }
    8251
    83                 verify( validate( alarms ) );
    84 
    8552                if( node->period > 0 ) {
    86                         node->alarm = currtime + node->period;
     53                        node->alarm += node->period;
    8754                        insert( alarms, node );
    8855                }
     
    9562                __kernel_set_timer( alarms->head->alarm - currtime );
    9663        }
    97 
    98         verify( validate( alarms ) );
    99         // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking preemption done\n" );
    10064}
    10165
    10266void update_preemption( processor * this, __cfa_time_t duration ) {
    103         LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Processor : %p updating preemption to %lu\n", this, duration );
    104 
     67        //     assert( THREAD_GETMEM( disableInt ) && THREAD_GETMEM( disableIntCnt ) == 1 );
    10568        alarm_node_t * alarm = this->preemption_alarm;
    106         duration *= 1000;
    10769
    10870        // Alarms need to be enabled
     
    12789}
    12890
     91void ?{}( preemption_scope * this, processor * proc ) {
     92        (&this->alarm){ proc };
     93        this->proc = proc;
     94        this->proc->preemption_alarm = &this->alarm;
     95        update_preemption( this->proc, this->proc->preemption );
     96}
     97
     98void ^?{}( preemption_scope * this ) {
     99        update_preemption( this->proc, 0 );
     100}
     101
    129102//=============================================================================================
    130 // Kernel Signal Tools
     103// Kernel Signal logic
    131104//=============================================================================================
    132105
    133 LIB_DEBUG_DO( static thread_local void * last_interrupt = 0; )
    134 
    135 extern "C" {
    136         void disable_interrupts() {
    137                 __attribute__((unused)) unsigned short new_val = __atomic_add_fetch_2( &disable_preempt_count, 1, __ATOMIC_SEQ_CST );
    138                 verify( new_val < (unsigned short)65_000 );
    139                 verify( new_val != (unsigned short) 0 );
    140         }
    141 
    142         void enable_interrupts_noRF() {
    143                 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    144                 verify( prev != (unsigned short) 0 );
    145         }
    146 
    147         void enable_interrupts( DEBUG_CTX_PARAM ) {
    148                 processor * proc   = this_processor;
    149                 thread_desc * thrd = this_thread;
    150                 unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    151                 verify( prev != (unsigned short) 0 );
    152                 if( prev == 1 && proc->pending_preemption ) {
    153                         proc->pending_preemption = false;
    154                         BlockInternal( thrd );
    155                 }
    156 
    157                 LIB_DEBUG_DO( proc->last_enable = caller; )
    158         }
    159 }
    160 
    161 static inline void signal_unblock( int sig ) {
    162         sigset_t mask;
    163         sigemptyset( &mask );
    164         sigaddset( &mask, sig );
    165 
    166         if ( pthread_sigmask( SIG_UNBLOCK, &mask, NULL ) == -1 ) {
    167             abortf( "internal error, pthread_sigmask" );
    168         }
    169 }
    170 
    171 static inline void signal_block( int sig ) {
    172         sigset_t mask;
    173         sigemptyset( &mask );
    174         sigaddset( &mask, sig );
    175 
    176         if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {
    177             abortf( "internal error, pthread_sigmask" );
    178         }
    179 }
    180 
    181106static inline bool preemption_ready() {
    182         return disable_preempt_count == 0 && !preemption_in_progress;
     107        return this_processor->disable_preempt_count == 0;
    183108}
    184109
     
    191116}
    192117
     118void sigHandler_ctxSwitch( __attribute__((unused)) int sig ) {
     119        if( preemption_ready() ) {
     120                ScheduleInternal( this_processor->current_thread );
     121        }
     122        else {
     123                defer_ctxSwitch();
     124        }
     125}
     126
     127void sigHandler_alarm( __attribute__((unused)) int sig ) {
     128        if( try_lock( &systemProcessor->alarm_lock ) ) {
     129                tick_preemption();
     130                unlock( &systemProcessor->alarm_lock );
     131        }
     132        else {
     133                defer_alarm();
     134        }
     135}
     136
    193137static void preempt( processor * this ) {
    194138        pthread_kill( this->kernel_thread, SIGUSR1 );
     
    198142        //TODO : implement waking threads
    199143}
    200 
    201 //=============================================================================================
    202 // Kernel Signal Startup/Shutdown logic
    203 //=============================================================================================
    204 
    205 static pthread_t alarm_thread;
    206 void * alarm_loop( __attribute__((unused)) void * args );
    207 
    208 void kernel_start_preemption() {
    209         LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n");
    210         __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO );
    211         // __kernel_sigaction( SIGSEGV, sigHandler_segv     , SA_SIGINFO );
    212         // __kernel_sigaction( SIGBUS , sigHandler_segv     , SA_SIGINFO );
    213 
    214         signal_block( SIGALRM );
    215 
    216         pthread_create( &alarm_thread, NULL, alarm_loop, NULL );
    217 }
    218 
    219 void kernel_stop_preemption() {
    220         LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopping\n");
    221 
    222         sigset_t mask;
    223         sigfillset( &mask );
    224         sigprocmask( SIG_BLOCK, &mask, NULL );
    225 
    226         sigval val = { 1 };
    227         pthread_sigqueue( alarm_thread, SIGALRM, val );
    228         pthread_join( alarm_thread, NULL );
    229         LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n");
    230 }
    231 
    232 void ?{}( preemption_scope * this, processor * proc ) {
    233         (&this->alarm){ proc };
    234         this->proc = proc;
    235         this->proc->preemption_alarm = &this->alarm;
    236         update_preemption( this->proc, this->proc->preemption );
    237 }
    238 
    239 void ^?{}( preemption_scope * this ) {
    240         disable_interrupts();
    241 
    242         update_preemption( this->proc, 0 );
    243 }
    244 
    245 //=============================================================================================
    246 // Kernel Signal Handlers
    247 //=============================================================================================
    248 
    249 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
    250         LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); )
    251         if( preemption_ready() ) {
    252                 preemption_in_progress = true;
    253                 signal_unblock( SIGUSR1 );
    254                 this_processor->pending_preemption = false;
    255                 preemption_in_progress = false;
    256                 BlockInternal( (thread_desc*)this_thread );
    257         }
    258         else {
    259                 defer_ctxSwitch();
    260         }
    261 }
    262 
    263 void * alarm_loop( __attribute__((unused)) void * args ) {
    264         sigset_t mask;
    265         sigemptyset( &mask );
    266         sigaddset( &mask, SIGALRM );
    267 
    268         if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {
    269             abortf( "internal error, pthread_sigmask" );
    270         }
    271 
    272         while( true ) {
    273                 siginfo_t info;
    274                 int sig = sigwaitinfo( &mask, &info );
    275                 if( sig < 0 ) {
    276                         abortf( "internal error, sigwait" );
    277                 }
    278                 else if( sig == SIGALRM )
    279                 {
    280                         LIB_DEBUG_PRINT_SAFE("Kernel : Caught signal %d (%d)\n", sig, info.si_value.sival_int );
    281                         if( info.si_value.sival_int == 0 )
    282                         {
    283                                 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
    284                                 lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
    285                                 tick_preemption();
    286                                 unlock( &systemProcessor->alarm_lock );
    287                         }
    288                         else if( info.si_value.sival_int == 1 )
    289                         {
    290                                 break;
    291                         }
    292                 }
    293                 else
    294                 {
    295                         LIB_DEBUG_PRINT_SAFE("Kernel : Unexpected signal %d (%d)\n", sig, info.si_value.sival_int);
    296                 }
    297         }
    298 
    299         LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread stopping\n");
    300         return NULL;
    301 }
    302 
    303 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) {
    304         struct sigaction act;
    305 
    306         act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;
    307         act.sa_flags = flags;
    308 
    309         if ( sigaction( sig, &act, NULL ) == -1 ) {
    310                 LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO,
    311                         " __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",
    312                         sig, handler, flags, errno, strerror( errno )
    313                 );
    314                 _exit( EXIT_FAILURE );
    315         }
    316 }
    317 
    318 typedef void (*sa_handler_t)(int);
    319 
    320 static void __kernel_sigdefault( int sig ) {
    321         struct sigaction act;
    322 
    323         // act.sa_handler = SIG_DFL;
    324         act.sa_flags = 0;
    325         sigemptyset( &act.sa_mask );
    326 
    327         if ( sigaction( sig, &act, NULL ) == -1 ) {
    328                 LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO,
    329                         " __kernel_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n",
    330                         sig, errno, strerror( errno )
    331                 );
    332                 _exit( EXIT_FAILURE );
    333         }
    334 }
    335 
    336 //=============================================================================================
    337 // Terminating Signals logic
    338 //=============================================================================================
    339 
    340 LIB_DEBUG_DO(
    341         static void __kernel_backtrace( int start ) {
    342                 // skip first N stack frames
    343 
    344                 enum { Frames = 50 };
    345                 void * array[Frames];
    346                 int size = backtrace( array, Frames );
    347                 char ** messages = backtrace_symbols( array, size );
    348 
    349                 // find executable name
    350                 *index( messages[0], '(' ) = '\0';
    351                 #ifdef __USE_STREAM__
    352                 serr | "Stack back trace for:" | messages[0] | endl;
    353                 #else
    354                 fprintf( stderr, "Stack back trace for: %s\n", messages[0]);
    355                 #endif
    356 
    357                 // skip last 2 stack frames after main
    358                 for ( int i = start; i < size && messages != NULL; i += 1 ) {
    359                         char * name = NULL;
    360                         char * offset_begin = NULL;
    361                         char * offset_end = NULL;
    362 
    363                         for ( char *p = messages[i]; *p; ++p ) {
    364                                 // find parantheses and +offset
    365                                 if ( *p == '(' ) {
    366                                         name = p;
    367                                 }
    368                                 else if ( *p == '+' ) {
    369                                         offset_begin = p;
    370                                 }
    371                                 else if ( *p == ')' ) {
    372                                         offset_end = p;
    373                                         break;
    374                                 }
    375                         }
    376 
    377                         // if line contains symbol print it
    378                         int frameNo = i - start;
    379                         if ( name && offset_begin && offset_end && name < offset_begin ) {
    380                                 // delimit strings
    381                                 *name++ = '\0';
    382                                 *offset_begin++ = '\0';
    383                                 *offset_end++ = '\0';
    384 
    385                                 #ifdef __USE_STREAM__
    386                                 serr    | "("  | frameNo | ")" | messages[i] | ":"
    387                                         | name | "+" | offset_begin | offset_end | endl;
    388                                 #else
    389                                 fprintf( stderr, "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end);
    390                                 #endif
    391                         }
    392                         // otherwise, print the whole line
    393                         else {
    394                                 #ifdef __USE_STREAM__
    395                                 serr | "(" | frameNo | ")" | messages[i] | endl;
    396                                 #else
    397                                 fprintf( stderr, "(%i) %s\n", frameNo, messages[i] );
    398                                 #endif
    399                         }
    400                 }
    401 
    402                 free( messages );
    403         }
    404 )
    405 
    406 // void sigHandler_segv( __CFA_SIGPARMS__ ) {
    407 //      LIB_DEBUG_DO(
    408 //              #ifdef __USE_STREAM__
    409 //              serr    | "*CFA runtime error* program cfa-cpp terminated with"
    410 //                      | (sig == SIGSEGV ? "segment fault." : "bus error.")
    411 //                      | endl;
    412 //              #else
    413 //              fprintf( stderr, "*CFA runtime error* program cfa-cpp terminated with %s\n", sig == SIGSEGV ? "segment fault." : "bus error." );
    414 //              #endif
    415 
    416 //              // skip first 2 stack frames
    417 //              __kernel_backtrace( 1 );
    418 //      )
    419 //      exit( EXIT_FAILURE );
    420 // }
    421 
    422 // void sigHandler_abort( __CFA_SIGPARMS__ ) {
    423 //      // skip first 6 stack frames
    424 //      LIB_DEBUG_DO( __kernel_backtrace( 6 ); )
    425 
    426 //      // reset default signal handler
    427 //      __kernel_sigdefault( SIGABRT );
    428 
    429 //      raise( SIGABRT );
    430 // }
  • src/libcfa/concurrency/thread

    r3d4b23fa r55a68c3  
    5454}
    5555
    56 extern volatile thread_local thread_desc * this_thread;
     56thread_desc * this_thread(void);
    5757
    5858forall( dtype T | is_thread(T) )
  • src/libcfa/concurrency/thread.c

    r3d4b23fa r55a68c3  
    2828}
    2929
    30 extern volatile thread_local processor * this_processor;
     30extern thread_local processor * this_processor;
    3131
    3232//-----------------------------------------------------------------------------
     
    7171        coroutine_desc* thrd_c = get_coroutine(this);
    7272        thread_desc*  thrd_h = get_thread   (this);
    73         thrd_c->last = this_coroutine;
     73        thrd_c->last = this_coroutine();
     74        this_processor->current_coroutine = thrd_c;
    7475
    75         // LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
     76        LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
    7677
    77         disable_interrupts();
    7878        create_stack(&thrd_c->stack, thrd_c->stack.size);
    79         this_coroutine = thrd_c;
    8079        CtxStart(this, CtxInvokeThread);
    81         assert( thrd_c->last->stack.context );
    8280        CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context );
    8381
    8482        ScheduleThread(thrd_h);
    85         enable_interrupts( DEBUG_CTX );
    8683}
    8784
    8885void yield( void ) {
    89         BlockInternal( (thread_desc *)this_thread );
     86        ScheduleInternal( this_processor->current_thread );
    9087}
    9188
     
    9895void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    9996        // set state of current coroutine to inactive
    100         src->state = src->state == Halted ? Halted : Inactive;
     97        src->state = Inactive;
    10198        dst->state = Active;
    10299
     
    106103        // set new coroutine that the processor is executing
    107104        // and context switch to it
    108         this_coroutine = dst;
    109         assert( src->stack.context );
     105        this_processor->current_coroutine = dst;
    110106        CtxSwitch( src->stack.context, dst->stack.context );
    111         this_coroutine = src;
     107        this_processor->current_coroutine = src;
    112108
    113109        // set state of new coroutine to active
    114         dst->state = dst->state == Halted ? Halted : Inactive;
     110        dst->state = Inactive;
    115111        src->state = Active;
    116112}
  • src/libcfa/exception.c

    r3d4b23fa r55a68c3  
    1010// Created On       : Mon Jun 26 15:13:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tus Jul 11 16:36:00 2017
    13 // Update Count     : 1
     12// Last Modified On : Mon Nov 26 15:11:00 2017
     13// Update Count     : 0
    1414//
    1515
     
    4444// RESUMPTION ================================================================
    4545
    46 void __cfaehm__throw_resume(exception * except) {
     46void __cfaehm__throw_resumption(exception * except) {
    4747
    4848        // DEBUG
     
    6565
    6666        // Fall back to termination:
    67         __cfaehm__throw_terminate(except);
     67        __cfaehm__throw_termination(except);
    6868        // TODO: Default handler for resumption.
    6969}
     
    111111}
    112112
    113 void __cfaehm__throw_terminate( exception * val ) {
     113void __cfaehm__throw_termination( exception * val ) {
    114114        // Store the current exception
    115115        shared_stack.current_exception = *val;
     
    147147
    148148// Nesting this the other way would probably be faster.
    149 void __cfaehm__rethrow_terminate(void) {
     149void __cfaehm__rethrow_termination(void) {
    150150        // DEBUG
    151151        printf("Rethrowing termination exception\n");
    152152
    153         __cfaehm__throw_terminate(&shared_stack.current_exception);
     153        __cfaehm__throw_termination(&shared_stack.current_exception);
    154154}
    155155
  • src/libcfa/exception.h

    r3d4b23fa r55a68c3  
    1010// Created On       : Mon Jun 26 15:11:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tus Jul 11 16:31:00 2017
    13 // Update Count     : 2
     12// Last Modified On : Mon Nov 26 15:11:00 2017
     13// Update Count     : 0
    1414//
    1515
     
    2222
    2323#ifdef __CFORALL__
    24 extern "C" {
     24extern "BuiltinC" {
    2525#endif
    2626
    2727// Used in throw statement translation.
    28 void __cfaehm__throw_terminate(exception * except) __attribute__((noreturn));
    29 void __cfaehm__rethrow_terminate() __attribute__((noreturn));
    30 void __cfaehm__throw_resume(exception * except);
     28void __cfaehm__throw_termination(exception * except) __attribute__((noreturn));
     29void __cfaehm__rethrow_termination() __attribute__((noreturn));
     30void __cfaehm__throw_resumption(exception * except);
    3131
    3232// Function catches termination exceptions.
  • src/libcfa/fstream

    r3d4b23fa r55a68c3  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  7 08:32:38 2017
    13 // Update Count     : 117
     12// Last Modified On : Sat Jul  1 16:37:53 2017
     13// Update Count     : 112
    1414//
    1515
    16 #pragma once
     16#ifndef __FSTREAM_H__
     17#define __FSTREAM_H__
    1718
    1819#include "iostream"
    1920
    20 enum { sepSize = 16 };
     21enum { separateSize = 16 };
    2122struct ofstream {
    2223        void * file;
    2324        _Bool sepDefault;
    2425        _Bool sepOnOff;
    25         _Bool sawNL;
     26        _Bool lastSepOn;
    2627        const char * sepCur;
    27         char separator[sepSize];
    28         char tupleSeparator[sepSize];
     28        char separator[separateSize];
     29        char tupleSeparator[separateSize];
    2930}; // ofstream
    3031
     
    3536const char * sepGetCur( ofstream * );
    3637void sepSetCur( ofstream *, const char * );
    37 _Bool getNL( ofstream * );
    38 void setNL( ofstream *, _Bool );
     38_Bool lastSepOn( ofstream * );
    3939
    4040// public
     
    7575extern ifstream * sin;
    7676
     77#endif // __FSTREAM_H__
     78
    7779// Local Variables: //
    7880// mode: c //
  • src/libcfa/fstream.c

    r3d4b23fa r55a68c3  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul  6 18:38:25 2017
    13 // Update Count     : 251
     12// Last Modified On : Sat Jul  1 16:37:54 2017
     13// Update Count     : 242
    1414//
    1515
     
    3333        this->sepDefault = sepDefault;
    3434        this->sepOnOff = sepOnOff;
     35        this->lastSepOn = false;
    3536        sepSet( this, separator );
    3637        sepSetCur( this, sepGet( this ) );
     
    3940
    4041// private
    41 _Bool sepPrt( ofstream * os ) { setNL( os, false ); return os->sepOnOff; }
     42_Bool lastSepOn( ofstream * os ) { return os->lastSepOn; }
     43_Bool sepPrt( ofstream * os ) { os->lastSepOn = false; return os->sepOnOff; }
    4244void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; }
    4345void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; }
    4446const char * sepGetCur( ofstream * os ) { return os->sepCur; }
    4547void sepSetCur( ofstream * os, const char * sepCur ) { os->sepCur = sepCur; }
    46 _Bool getNL( ofstream * os ) { return os->sawNL; }
    47 void setNL( ofstream * os, _Bool state ) { os->sawNL = state; }
    4848
    4949// public
    50 void sepOn( ofstream * os ) { os->sepOnOff = ! getNL( os ); }
    51 void sepOff( ofstream * os ) { os->sepOnOff = false; }
     50void sepOn( ofstream * os ) { os->lastSepOn = true; os->sepOnOff = true; }
     51void sepOff( ofstream * os ) { os->lastSepOn = false; os->sepOnOff = 0; }
    5252
    5353_Bool sepDisable( ofstream *os ) {
    5454        _Bool temp = os->sepDefault;
    5555        os->sepDefault = false;
     56        os->lastSepOn = false;
    5657        sepReset( os );
    5758        return temp;
     
    6869void sepSet( ofstream * os, const char * s ) {
    6970        assert( s );
    70         strncpy( os->separator, s, sepSize - 1 );
    71         os->separator[sepSize - 1] = '\0';
     71        strncpy( os->separator, s, separateSize - 1 );
     72        os->separator[separateSize - 1] = '\0';
    7273} // sepSet
    7374
     
    7576void sepSetTuple( ofstream * os, const char * s ) {
    7677        assert( s );
    77         strncpy( os->tupleSeparator, s, sepSize - 1 );
    78         os->tupleSeparator[sepSize - 1] = '\0';
     78        strncpy( os->tupleSeparator, s, separateSize - 1 );
     79        os->tupleSeparator[separateSize - 1] = '\0';
    7980} // sepSet
    8081
     
    152153
    153154void open( ifstream * is, const char * name, const char * mode ) {
    154         FILE *file = fopen( name, mode );
    155         if ( file == 0 ) {                                                                      // do not change unless successful
     155        FILE *t = fopen( name, mode );
     156        if ( t == 0 ) {                                                                         // do not change unless successful
    156157                fprintf( stderr, IO_MSG "open input file \"%s\", ", name );
    157158                perror( 0 );
    158159                exit( EXIT_FAILURE );
    159160        } // if
    160         is->file = file;
     161        is->file = t;
    161162} // open
    162163
  • src/libcfa/gmp

    r3d4b23fa r55a68c3  
    1010// Created On       : Tue Apr 19 08:43:43 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  7 09:33:20 2017
    13 // Update Count     : 15
     12// Last Modified On : Sat May 27 09:55:51 2017
     13// Update Count     : 14
    1414//
    1515
    1616// https://gmplib.org/gmp-man-6.1.1.pdf
    17 
    18 #pragma once
    1917
    2018#include <gmp.h>                                                                                // GNU multi-precise integers
  • src/libcfa/iostream

    r3d4b23fa r55a68c3  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  7 08:35:59 2017
    13 // Update Count     : 118
     12// Last Modified On : Sun Jul  2 08:42:56 2017
     13// Update Count     : 110
    1414//
    1515
    16 #pragma once
     16#ifndef __IOSTREAM_H__
     17#define __IOSTREAM_H__
    1718
    1819#include "iterator"
     
    2526        const char * sepGetCur( ostype * );                                     // get current separator string
    2627        void sepSetCur( ostype *, const char * );                       // set current separator string
    27         _Bool getNL( ostype * );                                                        // check newline
    28         void setNL( ostype *, _Bool );                                          // saw newline
     28        _Bool lastSepOn( ostype * );                                            // last manipulator is setOn (context sensitive)
    2929        // public
    3030        void sepOn( ostype * );                                                         // turn separator state on
     
    8282forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, ostype * (*)( ostype * ) );
    8383forall( dtype ostype | ostream( ostype ) ) ostype * endl( ostype * );
    84 forall( dtype ostype | ostream( ostype ) ) ostype * sep( ostype * );
    85 forall( dtype ostype | ostream( ostype ) ) ostype * sepTuple( ostype * );
    8684forall( dtype ostype | ostream( ostype ) ) ostype * sepOn( ostype * );
    8785forall( dtype ostype | ostream( ostype ) ) ostype * sepOff( ostype * );
     
    139137forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_cstrC );
    140138
     139#endif // __IOSTREAM_H
     140
    141141// Local Variables: //
    142142// mode: c //
  • src/libcfa/iostream.c

    r3d4b23fa r55a68c3  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul  6 18:14:17 2017
    13 // Update Count     : 396
     12// Last Modified On : Sun Jul  2 08:54:02 2017
     13// Update Count     : 375
    1414//
    1515
     
    1818extern "C" {
    1919#include <stdio.h>
    20 #include <stdbool.h>                                                                    // true/false
    2120#include <string.h>                                                                             // strlen
    2221#include <float.h>                                                                              // DBL_DIG, LDBL_DIG
     
    2524
    2625forall( dtype ostype | ostream( ostype ) )
    27 ostype * ?|?( ostype * os, char ch ) {
    28         fmt( os, "%c", ch );
    29         if ( ch == '\n' ) setNL( os, true );
     26ostype * ?|?( ostype * os, char c ) {
     27        fmt( os, "%c", c );
    3028        sepOff( os );
    3129        return os;
     
    182180
    183181        // last character IS spacing or opening punctuation => turn off separator for next item
    184         size_t len = strlen( cp );
    185         ch = cp[len - 1];                                                                       // must make unsigned
     182        unsigned int len = strlen( cp ), posn = len - 1;
     183        ch = cp[posn];                                                                          // must make unsigned
    186184        if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
    187185                sepOn( os );
     
    189187                sepOff( os );
    190188        } // if
    191         if ( ch == '\n' ) setNL( os, true );                            // check *AFTER* sepPrt call above as it resets NL flag
    192189        return write( os, cp, len );
    193190} // ?|?
     
    219216
    220217forall( dtype ostype | ostream( ostype ) )
    221 ostype * sep( ostype * os ) {
    222         os | sepGet( os );
    223         return os;
    224 } // sep
    225 
    226 forall( dtype ostype | ostream( ostype ) )
    227 ostype * sepTuple( ostype * os ) {
    228         os | sepGetTuple( os );
    229         return os;
    230 } // sepTuple
    231 
    232 forall( dtype ostype | ostream( ostype ) )
    233218ostype * endl( ostype * os ) {
     219        if ( lastSepOn( os ) ) fmt( os, "%s", sepGetCur( os ) );
    234220        os | '\n';
    235         setNL( os, true );
    236221        flush( os );
    237222        sepOff( os );                                                                           // prepare for next line
  • src/libcfa/iterator

    r3d4b23fa r55a68c3  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  7 08:37:25 2017
    13 // Update Count     : 10
     12// Last Modified On : Wed Mar  2 18:06:05 2016
     13// Update Count     : 9
    1414//
    1515
    16 #pragma once
     16#ifndef ITERATOR_H
     17#define ITERATOR_H
    1718
    1819// An iterator can be used to traverse a data structure.
     
    3839
    3940forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) )
    40 void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) );
     41void for_each( iterator_type begin, iterator_type end, void (*func)( elt_type ) );
    4142
    4243forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) )
    43 void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) );
     44void for_each_reverse( iterator_type begin, iterator_type end, void (*func)( elt_type ) );
     45
     46#endif // ITERATOR_H
    4447
    4548// Local Variables: //
  • src/libcfa/iterator.c

    r3d4b23fa r55a68c3  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  7 08:38:23 2017
    13 // Update Count     : 28
     12// Last Modified On : Wed Mar  2 18:08:11 2016
     13// Update Count     : 27
    1414//
    1515
     
    1717
    1818forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) )
    19 void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) {
     19void for_each( iterator_type begin, iterator_type end, void (*func)( elt_type ) ) {
    2020        for ( iterator_type i = begin; i != end; ++i ) {
    2121                func( *i );
    22         } // for
    23 } // for_each
     22        }
     23}
    2424
    2525forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) )
    26 void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) {
     26void for_each_reverse( iterator_type begin, iterator_type end, void (*func)( elt_type ) ) {
    2727        for ( iterator_type i = end; i != begin; ) {
    2828                --i;
    2929                func( *i );
    30         } // for
    31 } // for_each_reverse
     30        }
     31}
    3232
    3333// Local Variables: //
  • src/libcfa/libhdr/libalign.h

    r3d4b23fa r55a68c3  
    1 //                              -*- Mode: C++ -*-
     1//                              -*- Mode: C++ -*- 
    22//
    33// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     
    1818// Free Software  Foundation; either  version 2.1 of  the License, or  (at your
    1919// option) any later version.
    20 //
     20// 
    2121// This library is distributed in the  hope that it will be useful, but WITHOUT
    2222// ANY  WARRANTY;  without even  the  implied  warranty  of MERCHANTABILITY  or
    2323// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
    2424// for more details.
    25 //
     25// 
    2626// You should  have received a  copy of the  GNU Lesser General  Public License
    2727// along  with this library.
    28 //
     28// 
    2929
    3030
     
    3333
    3434#include "assert"
    35 #include <stdbool.h>
    3635
    37 // Minimum size used to align memory boundaries for memory allocations.
     36// Minimum size used to align memory boundaries for memory allocations. 
    3837#define libAlign() (sizeof(double))
    3938
  • src/libcfa/libhdr/libdebug.h

    r3d4b23fa r55a68c3  
    1818
    1919#ifdef __CFA_DEBUG__
    20         #define LIB_DEBUG_DO(...) __VA_ARGS__
    21         #define LIB_NO_DEBUG_DO(...)
    22         #define DEBUG_CTX __PRETTY_FUNCTION__
    23         #define DEBUG_CTX2 , __PRETTY_FUNCTION__
    24         #define DEBUG_CTX_PARAM const char * caller
    25         #define DEBUG_CTX_PARAM2 , const char * caller
     20        #define LIB_DEBUG_DO(x) x
     21        #define LIB_NO_DEBUG_DO(x) ((void)0)
    2622#else
    27         #define LIB_DEBUG_DO(...)
    28         #define LIB_NO_DEBUG_DO(...) __VA_ARGS__
    29         #define DEBUG_CTX
    30         #define DEBUG_CTX2
    31         #define DEBUG_CTX_PARAM
    32         #define DEBUG_CTX_PARAM2
     23        #define LIB_DEBUG_DO(x) ((void)0)
     24        #define LIB_NO_DEBUG_DO(x) x     
    3325#endif
    3426
     
    5951
    6052#ifdef __CFA_DEBUG_PRINT__
    61         #define LIB_DEBUG_WRITE( fd, buffer, len )     __lib_debug_write( fd, buffer, len )
    62         #define LIB_DEBUG_ACQUIRE()                    __lib_debug_acquire()
    63         #define LIB_DEBUG_RELEASE()                    __lib_debug_release()
    64         #define LIB_DEBUG_PRINT_SAFE(...)              __lib_debug_print_safe   (__VA_ARGS__)
    65         #define LIB_DEBUG_PRINT_NOLOCK(...)            __lib_debug_print_nolock (__VA_ARGS__)
    66         #define LIB_DEBUG_PRINT_BUFFER(...)            __lib_debug_print_buffer (__VA_ARGS__)
    67         #define LIB_DEBUG_PRINT_BUFFER_DECL(fd, ...)   char text[256]; int len = snprintf( text, 256, __VA_ARGS__ ); __lib_debug_write( fd, text, len );
    68         #define LIB_DEBUG_PRINT_BUFFER_LOCAL(fd, ...)  len = snprintf( text, 256, __VA_ARGS__ ); __lib_debug_write( fd, text, len );
     53      #define LIB_DEBUG_WRITE( fd, buffer, len )  __lib_debug_write( fd, buffer, len )
     54      #define LIB_DEBUG_ACQUIRE()                 __lib_debug_acquire()
     55      #define LIB_DEBUG_RELEASE()                 __lib_debug_release()
     56      #define LIB_DEBUG_PRINT_SAFE(...)           __lib_debug_print_safe   (__VA_ARGS__)
     57      #define LIB_DEBUG_PRINT_NOLOCK(...)         __lib_debug_print_nolock (__VA_ARGS__)
     58      #define LIB_DEBUG_PRINT_BUFFER(...)         __lib_debug_print_buffer (__VA_ARGS__)
    6959#else
    70         #define LIB_DEBUG_WRITE(...)               ((void)0)
    71         #define LIB_DEBUG_ACQUIRE()                ((void)0)
    72         #define LIB_DEBUG_RELEASE()                ((void)0)
    73         #define LIB_DEBUG_PRINT_SAFE(...)          ((void)0)
    74         #define LIB_DEBUG_PRINT_NOLOCK(...)        ((void)0)
    75         #define LIB_DEBUG_PRINT_BUFFER(...)        ((void)0)
    76         #define LIB_DEBUG_PRINT_BUFFER_DECL(...)   ((void)0)
    77         #define LIB_DEBUG_PRINT_BUFFER_LOCAL(...)  ((void)0)
     60      #define LIB_DEBUG_WRITE(...)          ((void)0)
     61      #define LIB_DEBUG_ACQUIRE()           ((void)0)
     62      #define LIB_DEBUG_RELEASE()           ((void)0)
     63      #define LIB_DEBUG_PRINT_SAFE(...)     ((void)0)
     64      #define LIB_DEBUG_PRINT_NOLOCK(...)   ((void)0)
     65      #define LIB_DEBUG_PRINT_BUFFER(...)   ((void)0)
    7866#endif
    7967
  • src/libcfa/limits

    r3d4b23fa r55a68c3  
    1010// Created On       : Wed Apr  6 18:06:52 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  7 09:33:57 2017
    13 // Update Count     : 7
     12// Last Modified On : Wed Apr  6 21:08:16 2016
     13// Update Count     : 6
    1414//
    1515
    16 #pragma once
     16#ifndef LIMITS_H
     17#define LIMITS_H
    1718
    1819// Integral Constants
     
    109110extern const long _Complex _1_SQRT_2;                                   // 1 / sqrt(2)
    110111
     112#endif // LIMITS_H
     113
    111114// Local Variables: //
    112115// mode: c //
  • src/libcfa/math

    r3d4b23fa r55a68c3  
    1010// Created On       : Mon Apr 18 23:37:04 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  7 09:34:15 2017
    13 // Update Count     : 61
    14 //
    15 
    16 #pragma once
     12// Last Modified On : Wed May 24 17:40:39 2017
     13// Update Count     : 60
     14//
     15
     16#ifndef MATH_H
     17#define MATH_H
    1718
    1819extern "C" {
     
    344345long double scalbln( long double, long int );
    345346
     347#endif // MATH_H
     348
    346349// Local Variables: //
    347350// mode: c //
  • src/libcfa/rational

    r3d4b23fa r55a68c3  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Fri Jul  7 09:34:33 2017
    15 // Update Count     : 93
     14// Last Modified On : Mon May 15 21:30:12 2017
     15// Update Count     : 90
    1616//
    1717
    18 #pragma once
     18#ifndef RATIONAL_H
     19#define RATIONAL_H
    1920
    2021#include "iostream"
     
    4647// implementation
    4748
    48 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     49forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    4950struct Rational {
    5051        RationalImpl numerator, denominator;                            // invariant: denominator > 0
     
    5354// constructors
    5455
    55 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     56forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    5657void ?{}( Rational(RationalImpl) * r );
    5758
    58 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     59forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    5960void ?{}( Rational(RationalImpl) * r, RationalImpl n );
    6061
    61 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     62forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    6263void ?{}( Rational(RationalImpl) * r, RationalImpl n, RationalImpl d );
    6364
    64 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     65forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    6566void ?{}( Rational(RationalImpl) * r, zero_t );
    6667
    67 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     68forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    6869void ?{}( Rational(RationalImpl) * r, one_t );
    6970
    70 // numerator/denominator getter
     71// getter for numerator/denominator
    7172
    72 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     73forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    7374RationalImpl numerator( Rational(RationalImpl) r );
    7475
    75 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     76forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    7677RationalImpl denominator( Rational(RationalImpl) r );
    77 
    78 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     78forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    7979[ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src );
    8080
    81 // numerator/denominator setter
     81// setter for numerator/denominator
    8282
    83 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     83forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    8484RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n );
    8585
    86 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     86forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    8787RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d );
    8888
    8989// comparison
    9090
    91 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     91forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    9292int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    9393
    94 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     94forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    9595int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    9696
    97 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     97forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    9898int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    9999
    100 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     100forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    101101int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    102102
    103 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     103forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    104104int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    105105
    106 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     106forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    107107int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    108108
    109109// arithmetic
    110110
    111 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     111forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    112112Rational(RationalImpl) +?( Rational(RationalImpl) r );
    113113
    114 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     114forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    115115Rational(RationalImpl) -?( Rational(RationalImpl) r );
    116116
    117 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     117forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    118118Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    119119
    120 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     120forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    121121Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    122122
    123 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     123forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    124124Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    125125
    126 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     126forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    127127Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    128128
    129129// conversion
    130 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
     130forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
    131131double widen( Rational(RationalImpl) r );
    132 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl );  RationalImpl convert( double );} )
     132forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl );  RationalImpl convert( double );} )
    133133Rational(RationalImpl) narrow( double f, RationalImpl md );
    134134
    135135// I/O
    136 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     136forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    137137forall( dtype istype | istream( istype ) | { istype * ?|?( istype *, RationalImpl * ); } )
    138138istype * ?|?( istype *, Rational(RationalImpl) * );
    139139
    140 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     140forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    141141forall( dtype ostype | ostream( ostype ) | { ostype * ?|?( ostype *, RationalImpl ); } )
    142142ostype * ?|?( ostype *, Rational(RationalImpl ) );
     143
     144#endif // RATIONAL_H
    143145
    144146// Local Variables: //
  • src/libcfa/rational.c

    r3d4b23fa r55a68c3  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 16 18:35:36 2017
    13 // Update Count     : 150
     12// Last Modified On : Mon May 15 21:29:23 2017
     13// Update Count     : 149
    1414//
    1515
     
    2222// Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce rationals.
    2323// alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
    24 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     24forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    2525static RationalImpl gcd( RationalImpl a, RationalImpl b ) {
    2626        for ( ;; ) {                                                                            // Euclid's algorithm
     
    3333} // gcd
    3434
    35 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     35forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    3636static RationalImpl simplify( RationalImpl * n, RationalImpl * d ) {
    3737        if ( *d == (RationalImpl){0} ) {
     
    4646// constructors
    4747
    48 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     48forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    4949void ?{}( Rational(RationalImpl) * r ) {
    5050        r{ (RationalImpl){0}, (RationalImpl){1} };
    5151} // rational
    5252
    53 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     53forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    5454void ?{}( Rational(RationalImpl) * r, RationalImpl n ) {
    5555        r{ n, (RationalImpl){1} };
    5656} // rational
    5757
    58 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     58forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    5959void ?{}( Rational(RationalImpl) * r, RationalImpl n, RationalImpl d ) {
    6060        RationalImpl t = simplify( &n, &d );                            // simplify
     
    6666// getter for numerator/denominator
    6767
    68 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     68forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    6969RationalImpl numerator( Rational(RationalImpl) r ) {
    7070        return r.numerator;
    7171} // numerator
    7272
    73 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     73forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    7474RationalImpl denominator( Rational(RationalImpl) r ) {
    7575        return r.denominator;
    7676} // denominator
    7777
    78 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     78forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    7979[ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ) {
    8080        return *dest = src.[ numerator, denominator ];
     
    8383// setter for numerator/denominator
    8484
    85 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     85forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    8686RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ) {
    8787        RationalImpl prev = r.numerator;
     
    9292} // numerator
    9393
    94 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     94forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    9595RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ) {
    9696        RationalImpl prev = r.denominator;
     
    104104// comparison
    105105
    106 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     106forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    107107int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    108108        return l.numerator * r.denominator == l.denominator * r.numerator;
    109109} // ?==?
    110110
    111 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     111forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    112112int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    113113        return ! ( l == r );
    114114} // ?!=?
    115115
    116 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     116forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    117117int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    118118        return l.numerator * r.denominator < l.denominator * r.numerator;
    119119} // ?<?
    120120
    121 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     121forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    122122int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    123123        return l.numerator * r.denominator <= l.denominator * r.numerator;
    124124} // ?<=?
    125125
    126 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     126forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    127127int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    128128        return ! ( l <= r );
    129129} // ?>?
    130130
    131 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     131forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    132132int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    133133        return ! ( l < r );
     
    137137// arithmetic
    138138
    139 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     139forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    140140Rational(RationalImpl) +?( Rational(RationalImpl) r ) {
    141141        Rational(RationalImpl) t = { r.numerator, r.denominator };
     
    143143} // +?
    144144
    145 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     145forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    146146Rational(RationalImpl) -?( Rational(RationalImpl) r ) {
    147147        Rational(RationalImpl) t = { -r.numerator, r.denominator };
     
    149149} // -?
    150150
    151 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     151forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    152152Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    153153        if ( l.denominator == r.denominator ) {                         // special case
     
    160160} // ?+?
    161161
    162 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     162forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    163163Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    164164        if ( l.denominator == r.denominator ) {                         // special case
     
    171171} // ?-?
    172172
    173 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     173forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    174174Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    175175        Rational(RationalImpl) t = { l.numerator * r.numerator, l.denominator * r.denominator };
     
    177177} // ?*?
    178178
    179 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     179forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    180180Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    181181        if ( r.numerator < (RationalImpl){0} ) {
     
    190190// conversion
    191191
    192 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
     192forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
    193193double widen( Rational(RationalImpl) r ) {
    194194        return convert( r.numerator ) / convert( r.denominator );
     
    196196
    197197// http://www.ics.uci.edu/~eppstein/numth/frap.c
    198 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )
     198forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )
    199199Rational(RationalImpl) narrow( double f, RationalImpl md ) {
    200200        if ( md <= (RationalImpl){1} ) {                                        // maximum fractional digits too small?
     
    227227// I/O
    228228
    229 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     229forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    230230forall( dtype istype | istream( istype ) | { istype * ?|?( istype *, RationalImpl * ); } )
    231231istype * ?|?( istype * is, Rational(RationalImpl) * r ) {
     
    238238} // ?|?
    239239
    240 forall( otype RationalImpl | arithmetic( RationalImpl ) )
     240forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    241241forall( dtype ostype | ostream( ostype ) | { ostype * ?|?( ostype *, RationalImpl ); } )
    242242ostype * ?|?( ostype * os, Rational(RationalImpl ) r ) {
  • src/libcfa/stdlib

    r3d4b23fa r55a68c3  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  7 09:34:49 2017
    13 // Update Count     : 219
    14 //
    15 
    16 #pragma once
     12// Last Modified On : Fri Jun  2 15:51:03 2017
     13// Update Count     : 218
     14//
     15
     16#ifndef STDLIB_H
     17#define STDLIB_H
    1718
    1819//---------------------------------------
     
    231232void swap( T * t1, T * t2 );
    232233
     234#endif // STDLIB_H
     235
    233236// Local Variables: //
    234237// mode: c //
  • src/main.cc

    r3d4b23fa r55a68c3  
    1010// Author           : Richard C. Bilson
    1111// Created On       : Fri May 15 23:12:02 2015
    12 // Last Modified By : Andrew Beach
    13 // Last Modified On : Fri Jul  7 11:13:00 2017
    14 // Update Count     : 442
     12// Last Modified By : Peter A. Buhr
     13// Last Modified On : Thu Jun 29 12:46:50 2017
     14// Update Count     : 441
    1515//
    1616
    17 #include <cassert>                          // for assertf
    18 #include <cxxabi.h>                         // for __cxa_demangle
    19 #include <execinfo.h>                       // for backtrace, backtrace_symbols
    20 #include <getopt.h>                         // for no_argument, optind, geto...
    21 #include <signal.h>                         // for signal, SIGABRT, SIGSEGV
    22 #include <cstdio>                           // for fopen, FILE, fclose, stdin
    23 #include <cstdlib>                          // for exit, free, abort, EXIT_F...
    24 #include <cstring>                          // for index
    25 #include <fstream>                          // for ofstream
    26 #include <iostream>                         // for operator<<, basic_ostream
    27 #include <iterator>                         // for back_inserter
    28 #include <list>                             // for list
    29 #include <string>                           // for operator<<, allocator
    30 
    31 #include "../config.h"                      // for CFA_LIBDIR
    32 #include "CodeGen/FixMain.h"                // for FixMain
    33 #include "CodeGen/FixNames.h"               // for fixNames
    34 #include "CodeGen/Generate.h"               // for generate
    35 #include "CodeTools/DeclStats.h"            // for printDeclStats
    36 #include "CodeTools/TrackLoc.h"             // for fillLocations
    37 #include "Common/CompilerError.h"           // for CompilerError
    38 #include "Common/SemanticError.h"           // for SemanticError
    39 #include "Common/UnimplementedError.h"      // for UnimplementedError
    40 #include "Common/utility.h"                 // for deleteAll, filter, printAll
    41 #include "ControlStruct/ExceptTranslate.h"  // for translateEHM
    42 #include "ControlStruct/Mutate.h"           // for mutate
    43 #include "GenPoly/Box.h"                    // for box
    44 #include "GenPoly/CopyParams.h"             // for copyParams
    45 #include "GenPoly/InstantiateGeneric.h"     // for instantiateGeneric
    46 #include "GenPoly/Lvalue.h"                 // for convertLvalue
    47 #include "GenPoly/Specialize.h"             // for convertSpecializations
    48 #include "InitTweak/FixInit.h"              // for fix
    49 #include "InitTweak/GenInit.h"              // for genInit
    50 #include "MakeLibCfa.h"                     // for makeLibCfa
    51 #include "Parser/LinkageSpec.h"             // for Spec, Cforall, Intrinsic
    52 #include "Parser/ParseNode.h"               // for DeclarationNode, buildList
    53 #include "Parser/TypedefTable.h"            // for TypedefTable
    54 #include "ResolvExpr/AlternativePrinter.h"  // for AlternativePrinter
    55 #include "ResolvExpr/Resolver.h"            // for resolve
    56 #include "SymTab/Validate.h"                // for validate
    57 #include "SynTree/Declaration.h"            // for Declaration
    58 #include "SynTree/Visitor.h"                // for acceptAll
    59 #include "Tuples/Tuples.h"                  // for expandMemberTuples, expan...
     17#include <iostream>
     18#include <fstream>
     19#include <signal.h>                                                                             // signal
     20#include <getopt.h>                                                                             // getopt
     21#include <execinfo.h>                                                                   // backtrace, backtrace_symbols
     22#include <cxxabi.h>                                                                             // __cxa_demangle
     23#include <cstring>                                                                              // index
     24
     25using namespace std;
     26
     27#include "Parser/ParserTypes.h"
     28#include "Parser/TypedefTable.h"
     29#include "GenPoly/Lvalue.h"
     30#include "GenPoly/Specialize.h"
     31#include "GenPoly/Box.h"
     32#include "GenPoly/CopyParams.h"
     33#include "GenPoly/InstantiateGeneric.h"
     34#include "Concurrency/Keywords.h"
     35#include "CodeGen/Generate.h"
     36#include "CodeGen/FixNames.h"
     37#include "CodeGen/FixMain.h"
     38#include "CodeTools/DeclStats.h"
     39#include "CodeTools/TrackLoc.h"
     40#include "ControlStruct/Mutate.h"
     41#include "ControlStruct/ExceptTranslate.h"
     42#include "SymTab/Validate.h"
     43#include "ResolvExpr/AlternativePrinter.h"
     44#include "ResolvExpr/Resolver.h"
     45#include "MakeLibCfa.h"
     46#include "InitTweak/GenInit.h"
     47#include "InitTweak/FixInit.h"
     48#include "Common/UnimplementedError.h"
     49#include "../config.h"
     50#include "Tuples/Tuples.h"
    6051
    6152using namespace std;
     
    215206                                FILE * builtins = fopen( libcfap | treep ? "../prelude/builtins.cf" : CFA_LIBDIR "/builtins.cf", "r" );
    216207                                assertf( builtins, "cannot open builtins.cf\n" );
    217                                 parse( builtins, LinkageSpec::BuiltinCFA );
     208                                parse( builtins, LinkageSpec::Builtin );
    218209                        } // if
    219210                } // if
  • src/prelude/Makefile.in

    r3d4b23fa r55a68c3  
    294294          esac; \
    295295        done; \
    296         echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/prelude/Makefile'; \
     296        echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/prelude/Makefile'; \
    297297        $(am__cd) $(top_srcdir) && \
    298           $(AUTOMAKE) --foreign src/prelude/Makefile
     298          $(AUTOMAKE) --gnu src/prelude/Makefile
    299299Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    300300        @case '$?' in \
  • src/tests/.expect/32/math.txt

    r3d4b23fa r55a68c3  
    2222cos:0.540302 0.54030230586814 0.540302305868139717 0.83373-0.988898i 0.833730025131149-0.988897705762865i 0.833730025131149049-0.988897705762865096i
    2323tan:1.55741 1.5574077246549 1.55740772465490223 0.271753+1.08392i 0.271752585319512+1.08392332733869i 0.271752585319511717+1.08392332733869454i
    24 asin:1.5708 1.5707963267949 1.57079632679489662 0.666239+1.06128i 0.666239432492515+1.06127506190504i 0.666239432492515255+1.06127506190503565i
     24asin:1.5708 1.5707963267949 1.57079632679489662 0.66624+1.06128i 0.666239432492515+1.06127506190504i 0.666239432492515255+1.06127506190503565i
    2525acos:0 0 0 0.904557-1.06128i 0.904556894302381-1.06127506190504i 0.904556894302381364-1.06127506190503565i
    2626atan:0.785398 0.785398163397448 0.78539816339744831 1.01722+0.402359i 1.01722196789785+0.402359478108525i 1.01722196789785137+0.402359478108525094i
  • src/tests/.expect/concurrent/sched-int-disjoint.txt

    r3d4b23fa r55a68c3  
    999000
    101010000
     1111000
     1212000
     1313000
     1414000
     1515000
     1616000
     1717000
     1818000
     1919000
     2020000
     2121000
     2222000
     2323000
     2424000
     2525000
     2626000
     2727000
     2828000
     2929000
     3030000
     3131000
     3232000
     3333000
     3434000
     3535000
     3636000
     3737000
     3838000
     3939000
     4040000
     4141000
     4242000
     4343000
     4444000
     4545000
     4646000
     4747000
     4848000
     4949000
     5050000
     5151000
     5252000
     5353000
     5454000
     5555000
     5656000
     5757000
     5858000
     5959000
     6060000
     6161000
     6262000
     6363000
     6464000
     6565000
     6666000
     6767000
     6868000
     6969000
     7070000
     7171000
     7272000
     7373000
     7474000
     7575000
     7676000
     7777000
     7878000
     7979000
     8080000
     8181000
     8282000
     8383000
     8484000
     8585000
     8686000
     8787000
     8888000
     8989000
     9090000
     9191000
     9292000
     9393000
     9494000
     9595000
     9696000
     9797000
     9898000
     9999000
     100100000
    11101All waiter done
  • src/tests/.expect/io.txt

    r3d4b23fa r55a68c3  
    44123
    55
    6 opening delimiters
     6opening delimiters 
    77x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10
    88
    9 closing delimiters
    10 1, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x
     9closing delimiters 
     101, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x 
    1111
    12 opening/closing delimiters
     12opening/closing delimiters 
    1313x`1`x'2'x"3"x:4:x 5 x   6       x
    14147
     
    1919x
    202010
    21 x
     21x 
    2222
    23 override opening/closing delimiters
     23override opening/closing delimiters 
    2424x ( 1 ) x 2 , x 3 :x: 4
    2525
    26 input bacis types
     26input bacis types 
    2727
    28 output basic types
     28output basic types 
    2929A
    30301 2 3 4 5 6 7 8
     
    32321.1+2.3i 1.1-2.3i 1.1-2.3i
    3333
    34 tuples
    35 1, 2, 3 4, 5, 6
     34tuples 
     351, 2, 3 3, 4, 5
    3636
    37 toggle separator
     37toggle separator 
    38381.11.21.3
    39391.1+2.3i1.1-2.3i1.1-2.3i
    40 1.1+2.3i 1.1-2.3i1.1-2.3i
    41 1.1+2.3i 1.1-2.3i 1.1-2.3i
    42 1.1+2.3i1.1-2.3i 1.1-2.3i
    43 abcxyz
    44 abcxyz
     40 abcxyz
     41abcxyz
    4542
    46 change separator
    47 from " " to ", $"
     43change separator 
     44from "  "to " , $"
    48451.1, $1.2, $1.3
    49461.1+2.3i, $1.1-2.3i, $1.1-2.3i
    50 abc, $xyz
    51 1, 2, 3, $4, 5, 6
     47abc, $xyz, $
     481, 2, 3, $3, 4, 5
    5249
    53 from ", $" to " "
     50from ", $"to " "
    54511.1 1.2 1.3
    55521.1+2.3i 1.1-2.3i 1.1-2.3i
    56 abc xyz
    57 1, 2, 3 4, 5, 6
     53abc xyz 
     541, 2, 3 3, 4, 5
    5855
    59 check sepOn/sepOff
     56 1 2 3
     5712 3
     58 1 2 3
    60591 2 3
    61 12 3
    62 1 2 3
    63 1 2 3
     60 1 2 3
    6461
    65 1 2 3
    66 
    67 check enable/disable
    6862123
    69631 23
     
    7165123
    72661 2 3
    73 123
     67123 
    74681 2 3
    7569
    76 1 2 3 4 5 6 " "
    77 1, 2, 3 4, 5, 6 " "
    78 1, 2, 3 4, 5, 6
     701 2 3 3 4 5 " "
     711, 2, 3 3, 4, 5 ", "
     721, 2, 3 3, 4, 5
    7973
    80743, 4, a, 7.2
    81753, 4, a, 7.2
    82763 4 a 7.2
    83 3 4 a 7.234a7.23 4 a 7.2
     77 3 4 a 7.234a7.23 4 a 7.2
    84783-4-a-7.2^3^4^3-4-a-7.2
  • src/tests/Makefile.am

    r3d4b23fa r55a68c3  
    2929
    3030# applies to both programs
    31 DEBUG_FLAGS =
    32 
    33 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@
    34 if !BUILD_DEBUG
    35 BUILD_FLAGS += -nodebug
    36 else
    37 if !BUILD_RELEASE
    38 BUILD_FLAGS += -debug
    39 else
    40 BUILD_FLAGS += ${DEBUG_FLAGS}
    41 endif
    42 endif
    43 
     31EXTRA_FLAGS =
     32BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ ${EXTRA_FLAGS}
    4433TEST_FLAGS = $(if $(test), 2> .err/${@}.log, )
    4534AM_CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS}
  • src/tests/Makefile.in

    r3d4b23fa r55a68c3  
    9292host_triplet = @host@
    9393@BUILD_CONCURRENCY_TRUE@am__append_1 = coroutine thread monitor
    94 @BUILD_DEBUG_FALSE@am__append_2 = -nodebug
    95 @BUILD_DEBUG_TRUE@@BUILD_RELEASE_FALSE@am__append_3 = -debug
    96 @BUILD_DEBUG_TRUE@@BUILD_RELEASE_TRUE@am__append_4 = ${DEBUG_FLAGS}
    9794EXTRA_PROGRAMS = fstream_test$(EXEEXT) vector_test$(EXEEXT) \
    9895        avl_test$(EXEEXT)
     
    323320
    324321# applies to both programs
    325 DEBUG_FLAGS =
    326 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ \
    327         $(am__append_2) $(am__append_3) $(am__append_4)
     322EXTRA_FLAGS =
     323BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ ${EXTRA_FLAGS}
    328324TEST_FLAGS = $(if $(test), 2> .err/${@}.log, )
    329325AM_CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS}
     
    347343          esac; \
    348344        done; \
    349         echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tests/Makefile'; \
     345        echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tests/Makefile'; \
    350346        $(am__cd) $(top_srcdir) && \
    351           $(AUTOMAKE) --foreign src/tests/Makefile
     347          $(AUTOMAKE) --gnu src/tests/Makefile
    352348Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    353349        @case '$?' in \
  • src/tests/io.c

    r3d4b23fa r55a68c3  
    1010// Created On       : Wed Mar  2 16:56:02 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul  6 23:26:12 2017
    13 // Update Count     : 78
     12// Last Modified On : Sun Jul  2 09:40:58 2017
     13// Update Count     : 68
    1414//
    1515
     
    104104
    105105        sout | "tuples" | endl;
    106         [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
     106        [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
    107107        sout | t1 | t2 | endl;                                                          // print tuple
    108108        sout | endl;
     
    110110        sout | "toggle separator" | endl;
    111111        sout | f | "" | d | "" | ld | endl                                      // floating point without separator
    112                 | sepDisable | fc | dc | ldc | endl                             // complex without separator
    113                 | fc | sepOn | dc | ldc | endl                                  // local separator add
    114                 | sepEnable | fc | dc | ldc | endl                              // complex with separator
    115                 | fc | sepOff | dc | ldc | endl                                 // local separator removal
    116                 | s1 | sepOff | s2 | endl                                               // local separator removal
    117                 | s1 | "" | s2 | endl;                                                  // local separator removal
     112                | sepDisable | fc | dc | ldc | sepEnable | endl // complex without separator
     113                | sepOn | s1 | sepOff | s2 | endl                               // local separator removal
     114                | s1 | "" | s2 | endl;                                                  // C string without separator
    118115        sout | endl;
    119116
    120117        sout | "change separator" | endl;
    121         sout | "from \"" | sep | "\"";
     118        sout | "from \" " | sepGet( sout ) | "\"";
    122119        sepSet( sout, ", $" );                                                          // change separator, maximum of 15 characters
    123         sout | " to \"" | sep | "\"" | endl;
     120        sout | "to \" " | sepGet( sout ) | "\"" | endl;
    124121        sout | f | d | ld | endl
    125122                | fc | dc | ldc | endl
     
    127124                | t1 | t2 | endl;                                                               // print tuple
    128125        sout | endl;
    129         sout | "from \"" | sep | "\" ";
     126        sout | "from \"" | sepGet( sout ) | "\"";
    130127        sepSet( sout, " " );                                                            // restore separator
    131         sout | "to \"" | sep | "\"" | endl;
     128        sout | "to \"" | sepGet( sout ) | "\"" | endl;
    132129        sout | f | d | ld | endl
    133130                | fc | dc | ldc | endl
     
    136133        sout | endl;
    137134
    138         sout | "check sepOn/sepOff" | endl;
    139         sout | sepOn | 1 | 2 | 3 | sepOn | endl;                        // no separator at start/end of line
     135        sout | sepOn | 1 | 2 | 3 | sepOn | endl;                        // separator at start/end of line
    140136        sout | 1 | sepOff | 2 | 3 | endl;                                       // locally turn off implicit separator
    141         sout | sepOn | sepOn | 1 | 2 | 3 | sepOn | sepOff | sepOn | '\n'; // no separator at start/end of line
    142         sout | 1 | 2 | 3 | "\n\n" | sepOn;                                      // no separator at start of next line
     137        sout | sepOn | 1 | 2 | 3 | sepOn | sepOff | endl;       // separator at start of line
     138        sout | 1 | 2 | 3 | endl | sepOn;                                        // separator at start of next line
    143139        sout | 1 | 2 | 3 | endl;
    144140        sout | endl;
    145141
    146         sout | "check enable/disable" | endl;
    147142        sout | sepDisable | 1 | 2 | 3 | endl;                           // globally turn off implicit separation
    148143        sout | 1 | sepOn | 2 | 3 | endl;                                        // locally turn on implicit separator
     
    154149        sout | endl;
    155150
    156 //      sout | fmt( d, "%8.3f" ) || endl;
    157 //      sout | endl;
    158 
    159151        sepSetTuple( sout, " " );                                                       // set tuple separator from ", " to " "
    160         sout | t1 | t2 | " \"" | sep | "\"" | endl;
     152        sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
    161153        sepSetTuple( sout, ", " );                                                      // reset tuple separator to ", "
    162         sout | t1 | t2 | " \"" | sep | "\"" | endl;
     154        sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
    163155        sout | t1 | t2 | endl;                                                          // print tuple
    164156        sout | endl;
  • src/tests/preempt_longrun/Makefile.am

    r3d4b23fa r55a68c3  
    1010## Author           : Thierry Delisle
    1111## Created On       : Fri Jun 16 10:57:34 2017
    12 ## Last Modified By :
    13 ## Last Modified On :
     12## Last Modified By : 
     13## Last Modified On : 
    1414## Update Count     : 0
    1515###############################################################################
    1616
    1717repeats=10
    18 max_time=600
    19 preempt=1_000ul
     18max_time=30
     19preempt=10_000ul
    2020
    2121REPEAT = ${abs_top_srcdir}/tools/repeat -s
     
    2525CC = @CFA_BINDIR@/@CFA_NAME@
    2626
    27 TESTS = barge block create disjoint enter enter3 processor stack wait yield
     27TESTS = barge block create disjoint processor stack wait yield
    2828
    2929.INTERMEDIATE: ${TESTS}
  • src/tests/preempt_longrun/Makefile.in

    r3d4b23fa r55a68c3  
    449449top_srcdir = @top_srcdir@
    450450repeats = 10
    451 max_time = 600
    452 preempt = 1_000ul
     451max_time = 30
     452preempt = 10_000ul
    453453REPEAT = ${abs_top_srcdir}/tools/repeat -s
    454454BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -debug -O2 -DPREEMPTION_RATE=${preempt}
    455 TESTS = barge block create disjoint enter enter3 processor stack wait yield
     455TESTS = barge block create disjoint processor stack wait yield
    456456all: all-am
    457457
     
    467467          esac; \
    468468        done; \
    469         echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tests/preempt_longrun/Makefile'; \
     469        echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tests/preempt_longrun/Makefile'; \
    470470        $(am__cd) $(top_srcdir) && \
    471           $(AUTOMAKE) --foreign src/tests/preempt_longrun/Makefile
     471          $(AUTOMAKE) --gnu src/tests/preempt_longrun/Makefile
    472472Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    473473        @case '$?' in \
     
    663663        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
    664664        "$$tst" $(AM_TESTS_FD_REDIRECT)
    665 enter.log: enter
    666         @p='enter'; \
    667         b='enter'; \
    668         $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
    669         --log-file $$b.log --trs-file $$b.trs \
    670         $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
    671         "$$tst" $(AM_TESTS_FD_REDIRECT)
    672 enter3.log: enter3
    673         @p='enter3'; \
    674         b='enter3'; \
    675         $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
    676         --log-file $$b.log --trs-file $$b.trs \
    677         $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
    678         "$$tst" $(AM_TESTS_FD_REDIRECT)
    679665processor.log: processor
    680666        @p='processor'; \
  • src/tests/preempt_longrun/create.c

    r3d4b23fa r55a68c3  
    1010}
    1111
    12 thread worker_t {};
     12thread Worker {};
    1313
    14 void main(worker_t * this) {}
     14void main(Worker * this) {}
    1515
    1616int main(int argc, char* argv[]) {
    17         processor p;
    18         for(int i = 0; i < 10_000ul; i++) {
    19                 worker_t w[7];
     17        for(int i = 0; i < 100_000ul; i++) {
     18                Worker w;
    2019        }
    2120}
  • src/tests/preempt_longrun/processor.c

    r3d4b23fa r55a68c3  
    1010}
    1111
    12 thread worker_t {};
     12thread Worker {};
    1313
    14 void main(worker_t * this) {}
     14void main(Worker * this) {}
    1515
    1616int main(int argc, char* argv[]) {
    17         for(int i = 0; i < 10_000ul; i++) {
     17        for(int i = 0; i < 100_000ul; i++) {
    1818                processor p;
    1919        }
  • src/tests/preempt_longrun/stack.c

    r3d4b23fa r55a68c3  
    1212}
    1313
    14 thread worker_t {};
     14thread Worker {};
    1515
    16 void main(worker_t * this) {
     16void main(Worker * this) {
    1717        volatile long p = 5_021_609ul;
    1818        volatile long a = 326_417ul;
    1919        volatile long n = 1l;
    20         for (volatile long i = 0; i < p; i++) {
    21                 n *= a;
    22                 n %= p;
     20        for (volatile long i = 0; i < p; i++) { 
     21                n *= a; 
     22                n %= p; 
    2323        }
    24 
     24               
    2525        if( n != a ) {
    2626                abort();
     
    2828}
    2929
    30 extern "C" {
    31 static worker_t * workers;
    32 }
    33 
    3430int main(int argc, char* argv[]) {
    3531        processor p;
    3632        {
    37                 worker_t w[7];
    38                 workers = w;
     33                Worker w[7];
    3934        }
    4035}
  • src/tests/preempt_longrun/yield.c

    r3d4b23fa r55a68c3  
    1010}
    1111
    12 thread worker_t {};
     12thread Worker {};
    1313
    14 void main(worker_t * this) {
    15         for(int i = 0; i < 325_000ul; i++) {
     14void main(Worker * this) {
     15        for(int i = 0; i < 100_000ul; i++) {
    1616                yield();
    1717        }
    18 }
    19 
    20 extern "C" {
    21 static worker_t * workers;
    2218}
    2319
     
    2521        processor p;
    2622        {
    27                 worker_t w[7];
    28                 workers = w;
     23                Worker w[7];
    2924        }
    3025}
  • src/tests/sched-int-block.c

    r3d4b23fa r55a68c3  
    66
    77#ifndef N
    8 #define N 10_000
     8#define N 100_000
    99#endif
    1010
     
    3131//------------------------------------------------------------------------------
    3232void wait_op( global_data_t * mutex a, global_data_t * mutex b, unsigned i ) {
    33         wait( &cond, (uintptr_t)this_thread );
     33        wait( &cond, (uintptr_t)this_thread() );
    3434
    3535        yield( ((unsigned)rand48()) % 10 );
     
    4040        }
    4141
    42         a->last_thread = b->last_thread = this_thread;
     42        a->last_thread = b->last_thread = this_thread();
    4343
    4444        yield( ((unsigned)rand48()) % 10 );
     
    5656        yield( ((unsigned)rand48()) % 10 );
    5757
    58         a->last_thread = b->last_thread = a->last_signaller = b->last_signaller = this_thread;
     58        a->last_thread = b->last_thread = a->last_signaller = b->last_signaller = this_thread();
    5959
    6060        if( !is_empty( &cond ) ) {
     
    8686//------------------------------------------------------------------------------
    8787void barge_op( global_data_t * mutex a ) {
    88         a->last_thread = this_thread;
     88        a->last_thread = this_thread();
    8989}
    9090
  • src/tests/sched-int-disjoint.c

    r3d4b23fa r55a68c3  
    55
    66#ifndef N
    7 #define N 10_000
     7#define N 100_000
    88#endif
    99
     
    4242
    4343void main( Barger * this ) {
    44         while( !all_done ) {
     44        while( !all_done ) { 
    4545                barge( &data );
    46                 yield();
     46                yield(); 
    4747        }
    4848}
     
    5353        wait( &cond );
    5454        if( d->state != SIGNAL ) {
    55                 sout | "ERROR barging!" | endl;
     55                sout | "ERROR barging!" | endl; 
    5656        }
    5757
     
    8585        bool running = data.counter < N && data.counter > 0;
    8686        if( data.state != SIGNAL && running ) {
    87                 sout | "ERROR Eager signal" | data.state | endl;
     87                sout | "ERROR Eager signal" | data.state | endl; 
    8888        }
    8989}
     
    9292
    9393void main( Signaller * this ) {
    94         while( !all_done ) {
     94        while( !all_done ) { 
    9595                logic( &mut );
    96                 yield();
     96                yield(); 
    9797        }
    9898}
     
    111111                sout | "All waiter done" | endl;
    112112                all_done = true;
    113         }
     113        }       
    114114}
  • src/tests/sched-int-wait.c

    r3d4b23fa r55a68c3  
    5050                unsigned action = (unsigned)rand48() % 4;
    5151                switch( action ) {
    52                         case 0:
     52                        case 0: 
    5353                                signal( &condABC, &globalA, &globalB, &globalC );
    5454                                break;
    55                         case 1:
     55                        case 1: 
    5656                                signal( &condAB , &globalA, &globalB );
    5757                                break;
    58                         case 2:
     58                        case 2: 
    5959                                signal( &condBC , &globalB, &globalC );
    6060                                break;
    61                         case 3:
     61                        case 3: 
    6262                                signal( &condAC , &globalA, &globalC );
    6363                                break;
     
    6767                }
    6868                yield();
    69         }
     69        }       
    7070}
    7171
  • src/tests/test.py

    r3d4b23fa r55a68c3  
    166166
    167167        # build, skipping to next test on error
    168         make_ret, _ = sh("""%s test=yes DEBUG_FLAGS="%s" %s 2> %s 1> /dev/null""" % (make_cmd, options, test.name, out_file), dry_run)
     168        make_ret, _ = sh("""%s test=yes EXTRA_FLAGS="%s" %s 2> %s 1> /dev/null""" % (make_cmd, options, test.name, out_file), dry_run)
    169169
    170170        retcode = 0
     
    202202                        error = myfile.read()
    203203
    204 
     204               
    205205        # clean the executable
    206206        sh("rm -f %s > /dev/null 2>&1" % test.name, dry_run)
  • src/tests/thread.c

    r3d4b23fa r55a68c3  
    44#include <thread>
    55
    6 thread First  { semaphore* lock; };
    7 thread Second { semaphore* lock; };
     6// thread First;
     7// void main(First* this);
    88
    9 void ?{}( First * this, semaphore* lock ) { this->lock = lock; }
    10 void ?{}( Second * this, semaphore* lock ) { this->lock = lock; }
     9// thread Second;
     10// void main(Second* this);
     11
     12thread First  { signal_once* lock; };
     13thread Second { signal_once* lock; };
     14
     15void ?{}( First * this, signal_once* lock ) { this->lock = lock; }
     16void ?{}( Second * this, signal_once* lock ) { this->lock = lock; }
    1117
    1218void main(First* this) {
     
    1521                yield();
    1622        }
    17         V(this->lock);
     23        signal(this->lock);
    1824}
    1925
    2026void main(Second* this) {
    21         P(this->lock);
     27        wait(this->lock);
    2228        for(int i = 0; i < 10; i++) {
    2329                sout | "Second : Suspend No." | i + 1 | endl;
     
    2834
    2935int main(int argc, char* argv[]) {
    30         semaphore lock = { 0 };
     36        signal_once lock;
    3137        sout | "User main begin" | endl;
    3238        {
  • tools/prettyprinter/Makefile.in

    r3d4b23fa r55a68c3  
    350350          esac; \
    351351        done; \
    352         echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tools/prettyprinter/Makefile'; \
     352        echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/prettyprinter/Makefile'; \
    353353        $(am__cd) $(top_srcdir) && \
    354           $(AUTOMAKE) --foreign tools/prettyprinter/Makefile
     354          $(AUTOMAKE) --gnu tools/prettyprinter/Makefile
    355355Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    356356        @case '$?' in \
Note: See TracChangeset for help on using the changeset viewer.