Changes in / [55a68c3:3d4b23fa]


Ignore:
Files:
5 added
25 deleted
100 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/common.tex

    r55a68c3 r3d4b23fa  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sun Jun 18 20:32:32 2017
    14 %% Update Count     : 319
     13%% Last Modified On : Thu Jul 13 11:44:59 2017
     14%% Update Count     : 335
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    3636% Names used in the document.
    3737
    38 \newcommand{\CFAIcon}{\textrm{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}\xspace} % Cforall symbolic name
     38\newcommand{\CFAIcon}{\textsf{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
    5760\newlength{\gcolumnposn}                                % temporary hack because lstlisting does not handle tabs correctly
    5861\newlength{\columnposn}
    5962\setlength{\gcolumnposn}{2.5in}
    6063\setlength{\columnposn}{\gcolumnposn}
    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}}}
     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}}}}
    6265\newcommand{\CRT}{\global\columnposn=\gcolumnposn}
    6366
     
    231234basicstyle=\linespread{0.9}\sf,                                                 % reduce line spacing and use sanserif font
    232235stringstyle=\tt,                                                                                % use typewriter font
    233 tabsize=4,                                                                                              % 4 space tabbing
     236tabsize=6,                                                                                              % N space tabbing
    234237xleftmargin=\parindentlnth,                                                             % indent code to paragraph indentation
    235238extendedchars=true,                                                                             % allow ASCII characters in the range 128-255
  • doc/LaTeXmacros/lstlang.sty

    r55a68c3 r3d4b23fa  
    88%% Created On       : Sat May 13 16:34:42 2017
    99%% Last Modified By : Peter A. Buhr
    10 %% Last Modified On : Thu Jun 22 07:40:31 2017
    11 %% Update Count     : 10
     10%% Last Modified On : Wed Jul 12 22:42:09 2017
     11%% Update Count     : 12
    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__, zero_t},
     114                __typeof__, with, 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++}{}
    120123
    121124% uC++ programming language, based on ANSI C++
  • doc/bibliography/cfa.bib

    r55a68c3 r3d4b23fa  
    22732273@manual{JavaScript,
    22742274    keywords    = {JavaScript},
    2275     contributer = {pabuhr},
     2275    contributer = {pabuhr@plg},
    22762276    title       = {ECMAScript 2015 Language Specification {JavaScript}},
    22772277    organization= {ECAM International},
     
    24462446@manual{Erlang,
    24472447    keywords    = {Erlang},
    2448     contributer = {pabuhr},
     2448    contributer = {pabuhr@plg},
    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},
    27732786}
    27742787
     
    50525065    contributer = {pabuhr@plg},
    50535066    author      = {Kathleen Jensen and Niklaus Wirth},
    5054     title       = {{P}ascal User Manual and Report},
     5067    title       = {{P}ascal User Manual and Report, ISO Pascal Standard},
    50555068    publisher   = {Springer--Verlag},
    5056     year        = 1985,
    5057     edition     = {3rd},
    5058     note        = {Revised by Andrew B. Mickel and James F. Miner, ISO Pascal Standard}
     5069    year        = 1991,
     5070    edition     = {4th},
     5071    note        = {Revised by Andrew B. Mickel and James F. Miner}
    50595072}
    50605073
  • doc/proposals/tagged-struct.txt

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

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

    r55a68c3 r3d4b23fa  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sun Jul  2 09:49:56 2017
    14 %% Update Count     : 2503
     13%% Last Modified On : Thu Jul 13 11:44:57 2017
     14%% Update Count     : 2690
    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
    5963% inline code ©...© (copyright symbol) emacs: C-q M-)
    6064% red highlighting ®...® (registered trademark symbol) emacs: C-q M-.
     
    137141
    138142\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.
    139 The syntax of the \CFA language builds from C, and should look immediately familiar to C/\Index*[C++]{\CC{}} programmers.
     143The syntax of \CFA builds from C and should look immediately familiar to C/\Index*[C++]{\CC{}} programmers.
    140144% Any language feature that is not described here can be assumed to be using the standard \Celeven syntax.
    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.
    142 Like 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.
     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.
     146Like 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.
    143147The primary new features include parametric-polymorphic routines and types, exceptions, concurrency, and modules.
    144148
    145 One 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''.
    146 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 features.
    147 A 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.
    148 There is no notion or requirement for rewriting a legacy C program in \CFA;
    149 instead, a programmer evolves an existing C program into \CFA by incrementally incorporating \CFA features.
    150 New 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.
     149One 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''.
     150Programmers can cautiously add \CFA extensions to their C programs in any order and at any time to incrementally move towards safer, higher-level programming.
     151A 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.
     152There is no notion or requirement for \emph{rewriting} a legacy C program in \CFA;
     153instead, a programmer evolves a legacy program into \CFA by incrementally incorporating \CFA features.
     154As 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.
     157However, \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.
    152158In contrast, \CFA has 30 years of hindsight and a clean starting point.
    153159
     
    156162\begin{quote2}
    157163\begin{tabular}{@{}l@{\hspace{1.5em}}l@{\hspace{1.5em}}l@{}}
    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 
    162 int main( void ) {
    163         int x = 0, y = 1, z = 2;
    164         ®sout | x | y | z | endl;®
    165 }
    166 \end{cfa}
    167 &
    168 \begin{lstlisting}
     164\multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{\CC}}      \\
     165\begin{cfa}
    169166#include <stdio.h>§\indexc{stdio.h}§
    170167
     
    173170        ®printf( "%d %d %d\n", x, y, z );®
    174171}
    175 \end{lstlisting}
     172\end{cfa}
    176173&
    177 \begin{lstlisting}
     174\begin{cfa}
     175#include <fstream>§\indexc{fstream}§
     176
     177int 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}
    178184#include <iostream>§\indexc{iostream}§
    179185using namespace std;
     
    182188        ®cout<<x<<" "<<y<<" "<<z<<endl;®
    183189}
    184 \end{lstlisting}
     190\end{cfa}
    185191\end{tabular}
    186192\end{quote2}
    187193While 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}).
    188194
     195\subsection{Background}
     196
    189197This document is a programmer reference-manual for the \CFA programming language.
    190198The manual covers the core features of the language and runtime-system, with simple examples illustrating syntax and semantics of each feature.
    191199The manual does not teach programming, i.e., how to combine the new constructs to build complex programs.
    192 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.
    193 Implementers may refer to the \CFA Programming Language Specification for details about the language syntax and semantics.
     200A 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.
     201Implementers should refer to the \CFA Programming Language Specification for details about the language syntax and semantics.
    194202Changes to the syntax and additional features are expected to be included in later revisions.
    195203
     
    200208This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more.
    201209Even with all its problems, C continues to be popular because it allows writing software at virtually any level in a computer system without restriction.
    202 For system programming, where direct access to hardware and dealing with real-time issues is a requirement, C is usually the language of choice.
     210For system programming, where direct access to hardware, storage management, and real-time issues are a requirement, C is usually the only language of choice.
    203211The 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.
    204212As well, for 30 years, C has been the number 1 and 2 most popular programming language:
     
    216224\end{center}
    217225Hence, 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.
    218 Love it or hate it, C has been an important and influential part of computer science for 40 years and sit appeal is not diminishing.
    219 Unfortunately, C has too many problems and omissions to make it an acceptable programming language for modern needs.
    220 
    221 As stated, the goal of the \CFA project is to engineer modern language features into C in an evolutionary rather than revolutionary way.
     226Love it or hate it, C has been an important and influential part of computer science for 40 years and its appeal is not diminishing.
     227Unfortunately, C has many problems and omissions that make it an unacceptable programming language for modern needs.
     228
     229As stated, the goal of the \CFA project is to engineer modern language-features into C in an evolutionary rather than revolutionary way.
    222230\CC~\cite{C++14,C++} is an example of a similar project;
    223 however, it largely extended the language, and did not address many existing problems.\footnote{%
     231however, it largely extended the C language, and did not address most of C's existing problems.\footnote{%
    224232Two 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.}
    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.
     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.
    226234\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.
    227 These languages have different syntax and semantics from C, and do not interoperate directly with C, largely because of garbage collection.
     235These 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.
    228236As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten.
    229 These 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 
    231 The 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.
     237These 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
     239The 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.
    232240Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers;
    233241as a result, it will fade into disuse.
    234242Considering the large body of existing C code and programmers, there is significant impetus to ensure C is transformed into a modern programming language.
    235 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.
    236 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.
     243While \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.
     244While 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.
    237245
    238246
    239247\section{History}
    240248
    241 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 extended assignment capabilities using the notion of tuples.
     249The \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.
    242250(See~\cite{Werther96} for similar work in \Index*[C++]{\CC{}}.)
    243 A first \CFA implementation of these extensions was by Esteves~\cite{Esteves04}.
    244 The 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):
     251The first \CFA implementation of these extensions was by Esteves~\cite{Esteves04}.
     252
     253The 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):
    245254\begin{lstlisting}
    246255®forall( otype T )® T identity( T val ) { return val; }
     
    250259\CFA{}\hspace{1pt}'s polymorphism was originally formalized by Ditchfiled~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}.
    251260However, at that time, there was little interesting in extending C, so work did not continue.
    252 As 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.
     261As 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.
    253262
    254263
     
    257266
    258267\CFA is designed to integrate directly with existing C programs and libraries.
    259 The most important feature of \Index{interoperability} is using the same \Index{calling convention}s, so there is no overhead to call existing C routines.
     268The 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.
    260269This feature allows \CFA programmers to take advantage of the existing panoply of C libraries to access thousands of external software features.
    261270Language developers often state that adequate \Index{library support} takes more work than designing and implementing the language itself.
    262271Fortunately, \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.
    263 Hence, \CFA begins by leveraging the large repository of C libraries with little cost.
     272Hence, \CFA begins by leveraging the large repository of C libraries at little cost.
    264273
    265274\begin{comment}
     
    304313\end{comment}
    305314
    306 However, it is necessary to differentiate between C and \CFA code because of name overloading, as for \CC.
     315However, it is necessary to differentiate between C and \CFA code because of name \Index{overload}ing, as for \CC.
    307316For 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©.
    308 Whereas, \CFA wraps each of these routines into ones with the common name ©abs©:
     317Whereas, \CFA wraps each of these routines into ones with the overloaded name ©abs©:
    309318\begin{cfa}
    310319char abs( char );
     
    326335Hence, 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.
    327336There is no way around this problem, other than C's approach of creating unique names for each pairing of operation and type.
    328 This example strongly illustrates a core idea in \CFA: \emph{the power of a name}.
     337This example strongly illustrates a core idea in \CFA: \emph{the \Index{power of a name}}.
    329338The name ``©abs©'' evokes the notion of absolute value, and many mathematical types provide the notion of absolute value.
    330 Hence, knowing the name ©abs© should be sufficient to apply it to any type where it is applicable.
    331 The 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}
     339Hence, knowing the name ©abs© is sufficient to apply it to any type where it is applicable.
     340The 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}
    335344
    336345The command ©cfa© is used to compile \CFA program(s), and is based on the GNU \Indexc{gcc} command, \eg:
    337346\begin{cfa}
    338 cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA§-files [ assembler/loader-files ]
     347cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA{}§-files [ assembler/loader-files ]
    339348\end{cfa}
    340349\CFA programs having the following ©gcc© flags turned on:
     
    359368\Indexc{-debug}\index{compilation option!-debug@©-debug©}
    360369The program is linked with the debugging version of the runtime system.
    361 The debug version performs runtime checks to help during the debugging phase of a \CFA program, but substantially slows the execution of the program.
     370The debug version performs runtime checks to help during the debugging phase of a \CFA program, but can substantially slow program execution.
    362371The runtime checks should only be removed after the program is completely debugged.
    363372\textbf{This option is the default.}
     
    415424\end{description}
    416425These preprocessor variables allow conditional compilation of programs that must work differently in these situations.
    417 For example, to toggle between C and \CFA extensions, using the following:
     426For example, to toggle between C and \CFA extensions, use the following:
    418427\begin{cfa}
    419428#ifndef __CFORALL__
     
    426435
    427436
    428 \section{Constants Underscores}
    429 
    430 Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, \eg:
     437\section{Constant Underscores}
     438
     439Numeric constants are extended to allow \Index{underscore}s\index{constant!underscore}, \eg:
    431440\begin{cfa}
    4324412®_®147®_®483®_®648;                                    §\C{// decimal constant}§
     
    441450L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§;     §\C{// wide character constant}§
    442451\end{cfa}
    443 The rules for placement of underscores is as follows:
    444 \begin{enumerate}
     452The rules for placement of underscores are:
     453\begin{enumerate}[topsep=5pt,itemsep=5pt,parsep=0pt]
    445454\item
    446455A sequence of underscores is disallowed, \eg ©12__34© is invalid.
     
    463472\label{s:BackquoteIdentifiers}
    464473
    465 \CFA accommodates keyword clashes with existing C variable-names by syntactic transformations using the \CFA backquote escape-mechanism:
     474\CFA introduces in new keywords (see \VRef{s:CFAKeywords}) that can clash with existing C variable-names in legacy code.
     475Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism:
    466476\begin{cfa}
    467477int ®`®otype®`® = 3;                    §\C{// make keyword an identifier}§
     
    491501
    492502
    493 \section{Labelled Continue/Break}
     503\section{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break}}{Labelled continue / break}}
    494504
    495505While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure.
    496506Unfortunately, this restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting.
    497 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,Java}.
     507To 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}.
    498508For both ©continue© and ©break©, the target label must be directly associated with a ©for©, ©while© or ©do© statement;
    499509for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement.
    500510\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©.
    501511The innermost loop has 7 exit points, which cause resumption or termination of one or more of the 7 \Index{nested control-structure}s.
     512Java supports both labelled ©continue© and ©break© statements.
    502513
    503514\begin{figure}
     
    622633
    623634
    624 \section{Switch Statement}
     635\section{\texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}}
    625636
    626637C allows a number of questionable forms for the ©switch© statement:
     
    663674        ®// open input file
    664675®} else if ( argc == 2 ) {
    665         ®// open input file
     676        ®// open input file (duplicate)
    666677
    667678®} else {
     
    676687\begin{cfa}
    677688switch ( i ) {
    678   case 1: case 3: case 5:       // odd values
    679         // same action
     689  ®case 1: case 3: case 5:®     // odd values
     690        // odd action
    680691        break;
    681   case 2: case 4: case 6:       // even values
    682         // same action
     692  ®case 2: case 4: case 6:®     // even values
     693        // even action
    683694        break;
    684695}
     
    686697However, this situation is handled in other languages without fall-through by allowing a list of case values.
    687698While 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.
    688 Hence, 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.
     699Hence, 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.
    689700
    690701\item
     
    770781and 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.
    771782\end{itemize}
    772 These observations help to put the \CFA changes to the ©switch© into perspective.
     783These observations put into perspective the \CFA changes to the ©switch©.
    773784\begin{enumerate}
    774785\item
     
    791802  case 7:
    792803        ...
    793         ®break®                                         §\C{// explicit end of switch}§
     804        ®break®                                         §\C{// redundant explicit end of switch}§
    794805  default:
    795806        j = 3;
     
    797808\end{cfa}
    798809Like the ©switch© statement, the ©choose© statement retains the fall-through semantics for a list of ©case© clauses;
    799 the implicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause.
    800 The 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.
     810An implicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause.
     811An 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.
    801812As well, allowing an explicit ©break© from the ©choose© is a carry over from the ©switch© statement, and expected by C programmers.
    802813\item
     
    827838
    828839
    829 \section{Case Clause}
     840\section{\texorpdfstring{\LstKeywordStyle{case} Clause}{case Clause}}
    830841
    831842C restricts the ©case© clause of a ©switch© statement to a single value.
     
    900911\begin{cfa}
    901912case ®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
     919In \Index{object-oriented} programming, there is an implicit first parameter, often names \textbf{©self©} or \textbf{©this©}, which is elided.
     920\begin{C++}
     921class 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++}
     929Since CFA is non-object-oriented, the equivalent object-oriented program looks like:
     930\begin{cfa}
     931struct C {
     932        int i, j;
     933};
     934int mem( C &this ) {    // explicit "this" parameter
     935        ®this.®i = 1;                     // "this" is not elided
     936        ®this.®j = 2;
     937}
     938\end{cfa}
     939but 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}
     942int mem( C &this ) ®with this® {
     943        i = 1;                  ®// this.i
     944®       j = 2;                  ®// this.j
     945®}
     946\end{cfa}
     947which extends to multiple routine parameters:
     948\begin{cfa}
     949struct D {
     950        double m, n;
     951};
     952int mem2( C &this1, D &this2 ) ®with this1, this2® {
     953        i = 1; j = 2;
     954        m = 1.0; n = 2.0;
     955}
     956\end{cfa}
     957The ©with© clause/statement comes from Pascal~\cite[\S~4.F]{Pascal}.
     958
     959The statement form is used within a block:
     960\begin{cfa}
     961int 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
     976Names clashes when opening multiple structures are ambiguous.
     977\begin{cfa}
     978struct A { int i; int j; } a, c;
     979struct 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}
    902988\end{cfa}
    903989
     
    11361222
    11371223
    1138 \section{Pointer/Reference}
     1224\section{Pointer / Reference}
    11391225
    11401226C provides a \newterm{pointer type};
     
    24502536\end{cfa}
    24512537\\
    2452 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2538\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    245325391® ®2® ®3
    24542540\end{cfa}
    24552541&
    2456 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2542\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    245725431 2 3
    24582544\end{cfa}
     
    24612547The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators.
    24622548Similar simplification occurs for \Index{tuple} I/O, which prints all tuple values separated by ``\lstinline[showspaces=true]@, @''.
    2463 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    2464 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
     2549\begin{cfa}
     2550[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
    24652551sout | t1 | t2 | endl;                                  §\C{// print tuples}§
    24662552\end{cfa}
    2467 \begin{cfa}[mathescape=off,showspaces=true,belowskip=0pt]
    2468 1®, ®2®, ®3 3®, ®4®, ®5
     2553\begin{cfa}[showspaces=true,aboveskip=0pt]
     25541®, ®2®, ®3 4®, ®5®, ®6
    24692555\end{cfa}
    24702556Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority overloadable operator, other than assignment.
     
    24852571\\
    24862572&
    2487 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2573\begin{cfa}[showspaces=true,aboveskip=0pt]
    248825743 3 12 0 3 1 2
    24892575\end{cfa}
     
    25032589sout | 1 | 2 | 3 | endl;
    25042590\end{cfa}
    2505 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2591\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    250625921 2 3
    25072593\end{cfa}
     
    25702656\subsection{Manipulator}
    25712657
    2572 The following routines and \CC-style \Index{manipulator}s control implicit seperation.
     2658The following \CC-style \Index{manipulator}s and routines control implicit seperation.
    25732659\begin{enumerate}
    25742660\item
    2575 Routines \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string.
     2661Routines \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.
    25762662The separator string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters).
    2577 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2663\begin{cfa}[mathescape=off,belowskip=0pt]
    25782664sepSet( sout, ", $" );                                          §\C{// set separator from " " to ", \$"}§
    2579 sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\"" | endl;
     2665sout | 1 | 2 | 3 | " \"" | ®sep® | "\"" | endl;
    25802666\end{cfa}
    25812667%$
     
    25842670\end{cfa}
    25852671%$
    2586 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2672\begin{cfa}[belowskip=0pt]
    25872673sepSet( sout, " " );                                            §\C{// reset separator to " "}§
    25882674sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\"" | endl;
    25892675\end{cfa}
    2590 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
     2676\begin{cfa}[showspaces=true,aboveskip=0pt]
    259126771® ®2® ®3 ®" "®
    25922678\end{cfa}
    2593 
    2594 \item
    2595 Routine \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string.
     2679©sepGet© can be used to store a separator and then restore it:
     2680\begin{cfa}[belowskip=0pt]
     2681char store[®sepSize®];                                          §\C{// sepSize is the maximum separator size}§
     2682strcpy( store, sepGet( sout ) );
     2683sepSet( sout, "_" );
     2684sout | 1 | 2 | 3 | endl;
     2685\end{cfa}
     2686\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     26871®_®2®_®3
     2688\end{cfa}
     2689\begin{cfa}[belowskip=0pt]
     2690sepSet( sout, store );
     2691sout | 1 | 2 | 3 | endl;
     2692\end{cfa}
     2693\begin{cfa}[showspaces=true,aboveskip=0pt]
     26941® ®2® ®3
     2695\end{cfa}
     2696
     2697\item
     2698Routine \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.
    25962699The tuple separator-string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters).
    2597 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2700\begin{cfa}[belowskip=0pt]
    25982701sepSetTuple( sout, " " );                                       §\C{// set tuple separator from ", " to " "}§
    2599 sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\"" | endl;
    2600 \end{cfa}
    2601 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
    2602 1 2 3 4 ®" "®
    2603 \end{cfa}
    2604 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2702sout | t1 | t2 | " \"" | ®sepTuple® | "\"" | endl;
     2703\end{cfa}
     2704\begin{cfa}[showspaces=true,aboveskip=0pt]
     27051 2 3 4 5 6 ®" "®
     2706\end{cfa}
     2707\begin{cfa}[belowskip=0pt]
    26052708sepSetTuple( sout, ", " );                                      §\C{// reset tuple separator to ", "}§
    26062709sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\"" | endl;
    26072710\end{cfa}
    2608 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
    2609 1, 2, 3, 4 ®", "®
    2610 \end{cfa}
    2611 
    2612 \item
    2613 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.
    2614 \begin{cfa}[mathescape=off,belowskip=0pt]
    2615 sout | 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]
    2621 sout | 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]
    2624 12 3
    2625 \end{cfa}
    2626 The tuple separator also responses to being turned on and off.
    2627 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    2628 sout | 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}
    2633 Notice a tuple seperator starts the line because the next item is a tuple.
    2634 
    2635 \item
    2636 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, unless locally adjusted.
    2637 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    2638 sout | 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]
     2711\begin{cfa}[showspaces=true,aboveskip=0pt]
     27121, 2, 3 4, 5, 6 ®", "®
     2713\end{cfa}
     2714As for ©sepGet©, ©sepGetTuple© can be use to store a tuple separator and then restore it.
     2715
     2716\item
     2717Manipulators \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]
     2719sout | sepDisable | 1 | 2 | 3 | endl;           §\C{// globally turn off implicit separator}§
     2720\end{cfa}
     2721\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    26412722123
    26422723\end{cfa}
    2643 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    2644 sout | 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]
    2647 1® ®23
    2648 \end{cfa}
    2649 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    2650 sout | sepEnable | 1 | 2 | 3 | endl;            §\C{// globally turn on implicit separation}§
     2724\begin{cfa}[belowskip=0pt]
     2725sout | sepEnable | 1 | 2 | 3 | endl;            §\C{// globally turn on implicit separator}§
    26512726\end{cfa}
    26522727\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    265327281 2 3
    26542729\end{cfa}
     2730
     2731\item
     2732Manipulators \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]
     2734sout | 1 | sepOff | 2 | 3 | endl;                       §\C{// locally turn off implicit separator}§
     2735\end{cfa}
     2736\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     273712 3
     2738\end{cfa}
     2739\begin{cfa}[belowskip=0pt]
     2740sout | sepDisable | 1 | sepOn | 2 | 3 | endl; §\C{// locally turn on implicit separator}§
     2741\end{cfa}
     2742\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     27431 23
     2744\end{cfa}
     2745The tuple separator also responses to being turned on and off.
     2746\begin{cfa}[belowskip=0pt]
     2747sout | t1 | sepOff | t2 | endl;                         §\C{// locally turn on/off implicit separator}§
     2748\end{cfa}
     2749\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     27501, 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;
     2753use ©sep© to accomplish this functionality.
     2754\begin{cfa}[belowskip=0pt]
     2755sout | 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]
     27581 2 3
     2759\end{cfa}
     2760\begin{cfa}[belowskip=0pt]
     2761sout | 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}
    26552766\end{enumerate}
    26562767
    26572768\begin{comment}
    26582769#include <fstream>
     2770#include <string.h>                                                                             // strcpy
    26592771
    26602772int main( void ) {
    26612773        int x = 1, y = 2, z = 3;
    26622774        sout | x | y | z | endl;
    2663         [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
     2775        [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
    26642776        sout | t1 | t2 | endl;                                          // print tuples
    26652777        sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
     
    26752787
    26762788        sepSet( sout, ", $" );                                          // set separator from " " to ", $"
    2677         sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
     2789        sout | 1 | 2 | 3 | " \"" | sep | "\"" | endl;
    26782790        sepSet( sout, " " );                                            // reset separator to " "
    26792791        sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
    26802792
    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
     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;
    26872799
    26882800        sepSetTuple( sout, " " );                                       // set tuple separator from ", " to " "
    2689         sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
     2801        sout | t1 | t2 | " \"" | sepTuple | "\"" | endl;
    26902802        sepSetTuple( sout, ", " );                                      // reset tuple separator to ", "
    26912803        sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
    26922804
    2693         sout | t1 | t2 | endl;                                          // print tuple
    2694         sout | sepOn | t1 | sepOff | t2 | endl;         // locally turn on/off implicit separation
     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
    26952815}
    26962816
     
    52245344
    52255345
    5226 \section{\CFA Keywords}
     5346\section{\texorpdfstring{\CFA Keywords}{Cforall Keywords}}
    52275347\label{s:CFAKeywords}
    52285348
     5349\CFA introduces the following new keywords.
     5350
    52295351\begin{quote2}
    5230 \begin{tabular}{llll}
     5352\begin{tabular}{lllll}
    52315353\begin{tabular}{@{}l@{}}
    5232 ©_AT©                   \\
     5354©_At©                   \\
    52335355©catch©                 \\
    52345356©catchResume©   \\
    52355357©choose©                \\
    52365358©coroutine©             \\
    5237 ©disable©               \\
    52385359\end{tabular}
    52395360&
    52405361\begin{tabular}{@{}l@{}}
     5362©disable©               \\
    52415363©dtype©                 \\
    52425364©enable©                \\
    52435365©fallthrough©   \\
    52445366©fallthru©              \\
    5245 ©finally©               \\
    5246 ©forall©                \\
    52475367\end{tabular}
    52485368&
    52495369\begin{tabular}{@{}l@{}}
     5370©finally©               \\
     5371©forall©                \\
    52505372©ftype©                 \\
    52515373©lvalue©                \\
    52525374©monitor©               \\
     5375\end{tabular}
     5376&
     5377\begin{tabular}{@{}l@{}}
    52535378©mutex©                 \\
    52545379©one_t©                 \\
    52555380©otype©                 \\
     5381©throw©                 \\
     5382©throwResume©   \\
    52565383\end{tabular}
    52575384&
    52585385\begin{tabular}{@{}l@{}}
    5259 ©throw©                 \\
    5260 ©throwResume©   \\
    52615386©trait©                 \\
    52625387©try©                   \\
    52635388©ttype©                 \\
    52645389©zero_t©                \\
     5390                                \\
    52655391\end{tabular}
    52665392\end{tabular}
     
    55485674// C unsafe allocation
    55495675extern "C" {
    5550 void * mallac( size_t size );§\indexc{memset}§
     5676void * malloc( size_t size );§\indexc{memset}§
    55515677void * calloc( size_t dim, size_t size );§\indexc{calloc}§
    55525678void * realloc( void * ptr, size_t size );§\indexc{realloc}§
  • src/CodeGen/CodeGenerator.cc

    r55a68c3 r3d4b23fa  
    1414//
    1515
    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"
     16#include <cassert>                   // for assert, assertf
     17#include <list>                      // for _List_iterator, list, list<>::it...
    3218
    3319#include "CodeGenerator.h"
    34 #include "OperatorTable.h"
    35 #include "GenType.h"
    36 
    37 #include "InitTweak/InitTweak.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...
    3836
    3937using namespace std;
  • src/CodeGen/CodeGenerator.h

    r55a68c3 r3d4b23fa  
    1717#define CODEGENV_H
    1818
    19 #include <list>
     19#include <list>                   // for list
     20#include <ostream>                // for ostream, operator<<
     21#include <string>                 // for string
    2022
    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"
     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
    2926
    3027namespace CodeGen {
  • src/CodeGen/FixMain.cc

    r55a68c3 r3d4b23fa  
    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 <fstream>
    20 #include <iostream>
     19#include <cassert>                 // for assert, assertf
     20#include <fstream>                 // for operator<<, basic_ostream::operator<<
     21#include <list>                    // for list
     22#include <string>                  // for operator<<
    2123
    22 #include "Common/SemanticError.h"
    23 #include "SynTree/Declaration.h"
     24#include "Common/SemanticError.h"  // for SemanticError
     25#include "SynTree/Declaration.h"   // for FunctionDecl, operator<<
     26#include "SynTree/Type.h"          // for FunctionType
    2427
    2528namespace CodeGen {
    2629        bool FixMain::replace_main = false;
    2730        std::unique_ptr<FunctionDecl> FixMain::main_signature = nullptr;
    28        
    29         void FixMain::registerMain(FunctionDecl* functionDecl) 
     31
     32        void FixMain::registerMain(FunctionDecl* functionDecl)
    3033        {
    31                 if(main_signature) { 
    32                         throw SemanticError("Multiple definition of main routine\n", functionDecl); 
     34                if(main_signature) {
     35                        throw SemanticError("Multiple definition of main routine\n", functionDecl);
    3336                }
    3437                main_signature.reset( functionDecl->clone() );
  • src/CodeGen/FixNames.cc

    r55a68c3 r3d4b23fa  
    1414//
    1515
    16 #include <memory>
     16#include "FixNames.h"
    1717
    18 #include "FixNames.h"
    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"
     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
    2532
    2633namespace CodeGen {
     
    4249                                                                                                                                   main_type = new FunctionType( Type::Qualifiers(), true ), nullptr )
    4350                                };
    44                 main_type->get_returnVals().push_back( 
     51                main_type->get_returnVals().push_back(
    4552                        new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )
    4653                );
     
    5259        std::string mangle_main_args() {
    5360                FunctionType* main_type;
    54                 std::unique_ptr<FunctionDecl> mainDecl { new FunctionDecl( "main", Type::StorageClasses(), LinkageSpec::Cforall, 
     61                std::unique_ptr<FunctionDecl> mainDecl { new FunctionDecl( "main", Type::StorageClasses(), LinkageSpec::Cforall,
    5562                                                                                                                                   main_type = new FunctionType( Type::Qualifiers(), false ), nullptr )
    5663                                };
    57                 main_type->get_returnVals().push_back( 
     64                main_type->get_returnVals().push_back(
    5865                        new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )
    5966                );
    6067
    61                 mainDecl->get_functionType()->get_parameters().push_back( 
     68                mainDecl->get_functionType()->get_parameters().push_back(
    6269                        new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )
    6370                );
    6471
    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 ) ) ), 
     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 ) ) ),
    6875                        nullptr )
    6976                );
     
    7582
    7683        bool is_main(const std::string& name) {
    77                 static std::string mains[] = { 
    78                         mangle_main(), 
     84                static std::string mains[] = {
     85                        mangle_main(),
    7986                        mangle_main_args()
    8087                };
     
    112119                        int nargs = functionDecl->get_functionType()->get_parameters().size();
    113120                        if( !(nargs == 0 || nargs == 2 || nargs == 3) ) {
    114                                 throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", functionDecl); 
     121                                throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", functionDecl);
    115122                        }
    116123                        functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new ConstantExpr( Constant::from_int( 0 ) ) ) );
  • src/CodeGen/FixNames.h

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

    r55a68c3 r3d4b23fa  
    1414//
    1515
    16 #include <sstream>
    17 #include <cassert>
    18 
     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
    1921#include "GenType.h"
    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"
     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
    2626
    2727namespace CodeGen {
  • src/CodeGen/GenType.h

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

    r55a68c3 r3d4b23fa  
    1414//
    1515
    16 #include <algorithm>
    17 #include <iostream>
    18 #include <cassert>
    19 #include <list>
     16#include <iostream>                  // for ostream, endl, operator<<
     17#include <list>                      // for list
     18#include <string>                    // for operator<<
    2019
     20#include "CodeGenerator.h"           // for CodeGenerator, doSemicolon, oper...
     21#include "GenType.h"                 // for genPrettyType
    2122#include "Generate.h"
    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"
     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
    2927
    3028using namespace std;
  • src/CodeGen/Generate.h

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

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

    r55a68c3 r3d4b23fa  
    1616#include "DeclStats.h"
    1717
    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"
     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
    3034
    3135namespace CodeTools {
    32        
     36
    3337        class DeclStats : public Visitor {
    3438                template<typename T>
     
    7579                                sum(n_types, o.n_types);
    7680                                sum(p_new, o.p_new);
    77                                
     81
    7882                                return *this;
    7983                        }
    8084                };
    81                
     85
    8286                struct Stats {
    8387                        unsigned n_decls;     ///< Total number of declarations
     
    98102                        /// Stats for the return list
    99103                        ArgPackStats returns;
    100                        
     104
    101105                        /// Count of declarations with each number of assertions
    102106                        std::map<unsigned, unsigned> n_assns;
     
    105109                        /// Stats for the assertions' return types
    106110                        ArgPackStats assn_returns;
    107                        
     111
    108112                        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() {}
    109113
     
    122126                                sum( assn_params, o.assn_params );
    123127                                sum( assn_returns, o.assn_returns );
    124                                
     128
    125129                                return *this;
    126130                        }
     
    144148
    145149                                n += dt->size();
    146                                
     150
    147151                                std::stringstream ss;
    148152                                dt->print( ss );
     
    176180                        ++pstats.n_types.at( types.size() );
    177181                }
    178                
     182
    179183                void analyzeFunc( FunctionType* fnTy, Stats& stats, ArgPackStats& params, ArgPackStats& returns ) {
    180184                        std::unordered_set<std::string> seen;
     
    186190                        auto& args = expr->get_args();
    187191                        unsigned fanout = args.size();
    188                        
     192
    189193                        ++exprs_by_fanout_at_depth[ std::make_pair(depth, fanout) ];
    190194                        for ( Expression* arg : args ) {
     
    205209                                return;
    206210                        }
    207                        
     211
    208212                        Stats& stats = for_linkage[ decl->get_linkage() ];
    209213
     
    323327                }
    324328
    325                 void printPairMap( const std::string& name, 
     329                void printPairMap( const std::string& name,
    326330                                   const std::map<std::pair<unsigned, unsigned>, unsigned>& map ) {
    327331                        for ( const auto& entry : map ) {
    328332                                const auto& key = entry.first;
    329                                 std::cout << "\"" << name << "\"," << key.first << "," << key.second << "," 
     333                                std::cout << "\"" << name << "\"," << key.first << "," << key.second << ","
    330334                                          << entry.second << std::endl;
    331335                        }
    332336                }
    333                
     337
    334338        public:
    335339                void print() {
     
    366370                stats.print();
    367371        }
    368        
     372
    369373} // namespace CodeTools
    370374
  • src/CodeTools/DeclStats.h

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

    r55a68c3 r3d4b23fa  
    1616#include "TrackLoc.h"
    1717
    18 #include <cstdlib>
     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
    1924
    20 #include <iostream>
    21 #include <sstream>
    22 #include <stack>
    23 #include <string>
    24 #include <typeindex>
     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
    2532
    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"
     33class Declaration;
    3334
    3435namespace CodeTools {
  • src/CodeTools/TrackLoc.h

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

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

    r55a68c3 r3d4b23fa  
    1414//
    1515
    16 #include <iostream>
    17 #include <list>
    18 #include <string>
    19 #include <algorithm>
    20 #include <iterator>
     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
    2121
     22#include "Common/utility.h"  // for to_string, CodeLocation (ptr only)
    2223#include "SemanticError.h"
    23 
    24 #include <unistd.h>
    2524
    2625inline const std::string& error_str() {
  • src/Common/SemanticError.h

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

    r55a68c3 r3d4b23fa  
    1717#include "Concurrency/Keywords.h"
    1818
    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"
     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
     36class Attribute;
    2737
    2838namespace Concurrency {
     
    322332                if( needs_main ) {
    323333                        FunctionType * main_type = new FunctionType( noQualifiers, false );
    324                        
     334
    325335                        main_type->get_parameters().push_back( this_decl->clone() );
    326336
     
    361371        void ConcurrentSueKeyword::addRoutines( ObjectDecl * field, FunctionDecl * func ) {
    362372                CompoundStmt * statement = new CompoundStmt( noLabels );
    363                 statement->push_back( 
     373                statement->push_back(
    364374                        new ReturnStmt(
    365375                                noLabels,
     
    386396        //=============================================================================================
    387397        void MutexKeyword::visit(FunctionDecl* decl) {
    388                 Visitor::visit(decl);           
     398                Visitor::visit(decl);
    389399
    390400                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
     
    510520        void ThreadStarter::visit(FunctionDecl * decl) {
    511521                Visitor::visit(decl);
    512                
     522
    513523                if( ! InitTweak::isConstructor(decl->get_name()) ) return;
    514524
     
    528538                if( ! stmt ) return;
    529539
    530                 stmt->push_back( 
     540                stmt->push_back(
    531541                        new ExprStmt(
    532542                                noLabels,
  • src/Concurrency/Keywords.h

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

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

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

    r55a68c3 r3d4b23fa  
    7171                // that need to be constructed or destructed
    7272                void previsit( StructDecl *aggregateDecl );
    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; }
     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; }
    8079
    8180                void previsit( CompoundStmt * compoundStmt );
     
    336335        }
    337336
    338         void CtorDtor::previsit( CompoundStmt * compoundStmt ) {
     337        void CtorDtor::previsit( __attribute__((unused)) CompoundStmt * compoundStmt ) {
    339338                GuardScope( managedTypes );
    340339        }
  • src/MakeLibCfa.cc

    r55a68c3 r3d4b23fa  
    1515
    1616#include "MakeLibCfa.h"
    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"
     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
    2532
    2633namespace LibCfa {
  • src/MakeLibCfa.h

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

    r55a68c3 r3d4b23fa  
    4343driver_cfa_cpp_SOURCES = ${SRC}
    4444driver_cfa_cpp_LDADD = ${LEXLIB} -ldl                   # yywrap
    45 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14
     45driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -Wextra -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

    r55a68c3 r3d4b23fa  
    544544driver_cfa_cpp_SOURCES = ${SRC}
    545545driver_cfa_cpp_LDADD = ${LEXLIB} -ldl                   # yywrap
    546 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14
     546driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -Wextra -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) --gnu src/Makefile'; \
     562        echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
    563563        $(am__cd) $(top_srcdir) && \
    564           $(AUTOMAKE) --gnu src/Makefile
     564          $(AUTOMAKE) --foreign src/Makefile
    565565Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    566566        @case '$?' in \
  • src/Parser/LinkageSpec.cc

    r55a68c3 r3d4b23fa  
    1010// Created On       : Sat May 16 13:22:09 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jun 28 11:51:00 2017
    13 // Update Count     : 24
     12// Last Modified On : Fri Jul  7 11:11:00 2017
     13// Update Count     : 25
    1414//
    1515
     
    2222#include "Common/SemanticError.h"
    2323
    24 LinkageSpec::Spec LinkageSpec::linkageCheck( const string * spec ) {
     24namespace LinkageSpec {
     25
     26Spec linkageCheck( const string * spec ) {
     27        assert( spec );
    2528        unique_ptr<const string> guard( spec ); // allocated by lexer
    2629        if ( *spec == "\"Cforall\"" ) {
     
    3538}
    3639
    37 string 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];
     40Spec 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
    4352}
    4453
    45 bool 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];
     54std::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    }
    5473}
    5574
    56 bool 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 
    67 bool 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 
    78 bool 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 }
     75} // LinkageSpec
    8876
    8977// Local Variables: //
  • src/Parser/LinkageSpec.h

    r55a68c3 r3d4b23fa  
    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 : Wed Jun 28 11:50:00 2017
    13 // Update Count     : 12
     12// Last Modified On : Fri Jul  7 11:03:00 2017
     13// Update Count     : 13
    1414//
    1515
     
    1919#include <string>
    2020
    21 struct 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
     21namespace 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,
    3130        };
    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 );
     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 };
    4078};
    4179
  • src/Parser/StatementNode.cc

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

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

    r55a68c3 r3d4b23fa  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep  1 20:22:55 2001
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jun 30 15:38:00 2017
    13 // Update Count     : 2415
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jul 12 18:23:36 2017
     13// Update Count     : 2426
    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        // CFA
     131%token CHOOSE DISABLE ENABLE FALLTHRU TRY CATCH CATCHRESUME FINALLY THROW THROWRESUME AT WITH   // 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                          exception_statement                     asm_statement
     186%type<sn> iteration_statement                   jump_statement
     187%type<sn> with_statement                                exception_statement                     asm_statement
    187188%type<sn> fall_through_opt                              fall_through
    188189%type<sn> statement                                             statement_list
    189190%type<sn> block_item_list                               block_item
    190 %type<sn> case_clause
     191%type<sn> with_clause_opt
    191192%type<en> case_value
    192 %type<sn> case_value_list                               case_label                                      case_label_list
     193%type<sn> case_clause                                   case_value_list                         case_label                                      case_label_list
    193194%type<sn> switch_clause_list_opt                switch_clause_list                      choose_clause_list_opt          choose_clause_list
    194195%type<sn> /* handler_list */                    handler_clause                          finally_clause
     
    729730        | iteration_statement
    730731        | jump_statement
     732        | with_statement
    731733        | exception_statement
    732734        | asm_statement
     
    934936        | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume
    935937                { $$ = new StatementNode( build_resume_at( $2, $4 ) ); }
     938        ;
     939
     940with_statement:
     941        WITH identifier_list compound_statement
     942                { $$ = (StatementNode *)0; }                                    // FIX ME
    936943        ;
    937944
     
    21762183                {
    21772184                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    2178                         linkage = LinkageSpec::linkageCheck( $2 );
     2185                        linkage = LinkageSpec::linkageUpdate( linkage, $2 );
    21792186                }
    21802187          '{' external_definition_list_opt '}'
     
    22122219        ;
    22132220
     2221with_clause_opt:
     2222        // empty
     2223                { $$ = (StatementNode *)0; }                                    // FIX ME
     2224        | WITH identifier_list
     2225                { $$ = (StatementNode *)0; }                                    // FIX ME
     2226        ;
     2227
    22142228function_definition:
    2215         cfa_function_declaration compound_statement                     // CFA
     2229        cfa_function_declaration with_clause_opt compound_statement     // CFA
    22162230                {
    22172231                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22182232                        typedefTable.leaveScope();
    2219                         $$ = $1->addFunctionBody( $2 );
    2220                 }
    2221         | declaration_specifier function_declarator compound_statement
     2233                        $$ = $1->addFunctionBody( $3 );
     2234                }
     2235        | declaration_specifier function_declarator with_clause_opt compound_statement
    22222236                {
    22232237                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22242238                        typedefTable.leaveScope();
    2225                         $$ = $2->addFunctionBody( $3 )->addType( $1 );
    2226                 }
    2227         | type_qualifier_list function_declarator compound_statement
     2239                        $$ = $2->addFunctionBody( $4 )->addType( $1 );
     2240                }
     2241        | type_qualifier_list function_declarator with_clause_opt compound_statement
    22282242                {
    22292243                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22302244                        typedefTable.leaveScope();
    2231                         $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
    2232                 }
    2233         | declaration_qualifier_list function_declarator compound_statement
     2245                        $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 );
     2246                }
     2247        | declaration_qualifier_list function_declarator with_clause_opt compound_statement
    22342248                {
    22352249                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22362250                        typedefTable.leaveScope();
    2237                         $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
    2238                 }
    2239         | declaration_qualifier_list type_qualifier_list function_declarator compound_statement
     2251                        $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 );
     2252                }
     2253        | declaration_qualifier_list type_qualifier_list function_declarator with_clause_opt compound_statement
    22402254                {
    22412255                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22422256                        typedefTable.leaveScope();
    2243                         $$ = $3->addFunctionBody( $4 )->addQualifiers( $2 )->addQualifiers( $1 );
     2257                        $$ = $3->addFunctionBody( $5 )->addQualifiers( $2 )->addQualifiers( $1 );
    22442258                }
    22452259
    22462260                // Old-style K&R function definition, OBSOLESCENT (see 4)
    2247         | declaration_specifier KR_function_declarator push KR_declaration_list_opt compound_statement
     2261        | declaration_specifier KR_function_declarator push KR_declaration_list_opt with_clause_opt compound_statement
    22482262                {
    22492263                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22502264                        typedefTable.leaveScope();
    2251                         $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addType( $1 );
    2252                 }
    2253         | type_qualifier_list KR_function_declarator push KR_declaration_list_opt compound_statement
     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
    22542268                {
    22552269                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22562270                        typedefTable.leaveScope();
    2257                         $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
     2271                        $$ = $2->addOldDeclList( $4 )->addFunctionBody( $6 )->addQualifiers( $1 );
    22582272                }
    22592273
    22602274                // Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4)
    2261         | declaration_qualifier_list KR_function_declarator push KR_declaration_list_opt compound_statement
     2275        | declaration_qualifier_list KR_function_declarator push KR_declaration_list_opt with_clause_opt compound_statement
    22622276                {
    22632277                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22642278                        typedefTable.leaveScope();
    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
     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
    22682282                {
    22692283                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    22702284                        typedefTable.leaveScope();
    2271                         $$ = $3->addOldDeclList( $5 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 );
     2285                        $$ = $3->addOldDeclList( $5 )->addFunctionBody( $7 )->addQualifiers( $2 )->addQualifiers( $1 );
    22722286                }
    22732287        ;
     
    23322346        | TYPEGENname
    23332347        | CONST
    2334                 { $$ = Token{ new string( "__const__" ) }; }
     2348                { $$ = Token{ new string( "__const__" ), { nullptr, -1 } }; }
    23352349        ;
    23362350
  • src/ResolvExpr/CurrentObject.cc

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

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

    r55a68c3 r3d4b23fa  
    2020CC = @CFA_BINDIR@/@CFA_NAME@
    2121
    22 noinst_PROGRAMS = bench ctxswitch-coroutine ctxswitch-thread
     22noinst_PROGRAMS = bench$(EXEEXT) ctxswitch-coroutine$(EXEEXT) ctxswitch-thread$(EXEEXT) sched-int$(EXEEXT) monitor$(EXEEXT) csv-data$(EXEEXT)
    2323
    24 bench :
     24bench$(EXEEXT) :
    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:
     32ctxswitch-coroutine$(EXEEXT):
    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:
     39ctxswitch-thread$(EXEEXT):
    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:
     46sched-int$(EXEEXT):
    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:
     53monitor$(EXEEXT):
    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:
     60csv-data$(EXEEXT):
    6161        @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c
    6262        @./a.out
  • src/benchmark/Makefile.in

    r55a68c3 r3d4b23fa  
    9292build_triplet = @build@
    9393host_triplet = @host@
    94 noinst_PROGRAMS = bench$(EXEEXT) ctxswitch-coroutine$(EXEEXT) \
    95         ctxswitch-thread$(EXEEXT)
    9694subdir = src/benchmark
    9795ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
     
    108106bench_OBJECTS = bench.$(OBJEXT)
    109107bench_LDADD = $(LDADD)
     108csv_data_SOURCES = csv-data.c
     109csv_data_OBJECTS = csv-data.$(OBJEXT)
     110csv_data_LDADD = $(LDADD)
    110111ctxswitch_coroutine_SOURCES = ctxswitch-coroutine.c
    111112ctxswitch_coroutine_OBJECTS = ctxswitch-coroutine.$(OBJEXT)
     
    114115ctxswitch_thread_OBJECTS = ctxswitch-thread.$(OBJEXT)
    115116ctxswitch_thread_LDADD = $(LDADD)
     117monitor_SOURCES = monitor.c
     118monitor_OBJECTS = monitor.$(OBJEXT)
     119monitor_LDADD = $(LDADD)
     120sched_int_SOURCES = sched-int.c
     121sched_int_OBJECTS = sched-int.$(OBJEXT)
     122sched_int_LDADD = $(LDADD)
    116123AM_V_P = $(am__v_P_@AM_V@)
    117124am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
     
    142149am__v_CCLD_0 = @echo "  CCLD    " $@;
    143150am__v_CCLD_1 =
    144 SOURCES = bench.c ctxswitch-coroutine.c ctxswitch-thread.c
    145 DIST_SOURCES = bench.c ctxswitch-coroutine.c ctxswitch-thread.c
     151SOURCES = bench.c csv-data.c ctxswitch-coroutine.c ctxswitch-thread.c \
     152        monitor.c sched-int.c
     153DIST_SOURCES = bench.c csv-data.c ctxswitch-coroutine.c \
     154        ctxswitch-thread.c monitor.c sched-int.c
    146155am__can_run_installinfo = \
    147156  case $$AM_UPDATE_INFO_DIR in \
     
    293302top_srcdir = @top_srcdir@
    294303AM_CFLAGS = -g -Wall -Wno-unused-function -O2
     304noinst_PROGRAMS = bench$(EXEEXT) ctxswitch-coroutine$(EXEEXT) ctxswitch-thread$(EXEEXT) sched-int$(EXEEXT) monitor$(EXEEXT) csv-data$(EXEEXT)
    295305all: all-am
    296306
     
    306316          esac; \
    307317        done; \
    308         echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/benchmark/Makefile'; \
     318        echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/benchmark/Makefile'; \
    309319        $(am__cd) $(top_srcdir) && \
    310           $(AUTOMAKE) --gnu src/benchmark/Makefile
     320          $(AUTOMAKE) --foreign src/benchmark/Makefile
    311321Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    312322        @case '$?' in \
     
    337347
    338348@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bench.Po@am__quote@
     349@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csv-data.Po@am__quote@
    339350@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctxswitch-coroutine.Po@am__quote@
    340351@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@
    341354
    342355.c.o:
     
    559572
    560573
    561 bench :
     574bench$(EXEEXT) :
    562575        @for ccflags in "-debug" "-nodebug"; do \
    563576                echo ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -lrt bench.c;\
     
    567580        rm -f ./a.out ;
    568581
    569 ctxswitch-coroutine:
     582ctxswitch-coroutine$(EXEEXT):
    570583        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 CorCtxSwitch.c
    571584        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    574587        @rm -f ./a.out
    575588
    576 ctxswitch-thread:
     589ctxswitch-thread$(EXEEXT):
    577590        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 ThrdCtxSwitch.c
    578591        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    581594        @rm -f ./a.out
    582595
    583 sched-int:
     596sched-int$(EXEEXT):
    584597        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c
    585598        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    588601        @rm -f ./a.out
    589602
    590 monitor:
     603monitor$(EXEEXT):
    591604        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c
    592605        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     
    595608        @rm -f ./a.out
    596609
    597 csv-data:
     610csv-data$(EXEEXT):
    598611        @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c
    599612        @./a.out
  • src/benchmark/bench.h

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

    r55a68c3 r3d4b23fa  
    1717
    1818        for (size_t i = 0; i < n; i++) {
    19                 pthread_attr_t attr;
    20                 if (pthread_attr_init(&attr) < 0) {
     19                pthread_t thread;
     20                if (pthread_create(&thread, NULL, foo, NULL) < 0) {
    2121                        return 1;
    2222                }
    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) {
     23
     24                if (pthread_join( thread, NULL) < 0) {
    2825                        return 1;
    2926                }
  • src/benchmark/csv-data.c

    r55a68c3 r3d4b23fa  
    2525}
    2626
    27 #ifndef N
    28 #define N 100000000
    29 #endif
    30 
    3127//-----------------------------------------------------------------------------
    3228// coroutine context switch
     
    3834
    3935        StartTime = Time();
    40         // for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) {
    41         //      resume( this_coroutine() );
    42         //      // resume( &s );
    43         // }
    4436        resumer( &s, NoOfTimes );
    4537        EndTime = Time();
     
    10496mon_t mon1;
    10597
    106 condition cond1a; 
     98condition cond1a;
    10799condition cond1b;
    108100
     
    152144mon_t mon2;
    153145
    154 condition cond2a; 
     146condition cond2a;
    155147condition cond2b;
    156148
  • src/driver/Makefile.in

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

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

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

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

    r55a68c3 r3d4b23fa  
    142142LIBRARIES = $(lib_LIBRARIES)
    143143AR = ar
    144 ARFLAGS = cru
    145144AM_V_AR = $(am__v_AR_@AM_V@)
    146145am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
     
    409408# create object files in directory with source files
    410409AUTOMAKE_OPTIONS = subdir-objects
     410ARFLAGS = 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) --gnu src/libcfa/Makefile'; \
     441        echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/libcfa/Makefile'; \
    442442        $(am__cd) $(top_srcdir) && \
    443           $(AUTOMAKE) --gnu src/libcfa/Makefile
     443          $(AUTOMAKE) --foreign src/libcfa/Makefile
    444444Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    445445        @case '$?' in \
  • src/libcfa/concurrency/CtxSwitch-i386.S

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

    r55a68c3 r3d4b23fa  
    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
    101 CtxGet:
    102         movq %rsp,SP_OFFSET(%rdi)
    103         movq %rbp,FP_OFFSET(%rdi)
    104 
    105         ret
    10697
    10798// Local Variables: //
  • src/libcfa/concurrency/alarm.c

    r55a68c3 r3d4b23fa  
    1616
    1717extern "C" {
     18#include <errno.h>
     19#include <stdio.h>
     20#include <string.h>
    1821#include <time.h>
     22#include <unistd.h>
    1923#include <sys/time.h>
    2024}
     25
     26#include "libhdr.h"
    2127
    2228#include "alarm.h"
     
    3137        timespec curr;
    3238        clock_gettime( CLOCK_REALTIME, &curr );
    33         return ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec;
     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;
    3442}
    3543
    3644void __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 );
    3746        itimerval val;
    3847        val.it_value.tv_sec = alarm / TIMEGRAN;                 // seconds
     
    7180}
    7281
     82LIB_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
    7391static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) {
    74         assert( !n->next );
     92        verify( !n->next );
    7593        if( p == this->tail ) {
    7694                this->tail = &n->next;
     
    8098        }
    8199        *p = n;
     100
     101        verify( validate( this ) );
    82102}
    83103
     
    89109
    90110        insert_at( this, n, it );
     111
     112        verify( validate( this ) );
    91113}
    92114
     
    100122                head->next = NULL;
    101123        }
     124        verify( validate( this ) );
    102125        return head;
    103126}
     
    105128static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
    106129        verify( it );
    107         verify( (*it)->next == n );
     130        verify( (*it) == n );
    108131
    109         (*it)->next = n->next;
     132        (*it) = n->next;
    110133        if( !n-> next ) {
    111134                this->tail = it;
    112135        }
    113136        n->next = NULL;
     137
     138        verify( validate( this ) );
    114139}
    115140
    116141static inline void remove( alarm_list_t * this, alarm_node_t * n ) {
    117142        alarm_node_t ** it = &this->head;
    118         while( (*it) && (*it)->next != n ) {
     143        while( (*it) && (*it) != n ) {
    119144                it = &(*it)->next;
    120145        }
    121146
     147        verify( validate( this ) );
     148
    122149        if( *it ) { remove_at( this, n, it ); }
     150
     151        verify( validate( this ) );
    123152}
    124153
    125154void register_self( alarm_node_t * this ) {
    126155        disable_interrupts();
    127         assert( !systemProcessor->pending_alarm );
    128         lock( &systemProcessor->alarm_lock );
     156        verify( !systemProcessor->pending_alarm );
     157        lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
    129158        {
     159                verify( validate( &systemProcessor->alarms ) );
     160                bool first = !systemProcessor->alarms.head;
     161
    130162                insert( &systemProcessor->alarms, this );
    131163                if( systemProcessor->pending_alarm ) {
    132164                        tick_preemption();
    133165                }
     166                if( first ) {
     167                        __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() );
     168                }
    134169        }
    135170        unlock( &systemProcessor->alarm_lock );
    136171        this->set = true;
    137         enable_interrupts();
     172        enable_interrupts( DEBUG_CTX );
    138173}
    139174
    140175void unregister_self( alarm_node_t * this ) {
     176        // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : unregister %p start\n", this );
    141177        disable_interrupts();
    142         lock( &systemProcessor->alarm_lock );
    143         remove( &systemProcessor->alarms, this );
     178        lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
     179        {
     180                verify( validate( &systemProcessor->alarms ) );
     181                remove( &systemProcessor->alarms, this );
     182        }
    144183        unlock( &systemProcessor->alarm_lock );
    145         disable_interrupts();
     184        enable_interrupts( DEBUG_CTX );
    146185        this->set = false;
     186        // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Kernel : unregister %p end\n", this );
    147187}
  • src/libcfa/concurrency/coroutine

    r55a68c3 r3d4b23fa  
    6363
    6464// Get current coroutine
    65 coroutine_desc * this_coroutine(void);
     65extern volatile thread_local coroutine_desc * this_coroutine;
    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

    r55a68c3 r3d4b23fa  
    3232#include "invoke.h"
    3333
    34 extern thread_local processor * this_processor;
     34extern volatile thread_local processor * this_processor;
    3535
    3636//-----------------------------------------------------------------------------
     
    4444// Coroutine ctors and dtors
    4545void ?{}(coStack_t* this) {
    46         this->size              = 10240;        // size of stack
     46        this->size              = 65000;        // 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 = Inactive;
     108        src->state = src->state == Halted ? Halted : Inactive;
    109109
    110110        // set new coroutine that task is executing
    111         this_processor->current_coroutine = dst;
     111        this_coroutine = dst;
    112112
    113113        // context switch to specified coroutine
     114        assert( src->stack.context );
    114115        CtxSwitch( src->stack.context, dst->stack.context );
    115         // when CtxSwitch returns we are back in the src coroutine             
     116        // when CtxSwitch returns we are back in the src coroutine
    116117
    117118        // set state of new coroutine to active
     
    131132                this->size = libCeiling( storageSize, 16 );
    132133                // use malloc/memalign because "new" raises an exception for out-of-memory
    133                
     134
    134135                // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment
    135136                LIB_DEBUG_DO( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) );
  • src/libcfa/concurrency/invoke.c

    r55a68c3 r3d4b23fa  
    2929
    3030extern void __suspend_internal(void);
    31 extern void __leave_monitor_desc( struct monitor_desc * this );
     31extern void __leave_thread_monitor( struct thread_desc * this );
     32extern void disable_interrupts();
     33extern void enable_interrupts( DEBUG_CTX_PARAM );
    3234
    3335void CtxInvokeCoroutine(
    34       void (*main)(void *), 
    35       struct coroutine_desc *(*get_coroutine)(void *), 
     36      void (*main)(void *),
     37      struct coroutine_desc *(*get_coroutine)(void *),
    3638      void *this
    3739) {
     
    5658
    5759void CtxInvokeThread(
    58       void (*dtor)(void *), 
    59       void (*main)(void *), 
    60       struct thread_desc *(*get_thread)(void *), 
     60      void (*dtor)(void *),
     61      void (*main)(void *),
     62      struct thread_desc *(*get_thread)(void *),
    6163      void *this
    6264) {
     65      // First suspend, once the thread arrives here,
     66      // the function pointer to main can be invalidated without risk
    6367      __suspend_internal();
    6468
     69      // Fetch the thread handle from the user defined thread structure
    6570      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;
    6971
    70       // LIB_DEBUG_PRINTF("Invoke Thread : invoking main %p (args %p)\n", main, this);
     72      // Officially start the thread by enabling preemption
     73      enable_interrupts( DEBUG_CTX );
     74
     75      // Call the main of the thread
    7176      main( this );
    7277
    73       __leave_monitor_desc( mon );
    74 
     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
    7584      //Final suspend, should never return
    76       __suspend_internal();
     85      __leave_thread_monitor( thrd );
    7786      abortf("Resumed dead thread");
    7887}
     
    8089
    8190void CtxStart(
    82       void (*main)(void *), 
    83       struct coroutine_desc *(*get_coroutine)(void *), 
    84       void *this, 
     91      void (*main)(void *),
     92      struct coroutine_desc *(*get_coroutine)(void *),
     93      void *this,
    8594      void (*invoke)(void *)
    8695) {
     
    108117        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke;
    109118      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
    110       ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7 
     119      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
    111120
    112121#elif defined( __x86_64__ )
     
    128137      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke;
    129138      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
    130       ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7 
     139      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
    131140#else
    132141      #error Only __i386__ and __x86_64__ is supported for threads in cfa
  • src/libcfa/concurrency/invoke.h

    r55a68c3 r3d4b23fa  
    3131      struct spinlock {
    3232            volatile int lock;
     33            #ifdef __CFA_DEBUG__
     34                  const char * prev_name;
     35                  void* prev_thrd;
     36            #endif
    3337      };
    3438
     
    8387            struct __thread_queue_t entry_queue;      // queue of threads that are blocked waiting for the monitor
    8488            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
    8689            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
    8790      };
     
    99102#ifndef _INVOKE_PRIVATE_H_
    100103#define _INVOKE_PRIVATE_H_
    101      
     104
    102105      struct machine_context_t {
    103106            void *SP;
     
    109112      extern void CtxInvokeStub( void );
    110113      void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
    111       void CtxGet( void * this ) asm ("CtxGet");
     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
    112126
    113127#endif //_INVOKE_PRIVATE_H_
  • src/libcfa/concurrency/kernel

    r55a68c3 r3d4b23fa  
    2828//-----------------------------------------------------------------------------
    2929// Locks
    30 bool try_lock( spinlock * );
    31 void lock( spinlock * );
    32 void unlock( spinlock * );
     30bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );
     31void lock      ( spinlock * DEBUG_CTX_PARAM2 );
     32void lock_yield( spinlock * DEBUG_CTX_PARAM2 );
     33void unlock    ( spinlock * );
    3334
    34 struct signal_once {
    35         volatile bool cond;
    36         struct spinlock lock;
    37         struct __thread_queue_t blocked;
     35struct semaphore {
     36        spinlock lock;
     37        int count;
     38        __thread_queue_t waiting;
    3839};
    3940
    40 void ?{}(signal_once * this);
    41 void ^?{}(signal_once * this);
     41void  ?{}(semaphore * this, int count = 1);
     42void ^?{}(semaphore * this);
     43void P(semaphore * this);
     44void V(semaphore * this);
    4245
    43 void wait( signal_once * );
    44 void signal( signal_once * );
    4546
    4647//-----------------------------------------------------------------------------
     
    6869        unsigned short thrd_count;
    6970};
    70 static inline void ?{}(FinishAction * this) { 
     71static inline void ?{}(FinishAction * this) {
    7172        this->action_code = No_Action;
    7273        this->thrd = NULL;
     
    7879        struct processorCtx_t * runner;
    7980        cluster * cltr;
    80         coroutine_desc * current_coroutine;
    81         thread_desc * current_thread;
    8281        pthread_t kernel_thread;
    83        
    84         signal_once terminated;
     82
     83        semaphore terminated;
    8584        volatile bool is_terminated;
    8685
     
    9089        unsigned int preemption;
    9190
    92         unsigned short disable_preempt_count;
     91        bool pending_preemption;
    9392
    94         bool pending_preemption;
     93        char * last_enable;
    9594};
    9695
  • src/libcfa/concurrency/kernel.c

    r55a68c3 r3d4b23fa  
    1515//
    1616
    17 #include "startup.h"
    18 
    19 //Start and stop routine for the kernel, declared first to make sure they run first
    20 void kernel_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
    21 void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
    22 
    23 //Header
    24 #include "kernel_private.h"
     17#include "libhdr.h"
    2518
    2619//C Includes
     
    3528
    3629//CFA Includes
    37 #include "libhdr.h"
     30#include "kernel_private.h"
    3831#include "preemption.h"
     32#include "startup.h"
    3933
    4034//Private includes
     
    4236#include "invoke.h"
    4337
     38//Start and stop routine for the kernel, declared first to make sure they run first
     39void kernel_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
     40void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
     41
    4442//-----------------------------------------------------------------------------
    4543// Kernel storage
    46 #define KERNEL_STORAGE(T,X) static char X##_storage[sizeof(T)]
     44#define KERNEL_STORAGE(T,X) static char X##Storage[sizeof(T)]
    4745
    4846KERNEL_STORAGE(processorCtx_t, systemProcessorCtx);
     
    5048KERNEL_STORAGE(system_proc_t, systemProcessor);
    5149KERNEL_STORAGE(thread_desc, mainThread);
    52 KERNEL_STORAGE(machine_context_t, mainThread_context);
     50KERNEL_STORAGE(machine_context_t, mainThreadCtx);
    5351
    5452cluster * systemCluster;
     
    5957// Global state
    6058
    61 thread_local processor * this_processor;
    62 
    63 coroutine_desc * this_coroutine(void) {
    64         return this_processor->current_coroutine;
    65 }
    66 
    67 thread_desc * this_thread(void) {
    68         return this_processor->current_thread;
    69 }
     59volatile thread_local processor * this_processor;
     60volatile thread_local coroutine_desc * this_coroutine;
     61volatile thread_local thread_desc * this_thread;
     62volatile thread_local bool preemption_in_progress = 0;
     63volatile thread_local unsigned short disable_preempt_count = 1;
    7064
    7165//-----------------------------------------------------------------------------
    7266// Main thread construction
    7367struct current_stack_info_t {
    74         machine_context_t ctx; 
     68        machine_context_t ctx;
    7569        unsigned int size;              // size of stack
    7670        void *base;                             // base of stack
     
    8276
    8377void ?{}( current_stack_info_t * this ) {
    84         CtxGet( &this->ctx );
     78        CtxGet( this->ctx );
    8579        this->base = this->ctx.FP;
    8680        this->storage = this->ctx.SP;
     
    9185
    9286        this->limit = (void *)(((intptr_t)this->base) - this->size);
    93         this->context = &mainThread_context_storage;
     87        this->context = &mainThreadCtxStorage;
    9488        this->top = this->base;
    9589}
     
    106100
    107101void ?{}( coroutine_desc * this, current_stack_info_t * info) {
    108         (&this->stack){ info }; 
     102        (&this->stack){ info };
    109103        this->name = "Main Thread";
    110104        this->errno_ = 0;
     
    136130void ?{}(processor * this, cluster * cltr) {
    137131        this->cltr = cltr;
    138         this->current_coroutine = NULL;
    139         this->current_thread = NULL;
    140         (&this->terminated){};
     132        (&this->terminated){ 0 };
    141133        this->is_terminated = false;
    142134        this->preemption_alarm = NULL;
    143135        this->preemption = default_preemption();
    144         this->disable_preempt_count = 1;                //Start with interrupts disabled
    145136        this->pending_preemption = false;
    146137
     
    150141void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) {
    151142        this->cltr = cltr;
    152         this->current_coroutine = NULL;
    153         this->current_thread = NULL;
    154         (&this->terminated){};
     143        (&this->terminated){ 0 };
    155144        this->is_terminated = false;
    156         this->disable_preempt_count = 0;
     145        this->preemption_alarm = NULL;
     146        this->preemption = default_preemption();
    157147        this->pending_preemption = false;
     148        this->kernel_thread = pthread_self();
    158149
    159150        this->runner = runner;
    160         LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner);
     151        LIB_DEBUG_PRINT_SAFE("Kernel : constructing system processor context %p\n", runner);
    161152        runner{ this };
    162153}
     154
     155LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )
    163156
    164157void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) {
     
    168161
    169162        (&this->proc){ cltr, runner };
     163
     164        verify( validate( &this->alarms ) );
    170165}
    171166
     
    174169                LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this);
    175170                this->is_terminated = true;
    176                 wait( &this->terminated );
     171                P( &this->terminated );
     172                pthread_join( this->kernel_thread, NULL );
    177173        }
    178174}
     
    184180
    185181void ^?{}(cluster * this) {
    186        
     182
    187183}
    188184
     
    203199
    204200                thread_desc * readyThread = NULL;
    205                 for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ ) 
     201                for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ )
    206202                {
    207203                        readyThread = nextThread( this->cltr );
     
    209205                        if(readyThread)
    210206                        {
     207                                verify( disable_preempt_count > 0 );
     208
    211209                                runThread(this, readyThread);
     210
     211                                verify( disable_preempt_count > 0 );
    212212
    213213                                //Some actions need to be taken from the kernel
     
    225225        }
    226226
    227         signal( &this->terminated );
     227        V( &this->terminated );
     228
    228229        LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this);
    229230}
    230231
    231 // runThread runs a thread by context switching 
    232 // from the processor coroutine to the target thread 
     232// runThread runs a thread by context switching
     233// from the processor coroutine to the target thread
    233234void runThread(processor * this, thread_desc * dst) {
    234235        coroutine_desc * proc_cor = get_coroutine(this->runner);
    235236        coroutine_desc * thrd_cor = get_coroutine(dst);
    236        
     237
    237238        //Reset the terminating actions here
    238239        this->finish.action_code = No_Action;
    239240
    240241        //Update global state
    241         this->current_thread = dst;
     242        this_thread = dst;
    242243
    243244        // Context Switch to the thread
     
    246247}
    247248
    248 // Once a thread has finished running, some of 
     249// Once a thread has finished running, some of
    249250// its final actions must be executed from the kernel
    250251void finishRunning(processor * this) {
     
    256257        }
    257258        else if( this->finish.action_code == Release_Schedule ) {
    258                 unlock( this->finish.lock );           
     259                unlock( this->finish.lock );
    259260                ScheduleThread( this->finish.thrd );
    260261        }
     
    289290        processor * proc = (processor *) arg;
    290291        this_processor = proc;
     292        this_coroutine = NULL;
     293        this_thread = NULL;
     294        disable_preempt_count = 1;
    291295        // SKULLDUGGERY: We want to create a context for the processor coroutine
    292296        // which is needed for the 2-step context switch. However, there is no reason
    293         // to waste the perfectly valid stack create by pthread. 
     297        // to waste the perfectly valid stack create by pthread.
    294298        current_stack_info_t info;
    295299        machine_context_t ctx;
     
    300304
    301305        //Set global state
    302         proc->current_coroutine = &proc->runner->__cor;
    303         proc->current_thread = NULL;
     306        this_coroutine = &proc->runner->__cor;
     307        this_thread = NULL;
    304308
    305309        //We now have a proper context from which to schedule threads
    306310        LIB_DEBUG_PRINT_SAFE("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx);
    307311
    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 
     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
    311315        // appropriate stack.
    312316        proc_cor_storage.__cor.state = Active;
     
    315319
    316320        // Main routine of the core returned, the core is now fully terminated
    317         LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner); 
     321        LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner);
    318322
    319323        return NULL;
     
    322326void start(processor * this) {
    323327        LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this);
    324        
     328
    325329        pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );
    326330
    327         LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);       
     331        LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);
    328332}
    329333
     
    331335// Scheduler routines
    332336void ScheduleThread( thread_desc * thrd ) {
    333         if( !thrd ) return;
     337        // if( !thrd ) return;
     338        assert( thrd );
     339        assert( thrd->cor.state != Halted );
     340
     341        verify( disable_preempt_count > 0 );
    334342
    335343        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    336        
    337         lock( &systemProcessor->proc.cltr->lock );
     344
     345        lock( &systemProcessor->proc.cltr->lock DEBUG_CTX2 );
    338346        append( &systemProcessor->proc.cltr->ready_queue, thrd );
    339347        unlock( &systemProcessor->proc.cltr->lock );
     348
     349        verify( disable_preempt_count > 0 );
    340350}
    341351
    342352thread_desc * nextThread(cluster * this) {
    343         lock( &this->lock );
     353        verify( disable_preempt_count > 0 );
     354        lock( &this->lock DEBUG_CTX2 );
    344355        thread_desc * head = pop_head( &this->ready_queue );
    345356        unlock( &this->lock );
     357        verify( disable_preempt_count > 0 );
    346358        return head;
    347359}
    348360
    349 void ScheduleInternal() {
     361void BlockInternal() {
     362        disable_interrupts();
     363        verify( disable_preempt_count > 0 );
    350364        suspend();
    351 }
    352 
    353 void ScheduleInternal( spinlock * lock ) {
     365        verify( disable_preempt_count > 0 );
     366        enable_interrupts( DEBUG_CTX );
     367}
     368
     369void BlockInternal( spinlock * lock ) {
     370        disable_interrupts();
    354371        this_processor->finish.action_code = Release;
    355372        this_processor->finish.lock = lock;
     373
     374        verify( disable_preempt_count > 0 );
    356375        suspend();
    357 }
    358 
    359 void ScheduleInternal( thread_desc * thrd ) {
     376        verify( disable_preempt_count > 0 );
     377
     378        enable_interrupts( DEBUG_CTX );
     379}
     380
     381void BlockInternal( thread_desc * thrd ) {
     382        disable_interrupts();
     383        assert( thrd->cor.state != Halted );
    360384        this_processor->finish.action_code = Schedule;
    361385        this_processor->finish.thrd = thrd;
     386
     387        verify( disable_preempt_count > 0 );
    362388        suspend();
    363 }
    364 
    365 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) {
     389        verify( disable_preempt_count > 0 );
     390
     391        enable_interrupts( DEBUG_CTX );
     392}
     393
     394void BlockInternal( spinlock * lock, thread_desc * thrd ) {
     395        disable_interrupts();
    366396        this_processor->finish.action_code = Release_Schedule;
    367397        this_processor->finish.lock = lock;
    368398        this_processor->finish.thrd = thrd;
     399
     400        verify( disable_preempt_count > 0 );
    369401        suspend();
    370 }
    371 
    372 void ScheduleInternal(spinlock ** locks, unsigned short count) {
     402        verify( disable_preempt_count > 0 );
     403
     404        enable_interrupts( DEBUG_CTX );
     405}
     406
     407void BlockInternal(spinlock ** locks, unsigned short count) {
     408        disable_interrupts();
    373409        this_processor->finish.action_code = Release_Multi;
    374410        this_processor->finish.locks = locks;
    375411        this_processor->finish.lock_count = count;
     412
     413        verify( disable_preempt_count > 0 );
    376414        suspend();
    377 }
    378 
    379 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     415        verify( disable_preempt_count > 0 );
     416
     417        enable_interrupts( DEBUG_CTX );
     418}
     419
     420void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     421        disable_interrupts();
    380422        this_processor->finish.action_code = Release_Multi_Schedule;
    381423        this_processor->finish.locks = locks;
     
    383425        this_processor->finish.thrds = thrds;
    384426        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
     435void 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
    385441        suspend();
    386442}
     
    392448// Kernel boot procedures
    393449void kernel_startup(void) {
    394         LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n");   
     450        LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n");
    395451
    396452        // Start by initializing the main thread
    397         // SKULLDUGGERY: the mainThread steals the process main thread 
     453        // SKULLDUGGERY: the mainThread steals the process main thread
    398454        // which will then be scheduled by the systemProcessor normally
    399         mainThread = (thread_desc *)&mainThread_storage;
     455        mainThread = (thread_desc *)&mainThreadStorage;
    400456        current_stack_info_t info;
    401457        mainThread{ &info };
     
    403459        LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n");
    404460
     461        // Initialize the system cluster
     462        systemCluster = (cluster *)&systemClusterStorage;
     463        systemCluster{};
     464
     465        LIB_DEBUG_PRINT_SAFE("Kernel : System cluster ready\n");
     466
     467        // Initialize the system processor and the system processor ctx
     468        // (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
     473        // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread
     474        ScheduleThread(mainThread);
     475
     476        //initialize the global state variables
     477        this_processor = &systemProcessor->proc;
     478        this_thread = mainThread;
     479        this_coroutine = &mainThread->cor;
     480        disable_preempt_count = 1;
     481
    405482        // Enable preemption
    406483        kernel_start_preemption();
    407484
    408         // Initialize the system cluster
    409         systemCluster = (cluster *)&systemCluster_storage;
    410         systemCluster{};
    411 
    412         LIB_DEBUG_PRINT_SAFE("Kernel : System cluster ready\n");
    413 
    414         // Initialize the system processor and the system processor ctx
    415         // (the coroutine that contains the processing control flow)
    416         systemProcessor = (system_proc_t *)&systemProcessor_storage;
    417         systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtx_storage };
    418 
    419         // Add the main thread to the ready queue
    420         // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread
    421         ScheduleThread(mainThread);
    422 
    423         //initialize the global state variables
    424         this_processor = &systemProcessor->proc;
    425         this_processor->current_thread = mainThread;
    426         this_processor->current_coroutine = &mainThread->cor;
    427 
    428485        // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX
    429486        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    430         // mainThread is on the ready queue when this call is made. 
     487        // mainThread is on the ready queue when this call is made.
    431488        resume( systemProcessor->proc.runner );
    432489
     
    435492        // THE SYSTEM IS NOW COMPLETELY RUNNING
    436493        LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");
     494
     495        enable_interrupts( DEBUG_CTX );
    437496}
    438497
    439498void kernel_shutdown(void) {
    440499        LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n");
     500
     501        disable_interrupts();
    441502
    442503        // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.
     
    448509        // THE SYSTEM IS NOW COMPLETELY STOPPED
    449510
     511        // Disable preemption
     512        kernel_stop_preemption();
     513
    450514        // Destroy the system processor and its context in reverse order of construction
    451515        // These were manually constructed so we need manually destroy them
     
    457521        ^(mainThread){};
    458522
    459         LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n");   
     523        LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n");
    460524}
    461525
     
    467531        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
    468532        // the globalAbort flag is true.
    469         lock( &kernel_abort_lock );
     533        lock( &kernel_abort_lock DEBUG_CTX2 );
    470534
    471535        // first task to abort ?
     
    473537                kernel_abort_called = true;
    474538                unlock( &kernel_abort_lock );
    475         } 
     539        }
    476540        else {
    477541                unlock( &kernel_abort_lock );
    478                
     542
    479543                sigset_t mask;
    480544                sigemptyset( &mask );
     
    482546                sigaddset( &mask, SIGUSR1 );                    // block SIGUSR1 signals
    483547                sigsuspend( &mask );                            // block the processor to prevent further damage during abort
    484                 _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it             
    485         }
    486 
    487         return this_thread();
     548                _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it
     549        }
     550
     551        return this_thread;
    488552}
    489553
     
    494558        __lib_debug_write( STDERR_FILENO, abort_text, len );
    495559
    496         if ( thrd != this_coroutine() ) {
    497                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine()->name, this_coroutine() );
     560        if ( thrd != this_coroutine ) {
     561                len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine );
    498562                __lib_debug_write( STDERR_FILENO, abort_text, len );
    499         } 
     563        }
    500564        else {
    501565                __lib_debug_write( STDERR_FILENO, ".\n", 2 );
     
    505569extern "C" {
    506570        void __lib_debug_acquire() {
    507                 lock(&kernel_debug_lock);
     571                lock( &kernel_debug_lock DEBUG_CTX2 );
    508572        }
    509573
    510574        void __lib_debug_release() {
    511                 unlock(&kernel_debug_lock);
     575                unlock( &kernel_debug_lock );
    512576        }
    513577}
     
    525589}
    526590
    527 bool try_lock( spinlock * this ) {
     591bool try_lock( spinlock * this DEBUG_CTX_PARAM2 ) {
    528592        return this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0;
    529593}
    530594
    531 void lock( spinlock * this ) {
     595void lock( spinlock * this DEBUG_CTX_PARAM2 ) {
    532596        for ( unsigned int i = 1;; i += 1 ) {
    533                 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) break;
    534         }
    535 }
     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
     605void 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
    536616
    537617void unlock( spinlock * this ) {
     
    539619}
    540620
    541 void ?{}( signal_once * this ) {
    542         this->cond = false;
    543 }
    544 void ^?{}( signal_once * this ) {
    545 
    546 }
    547 
    548 void 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         }
     621void  ?{}( semaphore * this, int count = 1 ) {
     622        (&this->lock){};
     623        this->count = count;
     624        (&this->waiting){};
     625}
     626void ^?{}(semaphore * this) {}
     627
     628void 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
     643void 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
    555652        unlock( &this->lock );
    556 }
    557 
    558 void 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 );
     653
     654        // make new owner
     655        WakeThread( thrd );
    569656}
    570657
     
    590677                }
    591678                head->next = NULL;
    592         }       
     679        }
    593680        return head;
    594681}
     
    609696                this->top = top->next;
    610697                top->next = NULL;
    611         }       
     698        }
    612699        return top;
    613700}
  • src/libcfa/concurrency/kernel_private.h

    r55a68c3 r3d4b23fa  
    1818#define KERNEL_PRIVATE_H
    1919
     20#include "libhdr.h"
     21
    2022#include "kernel"
    2123#include "thread"
     
    2325#include "alarm.h"
    2426
    25 #include "libhdr.h"
    2627
    2728//-----------------------------------------------------------------------------
    2829// Scheduler
     30
     31extern "C" {
     32        void disable_interrupts();
     33        void enable_interrupts_noRF();
     34        void enable_interrupts( DEBUG_CTX_PARAM );
     35}
     36
    2937void ScheduleThread( thread_desc * );
     38static inline void WakeThread( thread_desc * thrd ) {
     39        if( !thrd ) return;
     40
     41        disable_interrupts();
     42        ScheduleThread( thrd );
     43        enable_interrupts( DEBUG_CTX );
     44}
    3045thread_desc * nextThread(cluster * this);
    3146
    32 void ScheduleInternal(void);
    33 void ScheduleInternal(spinlock * lock);
    34 void ScheduleInternal(thread_desc * thrd);
    35 void ScheduleInternal(spinlock * lock, thread_desc * thrd);
    36 void ScheduleInternal(spinlock ** locks, unsigned short count);
    37 void ScheduleInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
     47void BlockInternal(void);
     48void BlockInternal(spinlock * lock);
     49void BlockInternal(thread_desc * thrd);
     50void BlockInternal(spinlock * lock, thread_desc * thrd);
     51void BlockInternal(spinlock ** locks, unsigned short count);
     52void BlockInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
     53void LeaveThread(spinlock * lock, thread_desc * thrd);
    3854
    3955//-----------------------------------------------------------------------------
     
    6076extern cluster * systemCluster;
    6177extern system_proc_t * systemProcessor;
    62 extern thread_local processor * this_processor;
    63 
    64 static 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 
    69 static 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 
    74 static 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 }
     78extern volatile thread_local processor * this_processor;
     79extern volatile thread_local coroutine_desc * this_coroutine;
     80extern volatile thread_local thread_desc * this_thread;
     81extern volatile thread_local bool preemption_in_progress;
     82extern volatile thread_local unsigned short disable_preempt_count;
    8283
    8384//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/monitor

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

    r55a68c3 r3d4b23fa  
    1919#include <stdlib>
    2020
     21#include "libhdr.h"
    2122#include "kernel_private.h"
    22 #include "libhdr.h"
    2323
    2424//-----------------------------------------------------------------------------
     
    4444
    4545extern "C" {
    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);
     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);
    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                         ScheduleInternal( &this->lock );
    66 
    67                         //ScheduleInternal will unlock spinlock, no need to unlock ourselves
    68                         return; 
     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;
    6969                }
    7070
     
    7575        // leave pseudo code :
    7676        //      TODO
    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 );
     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 );
    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                 ScheduleThread( new_owner );
     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 );
    102127        }
    103128}
     
    121146        enter( this->m, this->count );
    122147
    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;
     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;
    128153}
    129154
     
    131156        leave( this->m, this->count );
    132157
    133         this_thread()->current_monitors      = this->prev_mntrs;
    134         this_thread()->current_monitor_count = this->prev_count;
     158        this_thread->current_monitors      = this->prev_mntrs;
     159        this_thread->current_monitor_count = this->prev_count;
    135160}
    136161
     
    159184// Internal scheduling
    160185void wait( condition * this, uintptr_t user_info = 0 ) {
    161         LIB_DEBUG_PRINT_SAFE("Waiting\n");
     186        // LIB_DEBUG_PRINT_SAFE("Waiting\n");
    162187
    163188        brand_condition( this );
     
    170195        unsigned short count = this->monitor_count;
    171196        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    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 };
     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 };
    177202
    178203        __condition_criterion_t criteria[count];
    179204        for(int i = 0; i < count; i++) {
    180205                (&criteria[i]){ this->monitors[i], &waiter };
    181                 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     206                // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    182207        }
    183208
     
    201226        }
    202227
    203         LIB_DEBUG_PRINT_SAFE("Will unblock: ");
     228        // LIB_DEBUG_PRINT_SAFE("Will unblock: ");
    204229        for(int i = 0; i < thread_count; i++) {
    205                 LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
    206         }
    207         LIB_DEBUG_PRINT_SAFE("\n");
     230                // LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
     231        }
     232        // LIB_DEBUG_PRINT_SAFE("\n");
    208233
    209234        // Everything is ready to go to sleep
    210         ScheduleInternal( locks, count, threads, thread_count );
     235        BlockInternal( locks, count, threads, thread_count );
    211236
    212237
     
    222247bool signal( condition * this ) {
    223248        if( is_empty( this ) ) {
    224                 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
     249                // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    225250                return false;
    226251        }
     
    231256
    232257        unsigned short count = this->monitor_count;
    233        
     258
    234259        //Some more checking in debug
    235260        LIB_DEBUG_DO(
    236                 thread_desc * this_thrd = this_thread();
     261                thread_desc * this_thrd = this_thread;
    237262                if ( this->monitor_count != this_thrd->current_monitor_count ) {
    238263                        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 );
     
    248273        //Lock all the monitors
    249274        lock_all( this->monitors, NULL, count );
    250         LIB_DEBUG_PRINT_SAFE("Signalling");
     275        // LIB_DEBUG_PRINT_SAFE("Signalling");
    251276
    252277        //Pop the head of the waiting queue
     
    256281        for(int i = 0; i < count; i++) {
    257282                __condition_criterion_t * crit = &node->criteria[i];
    258                 LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
     283                // LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
    259284                assert( !crit->ready );
    260285                push( &crit->target->signal_stack, crit );
    261286        }
    262287
    263         LIB_DEBUG_PRINT_SAFE("\n");
     288        // LIB_DEBUG_PRINT_SAFE("\n");
    264289
    265290        //Release
     
    281306        unsigned short count = this->monitor_count;
    282307        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    283         spinlock *   locks     [ count ];               //We need to pass-in an array of locks to ScheduleInternal
     308        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
    284309
    285310        lock_all( this->monitors, locks, count );
    286311
    287312        //create creteria
    288         __condition_node_t waiter = { this_thread(), count, 0 };
     313        __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };
    289314
    290315        __condition_criterion_t criteria[count];
    291316        for(int i = 0; i < count; i++) {
    292317                (&criteria[i]){ this->monitors[i], &waiter };
    293                 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     318                // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    294319                push( &criteria[i].target->signal_stack, &criteria[i] );
    295320        }
     
    309334
    310335        //Everything is ready to go to sleep
    311         ScheduleInternal( locks, count, &signallee, 1 );
     336        BlockInternal( locks, count, &signallee, 1 );
    312337
    313338
     
    325350
    326351uintptr_t front( condition * this ) {
    327         verifyf( !is_empty(this), 
     352        verifyf( !is_empty(this),
    328353                "Attempt to access user data on an empty condition.\n"
    329354                "Possible cause is not checking if the condition is empty before reading stored data."
     
    335360// Internal scheduling
    336361void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) {
    337         // thread_desc * this = this_thread();
     362        // thread_desc * this = this_thread;
    338363
    339364        // unsigned short count = this->current_monitor_count;
    340365        // unsigned int recursions[ count ];            //Save the current recursion levels to restore them later
    341         // spinlock *   locks     [ count ];            //We need to pass-in an array of locks to ScheduleInternal
     366        // spinlock *   locks     [ count ];            //We need to pass-in an array of locks to BlockInternal
    342367
    343368        // lock_all( this->current_monitors, locks, count );
     
    348373
    349374        // // // Everything is ready to go to sleep
    350         // // ScheduleInternal( locks, count, threads, thread_count );
     375        // // BlockInternal( locks, count, threads, thread_count );
    351376
    352377
     
    393418static inline void lock_all( spinlock ** locks, unsigned short count ) {
    394419        for( int i = 0; i < count; i++ ) {
    395                 lock( locks[i] );
     420                lock_yield( locks[i] DEBUG_CTX2 );
    396421        }
    397422}
     
    400425        for( int i = 0; i < count; i++ ) {
    401426                spinlock * l = &source[i]->lock;
    402                 lock( l );
     427                lock_yield( l DEBUG_CTX2 );
    403428                if(locks) locks[i] = l;
    404429        }
     
    443468        for(    int i = 0; i < count; i++ ) {
    444469
    445                 LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
     470                // LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
    446471                if( &criteria[i] == target ) {
    447472                        criteria[i].ready = true;
    448                         LIB_DEBUG_PRINT_SAFE( "True\n" );
     473                        // LIB_DEBUG_PRINT_SAFE( "True\n" );
    449474                }
    450475
     
    452477        }
    453478
    454         LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
     479        // LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
    455480        return ready2run ? node->waiting_thread : NULL;
    456481}
    457482
    458483static inline void brand_condition( condition * this ) {
    459         thread_desc * thrd = this_thread();
     484        thread_desc * thrd = this_thread;
    460485        if( !this->monitors ) {
    461                 LIB_DEBUG_PRINT_SAFE("Branding\n");
     486                // LIB_DEBUG_PRINT_SAFE("Branding\n");
    462487                assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors );
    463488                this->monitor_count = thrd->current_monitor_count;
  • src/libcfa/concurrency/preemption.c

    r55a68c3 r3d4b23fa  
    1515//
    1616
     17#include "libhdr.h"
    1718#include "preemption.h"
    1819
    1920extern "C" {
     21#include <errno.h>
     22#include <execinfo.h>
     23#define __USE_GNU
    2024#include <signal.h>
    21 }
    22 
    23 #define __CFA_DEFAULT_PREEMPTION__ 10
     25#undef __USE_GNU
     26#include <stdio.h>
     27#include <string.h>
     28#include <unistd.h>
     29}
     30
     31
     32#ifdef __USE_STREAM__
     33#include "fstream"
     34#endif
     35
     36#define __CFA_DEFAULT_PREEMPTION__ 10000
    2437
    2538__attribute__((weak)) unsigned int default_preemption() {
     
    2740}
    2841
     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
    2945static void preempt( processor   * this );
    3046static void timeout( thread_desc * this );
    3147
     48void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );
     49void sigHandler_alarm    ( __CFA_SIGPARMS__ );
     50void sigHandler_segv     ( __CFA_SIGPARMS__ );
     51void sigHandler_abort    ( __CFA_SIGPARMS__ );
     52
     53static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
     54LIB_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
     62
    3263//=============================================================================================
    3364// Kernel Preemption logic
    3465//=============================================================================================
    3566
    36 void kernel_start_preemption() {
    37 
    38 }
    39 
    4067void tick_preemption() {
     68        // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Ticking preemption\n" );
     69
    4170        alarm_list_t * alarms = &systemProcessor->alarms;
    4271        __cfa_time_t currtime = __kernel_get_time();
    4372        while( alarms->head && alarms->head->alarm < currtime ) {
    4473                alarm_node_t * node = pop(alarms);
     74                // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking %p\n", node );
     75
    4576                if( node->kernel_alarm ) {
    4677                        preempt( node->proc );
     
    5081                }
    5182
     83                verify( validate( alarms ) );
     84
    5285                if( node->period > 0 ) {
    53                         node->alarm += node->period;
     86                        node->alarm = currtime + node->period;
    5487                        insert( alarms, node );
    5588                }
     
    6295                __kernel_set_timer( alarms->head->alarm - currtime );
    6396        }
     97
     98        verify( validate( alarms ) );
     99        // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking preemption done\n" );
    64100}
    65101
    66102void update_preemption( processor * this, __cfa_time_t duration ) {
    67         //     assert( THREAD_GETMEM( disableInt ) && THREAD_GETMEM( disableIntCnt ) == 1 );
     103        LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Processor : %p updating preemption to %lu\n", this, duration );
     104
    68105        alarm_node_t * alarm = this->preemption_alarm;
     106        duration *= 1000;
    69107
    70108        // Alarms need to be enabled
     
    89127}
    90128
     129//=============================================================================================
     130// Kernel Signal Tools
     131//=============================================================================================
     132
     133LIB_DEBUG_DO( static thread_local void * last_interrupt = 0; )
     134
     135extern "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
     161static 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
     171static 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
     181static inline bool preemption_ready() {
     182        return disable_preempt_count == 0 && !preemption_in_progress;
     183}
     184
     185static inline void defer_ctxSwitch() {
     186        this_processor->pending_preemption = true;
     187}
     188
     189static inline void defer_alarm() {
     190        systemProcessor->pending_alarm = true;
     191}
     192
     193static void preempt( processor * this ) {
     194        pthread_kill( this->kernel_thread, SIGUSR1 );
     195}
     196
     197static void timeout( thread_desc * this ) {
     198        //TODO : implement waking threads
     199}
     200
     201//=============================================================================================
     202// Kernel Signal Startup/Shutdown logic
     203//=============================================================================================
     204
     205static pthread_t alarm_thread;
     206void * alarm_loop( __attribute__((unused)) void * args );
     207
     208void 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
     219void 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
    91232void ?{}( preemption_scope * this, processor * proc ) {
    92233        (&this->alarm){ proc };
     
    97238
    98239void ^?{}( preemption_scope * this ) {
     240        disable_interrupts();
     241
    99242        update_preemption( this->proc, 0 );
    100243}
    101244
    102245//=============================================================================================
    103 // Kernel Signal logic
    104 //=============================================================================================
    105 
    106 static inline bool preemption_ready() {
    107         return this_processor->disable_preempt_count == 0;
    108 }
    109 
    110 static inline void defer_ctxSwitch() {
    111         this_processor->pending_preemption = true;
    112 }
    113 
    114 static inline void defer_alarm() {
    115         systemProcessor->pending_alarm = true;
    116 }
    117 
    118 void sigHandler_ctxSwitch( __attribute__((unused)) int sig ) {
     246// Kernel Signal Handlers
     247//=============================================================================================
     248
     249void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
     250        LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); )
    119251        if( preemption_ready() ) {
    120                 ScheduleInternal( this_processor->current_thread );
     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 );
    121257        }
    122258        else {
     
    125261}
    126262
    127 void 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 
    137 static void preempt( processor * this ) {
    138         pthread_kill( this->kernel_thread, SIGUSR1 );
    139 }
    140 
    141 static void timeout( thread_desc * this ) {
    142         //TODO : implement waking threads
    143 }
     263void * 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
     303static 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
     318typedef void (*sa_handler_t)(int);
     319
     320static 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
     340LIB_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

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

    r55a68c3 r3d4b23fa  
    2828}
    2929
    30 extern thread_local processor * this_processor;
     30extern volatile 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();
    74         this_processor->current_coroutine = thrd_c;
     73        thrd_c->last = this_coroutine;
    7574
    76         LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
     75        // LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
    7776
     77        disable_interrupts();
    7878        create_stack(&thrd_c->stack, thrd_c->stack.size);
     79        this_coroutine = thrd_c;
    7980        CtxStart(this, CtxInvokeThread);
     81        assert( thrd_c->last->stack.context );
    8082        CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context );
    8183
    8284        ScheduleThread(thrd_h);
     85        enable_interrupts( DEBUG_CTX );
    8386}
    8487
    8588void yield( void ) {
    86         ScheduleInternal( this_processor->current_thread );
     89        BlockInternal( (thread_desc *)this_thread );
    8790}
    8891
     
    9598void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    9699        // set state of current coroutine to inactive
    97         src->state = Inactive;
     100        src->state = src->state == Halted ? Halted : Inactive;
    98101        dst->state = Active;
    99102
     
    103106        // set new coroutine that the processor is executing
    104107        // and context switch to it
    105         this_processor->current_coroutine = dst;
     108        this_coroutine = dst;
     109        assert( src->stack.context );
    106110        CtxSwitch( src->stack.context, dst->stack.context );
    107         this_processor->current_coroutine = src;
     111        this_coroutine = src;
    108112
    109113        // set state of new coroutine to active
    110         dst->state = Inactive;
     114        dst->state = dst->state == Halted ? Halted : Inactive;
    111115        src->state = Active;
    112116}
  • src/libcfa/exception.c

    r55a68c3 r3d4b23fa  
    1010// Created On       : Mon Jun 26 15:13:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Nov 26 15:11:00 2017
    13 // Update Count     : 0
     12// Last Modified On : Tus Jul 11 16:36:00 2017
     13// Update Count     : 1
    1414//
    1515
     
    4444// RESUMPTION ================================================================
    4545
    46 void __cfaehm__throw_resumption(exception * except) {
     46void __cfaehm__throw_resume(exception * except) {
    4747
    4848        // DEBUG
     
    6565
    6666        // Fall back to termination:
    67         __cfaehm__throw_termination(except);
     67        __cfaehm__throw_terminate(except);
    6868        // TODO: Default handler for resumption.
    6969}
     
    111111}
    112112
    113 void __cfaehm__throw_termination( exception * val ) {
     113void __cfaehm__throw_terminate( 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_termination(void) {
     149void __cfaehm__rethrow_terminate(void) {
    150150        // DEBUG
    151151        printf("Rethrowing termination exception\n");
    152152
    153         __cfaehm__throw_termination(&shared_stack.current_exception);
     153        __cfaehm__throw_terminate(&shared_stack.current_exception);
    154154}
    155155
  • src/libcfa/exception.h

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

    r55a68c3 r3d4b23fa  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul  1 16:37:53 2017
    13 // Update Count     : 112
     12// Last Modified On : Fri Jul  7 08:32:38 2017
     13// Update Count     : 117
    1414//
    1515
    16 #ifndef __FSTREAM_H__
    17 #define __FSTREAM_H__
     16#pragma once
    1817
    1918#include "iostream"
    2019
    21 enum { separateSize = 16 };
     20enum { sepSize = 16 };
    2221struct ofstream {
    2322        void * file;
    2423        _Bool sepDefault;
    2524        _Bool sepOnOff;
    26         _Bool lastSepOn;
     25        _Bool sawNL;
    2726        const char * sepCur;
    28         char separator[separateSize];
    29         char tupleSeparator[separateSize];
     27        char separator[sepSize];
     28        char tupleSeparator[sepSize];
    3029}; // ofstream
    3130
     
    3635const char * sepGetCur( ofstream * );
    3736void sepSetCur( ofstream *, const char * );
    38 _Bool lastSepOn( ofstream * );
     37_Bool getNL( ofstream * );
     38void setNL( ofstream *, _Bool );
    3939
    4040// public
     
    7575extern ifstream * sin;
    7676
    77 #endif // __FSTREAM_H__
    78 
    7977// Local Variables: //
    8078// mode: c //
  • src/libcfa/fstream.c

    r55a68c3 r3d4b23fa  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul  1 16:37:54 2017
    13 // Update Count     : 242
     12// Last Modified On : Thu Jul  6 18:38:25 2017
     13// Update Count     : 251
    1414//
    1515
     
    3333        this->sepDefault = sepDefault;
    3434        this->sepOnOff = sepOnOff;
    35         this->lastSepOn = false;
    3635        sepSet( this, separator );
    3736        sepSetCur( this, sepGet( this ) );
     
    4039
    4140// private
    42 _Bool lastSepOn( ofstream * os ) { return os->lastSepOn; }
    43 _Bool sepPrt( ofstream * os ) { os->lastSepOn = false; return os->sepOnOff; }
     41_Bool sepPrt( ofstream * os ) { setNL( os, false ); return os->sepOnOff; }
    4442void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; }
    4543void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; }
    4644const char * sepGetCur( ofstream * os ) { return os->sepCur; }
    4745void sepSetCur( ofstream * os, const char * sepCur ) { os->sepCur = sepCur; }
     46_Bool getNL( ofstream * os ) { return os->sawNL; }
     47void setNL( ofstream * os, _Bool state ) { os->sawNL = state; }
    4848
    4949// public
    50 void sepOn( ofstream * os ) { os->lastSepOn = true; os->sepOnOff = true; }
    51 void sepOff( ofstream * os ) { os->lastSepOn = false; os->sepOnOff = 0; }
     50void sepOn( ofstream * os ) { os->sepOnOff = ! getNL( os ); }
     51void sepOff( ofstream * os ) { os->sepOnOff = false; }
    5252
    5353_Bool sepDisable( ofstream *os ) {
    5454        _Bool temp = os->sepDefault;
    5555        os->sepDefault = false;
    56         os->lastSepOn = false;
    5756        sepReset( os );
    5857        return temp;
     
    6968void sepSet( ofstream * os, const char * s ) {
    7069        assert( s );
    71         strncpy( os->separator, s, separateSize - 1 );
    72         os->separator[separateSize - 1] = '\0';
     70        strncpy( os->separator, s, sepSize - 1 );
     71        os->separator[sepSize - 1] = '\0';
    7372} // sepSet
    7473
     
    7675void sepSetTuple( ofstream * os, const char * s ) {
    7776        assert( s );
    78         strncpy( os->tupleSeparator, s, separateSize - 1 );
    79         os->tupleSeparator[separateSize - 1] = '\0';
     77        strncpy( os->tupleSeparator, s, sepSize - 1 );
     78        os->tupleSeparator[sepSize - 1] = '\0';
    8079} // sepSet
    8180
     
    153152
    154153void open( ifstream * is, const char * name, const char * mode ) {
    155         FILE *t = fopen( name, mode );
    156         if ( t == 0 ) {                                                                         // do not change unless successful
     154        FILE *file = fopen( name, mode );
     155        if ( file == 0 ) {                                                                      // do not change unless successful
    157156                fprintf( stderr, IO_MSG "open input file \"%s\", ", name );
    158157                perror( 0 );
    159158                exit( EXIT_FAILURE );
    160159        } // if
    161         is->file = t;
     160        is->file = file;
    162161} // open
    163162
  • src/libcfa/gmp

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

    r55a68c3 r3d4b23fa  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul  2 08:42:56 2017
    13 // Update Count     : 110
     12// Last Modified On : Fri Jul  7 08:35:59 2017
     13// Update Count     : 118
    1414//
    1515
    16 #ifndef __IOSTREAM_H__
    17 #define __IOSTREAM_H__
     16#pragma once
    1817
    1918#include "iterator"
     
    2625        const char * sepGetCur( ostype * );                                     // get current separator string
    2726        void sepSetCur( ostype *, const char * );                       // set current separator string
    28         _Bool lastSepOn( ostype * );                                            // last manipulator is setOn (context sensitive)
     27        _Bool getNL( ostype * );                                                        // check newline
     28        void setNL( ostype *, _Bool );                                          // saw newline
    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 * );
     84forall( dtype ostype | ostream( ostype ) ) ostype * sep( ostype * );
     85forall( dtype ostype | ostream( ostype ) ) ostype * sepTuple( ostype * );
    8486forall( dtype ostype | ostream( ostype ) ) ostype * sepOn( ostype * );
    8587forall( dtype ostype | ostream( ostype ) ) ostype * sepOff( ostype * );
     
    137139forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_cstrC );
    138140
    139 #endif // __IOSTREAM_H
    140 
    141141// Local Variables: //
    142142// mode: c //
  • src/libcfa/iostream.c

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

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

    r55a68c3 r3d4b23fa  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 18:08:11 2016
    13 // Update Count     : 27
     12// Last Modified On : Fri Jul  7 08:38:23 2017
     13// Update Count     : 28
    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         }
    23 }
     22        } // for
     23} // for_each
    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         }
    31 }
     30        } // for
     31} // for_each_reverse
    3232
    3333// Local Variables: //
  • src/libcfa/libhdr/libalign.h

    r55a68c3 r3d4b23fa  
    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>
    3536
    36 // Minimum size used to align memory boundaries for memory allocations. 
     37// Minimum size used to align memory boundaries for memory allocations.
    3738#define libAlign() (sizeof(double))
    3839
  • src/libcfa/libhdr/libdebug.h

    r55a68c3 r3d4b23fa  
    1818
    1919#ifdef __CFA_DEBUG__
    20         #define LIB_DEBUG_DO(x) x
    21         #define LIB_NO_DEBUG_DO(x) ((void)0)
     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
    2226#else
    23         #define LIB_DEBUG_DO(x) ((void)0)
    24         #define LIB_NO_DEBUG_DO(x) x     
     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
    2533#endif
    2634
     
    5159
    5260#ifdef __CFA_DEBUG_PRINT__
    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__)
     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 );
    5969#else
    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)
     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)
    6678#endif
    6779
  • src/libcfa/limits

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

    r55a68c3 r3d4b23fa  
    1010// Created On       : Mon Apr 18 23:37:04 2016
    1111// Last Modified By : Peter A. Buhr
    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
     12// Last Modified On : Fri Jul  7 09:34:15 2017
     13// Update Count     : 61
     14//
     15
     16#pragma once
    1817
    1918extern "C" {
     
    345344long double scalbln( long double, long int );
    346345
    347 #endif // MATH_H
    348 
    349346// Local Variables: //
    350347// mode: c //
  • src/libcfa/rational

    r55a68c3 r3d4b23fa  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Mon May 15 21:30:12 2017
    15 // Update Count     : 90
     14// Last Modified On : Fri Jul  7 09:34:33 2017
     15// Update Count     : 93
    1616//
    1717
    18 #ifndef RATIONAL_H
    19 #define RATIONAL_H
     18#pragma once
    2019
    2120#include "iostream"
     
    4746// implementation
    4847
    49 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     48forall( otype RationalImpl | arithmetic( RationalImpl ) )
    5049struct Rational {
    5150        RationalImpl numerator, denominator;                            // invariant: denominator > 0
     
    5453// constructors
    5554
    56 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     55forall( otype RationalImpl | arithmetic( RationalImpl ) )
    5756void ?{}( Rational(RationalImpl) * r );
    5857
    59 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     58forall( otype RationalImpl | arithmetic( RationalImpl ) )
    6059void ?{}( Rational(RationalImpl) * r, RationalImpl n );
    6160
    62 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     61forall( otype RationalImpl | arithmetic( RationalImpl ) )
    6362void ?{}( Rational(RationalImpl) * r, RationalImpl n, RationalImpl d );
    6463
    65 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     64forall( otype RationalImpl | arithmetic( RationalImpl ) )
    6665void ?{}( Rational(RationalImpl) * r, zero_t );
    6766
    68 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     67forall( otype RationalImpl | arithmetic( RationalImpl ) )
    6968void ?{}( Rational(RationalImpl) * r, one_t );
    7069
    71 // getter for numerator/denominator
     70// numerator/denominator getter
    7271
    73 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     72forall( otype RationalImpl | arithmetic( RationalImpl ) )
    7473RationalImpl numerator( Rational(RationalImpl) r );
    7574
    76 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     75forall( otype RationalImpl | arithmetic( RationalImpl ) )
    7776RationalImpl denominator( Rational(RationalImpl) r );
    78 forall ( otype RationalImpl | arithmetic( RationalImpl ) )
     77
     78forall( otype RationalImpl | arithmetic( RationalImpl ) )
    7979[ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src );
    8080
    81 // setter for numerator/denominator
     81// numerator/denominator setter
    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
    145143
    146144// Local Variables: //
  • src/libcfa/rational.c

    r55a68c3 r3d4b23fa  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 15 21:29:23 2017
    13 // Update Count     : 149
     12// Last Modified On : Tue May 16 18:35:36 2017
     13// Update Count     : 150
    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

    r55a68c3 r3d4b23fa  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    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
     12// Last Modified On : Fri Jul  7 09:34:49 2017
     13// Update Count     : 219
     14//
     15
     16#pragma once
    1817
    1918//---------------------------------------
     
    232231void swap( T * t1, T * t2 );
    233232
    234 #endif // STDLIB_H
    235 
    236233// Local Variables: //
    237234// mode: c //
  • src/main.cc

    r55a68c3 r3d4b23fa  
    1010// Author           : Richard C. Bilson
    1111// Created On       : Fri May 15 23:12:02 2015
    12 // Last Modified By : Peter A. Buhr
    13 // Last Modified On : Thu Jun 29 12:46:50 2017
    14 // Update Count     : 441
     12// Last Modified By : Andrew Beach
     13// Last Modified On : Fri Jul  7 11:13:00 2017
     14// Update Count     : 442
    1515//
    1616
    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 
    25 using 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"
     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...
    5160
    5261using namespace std;
     
    206215                                FILE * builtins = fopen( libcfap | treep ? "../prelude/builtins.cf" : CFA_LIBDIR "/builtins.cf", "r" );
    207216                                assertf( builtins, "cannot open builtins.cf\n" );
    208                                 parse( builtins, LinkageSpec::Builtin );
     217                                parse( builtins, LinkageSpec::BuiltinCFA );
    209218                        } // if
    210219                } // if
  • src/prelude/Makefile.in

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

    r55a68c3 r3d4b23fa  
    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.66624+1.06128i 0.666239432492515+1.06127506190504i 0.666239432492515255+1.06127506190503565i
     24asin:1.5708 1.5707963267949 1.57079632679489662 0.666239+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

    r55a68c3 r3d4b23fa  
    999000
    101010000
    11 11000
    12 12000
    13 13000
    14 14000
    15 15000
    16 16000
    17 17000
    18 18000
    19 19000
    20 20000
    21 21000
    22 22000
    23 23000
    24 24000
    25 25000
    26 26000
    27 27000
    28 28000
    29 29000
    30 30000
    31 31000
    32 32000
    33 33000
    34 34000
    35 35000
    36 36000
    37 37000
    38 38000
    39 39000
    40 40000
    41 41000
    42 42000
    43 43000
    44 44000
    45 45000
    46 46000
    47 47000
    48 48000
    49 49000
    50 50000
    51 51000
    52 52000
    53 53000
    54 54000
    55 55000
    56 56000
    57 57000
    58 58000
    59 59000
    60 60000
    61 61000
    62 62000
    63 63000
    64 64000
    65 65000
    66 66000
    67 67000
    68 68000
    69 69000
    70 70000
    71 71000
    72 72000
    73 73000
    74 74000
    75 75000
    76 76000
    77 77000
    78 78000
    79 79000
    80 80000
    81 81000
    82 82000
    83 83000
    84 84000
    85 85000
    86 86000
    87 87000
    88 88000
    89 89000
    90 90000
    91 91000
    92 92000
    93 93000
    94 94000
    95 95000
    96 96000
    97 97000
    98 98000
    99 99000
    100 100000
    10111All waiter done
  • src/tests/.expect/io.txt

    r55a68c3 r3d4b23fa  
    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 3, 4, 5
     34tuples
     351, 2, 3 4, 5, 6
    3636
    37 toggle separator 
     37toggle separator
    38381.11.21.3
    39391.1+2.3i1.1-2.3i1.1-2.3i
    40  abcxyz
    41 abcxyz
     401.1+2.3i 1.1-2.3i1.1-2.3i
     411.1+2.3i 1.1-2.3i 1.1-2.3i
     421.1+2.3i1.1-2.3i 1.1-2.3i
     43abcxyz
     44abcxyz
    4245
    43 change separator 
    44 from "  "to " , $"
     46change separator
     47from " " to ", $"
    45481.1, $1.2, $1.3
    46491.1+2.3i, $1.1-2.3i, $1.1-2.3i
    47 abc, $xyz, $
    48 1, 2, 3, $3, 4, 5
     50abc, $xyz
     511, 2, 3, $4, 5, 6
    4952
    50 from ", $"to " "
     53from ", $" to " "
    51541.1 1.2 1.3
    52551.1+2.3i 1.1-2.3i 1.1-2.3i
    53 abc xyz 
    54 1, 2, 3 3, 4, 5
     56abc xyz
     571, 2, 3 4, 5, 6
    5558
    56  1 2 3
     59check sepOn/sepOff
     601 2 3
    576112 3
    58  1 2 3
    59621 2 3
    60  1 2 3
     631 2 3
    6164
     651 2 3
     66
     67check enable/disable
    6268123
    63691 23
     
    6571123
    66721 2 3
    67 123 
     73123
    68741 2 3
    6975
    70 1 2 3 3 4 5 " "
    71 1, 2, 3 3, 4, 5 ", "
    72 1, 2, 3 3, 4, 5
     761 2 3 4 5 6 " "
     771, 2, 3 4, 5, 6 " "
     781, 2, 3 4, 5, 6
    7379
    74803, 4, a, 7.2
    75813, 4, a, 7.2
    76823 4 a 7.2
    77  3 4 a 7.234a7.23 4 a 7.2
     833 4 a 7.234a7.23 4 a 7.2
    78843-4-a-7.2^3^4^3-4-a-7.2
  • src/tests/Makefile.am

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

    r55a68c3 r3d4b23fa  
    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}
    9497EXTRA_PROGRAMS = fstream_test$(EXEEXT) vector_test$(EXEEXT) \
    9598        avl_test$(EXEEXT)
     
    320323
    321324# applies to both programs
    322 EXTRA_FLAGS =
    323 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ ${EXTRA_FLAGS}
     325DEBUG_FLAGS =
     326BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ \
     327        $(am__append_2) $(am__append_3) $(am__append_4)
    324328TEST_FLAGS = $(if $(test), 2> .err/${@}.log, )
    325329AM_CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS}
     
    343347          esac; \
    344348        done; \
    345         echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tests/Makefile'; \
     349        echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tests/Makefile'; \
    346350        $(am__cd) $(top_srcdir) && \
    347           $(AUTOMAKE) --gnu src/tests/Makefile
     351          $(AUTOMAKE) --foreign src/tests/Makefile
    348352Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
    349353        @case '$?' in \
  • src/tests/io.c

    r55a68c3 r3d4b23fa  
    1010// Created On       : Wed Mar  2 16:56:02 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul  2 09:40:58 2017
    13 // Update Count     : 68
     12// Last Modified On : Thu Jul  6 23:26:12 2017
     13// Update Count     : 78
    1414//
    1515
     
    104104
    105105        sout | "tuples" | endl;
    106         [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
     106        [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
    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 | sepEnable | endl // complex without separator
    113                 | sepOn | s1 | sepOff | s2 | endl                               // local separator removal
    114                 | s1 | "" | s2 | endl;                                                  // C string 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
    115118        sout | endl;
    116119
    117120        sout | "change separator" | endl;
    118         sout | "from \" " | sepGet( sout ) | "\"";
     121        sout | "from \"" | sep | "\"";
    119122        sepSet( sout, ", $" );                                                          // change separator, maximum of 15 characters
    120         sout | "to \" " | sepGet( sout ) | "\"" | endl;
     123        sout | " to \"" | sep | "\"" | endl;
    121124        sout | f | d | ld | endl
    122125                | fc | dc | ldc | endl
     
    124127                | t1 | t2 | endl;                                                               // print tuple
    125128        sout | endl;
    126         sout | "from \"" | sepGet( sout ) | "\"";
     129        sout | "from \"" | sep | "\" ";
    127130        sepSet( sout, " " );                                                            // restore separator
    128         sout | "to \"" | sepGet( sout ) | "\"" | endl;
     131        sout | "to \"" | sep | "\"" | endl;
    129132        sout | f | d | ld | endl
    130133                | fc | dc | ldc | endl
     
    133136        sout | endl;
    134137
    135         sout | sepOn | 1 | 2 | 3 | sepOn | endl;                        // separator at start/end of line
     138        sout | "check sepOn/sepOff" | endl;
     139        sout | sepOn | 1 | 2 | 3 | sepOn | endl;                        // no separator at start/end of line
    136140        sout | 1 | sepOff | 2 | 3 | endl;                                       // locally turn off implicit separator
    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
     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
    139143        sout | 1 | 2 | 3 | endl;
    140144        sout | endl;
    141145
     146        sout | "check enable/disable" | endl;
    142147        sout | sepDisable | 1 | 2 | 3 | endl;                           // globally turn off implicit separation
    143148        sout | 1 | sepOn | 2 | 3 | endl;                                        // locally turn on implicit separator
     
    149154        sout | endl;
    150155
     156//      sout | fmt( d, "%8.3f" ) || endl;
     157//      sout | endl;
     158
    151159        sepSetTuple( sout, " " );                                                       // set tuple separator from ", " to " "
    152         sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
     160        sout | t1 | t2 | " \"" | sep | "\"" | endl;
    153161        sepSetTuple( sout, ", " );                                                      // reset tuple separator to ", "
    154         sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
     162        sout | t1 | t2 | " \"" | sep | "\"" | endl;
    155163        sout | t1 | t2 | endl;                                                          // print tuple
    156164        sout | endl;
  • src/tests/preempt_longrun/Makefile.am

    r55a68c3 r3d4b23fa  
    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=30
    19 preempt=10_000ul
     18max_time=600
     19preempt=1_000ul
    2020
    2121REPEAT = ${abs_top_srcdir}/tools/repeat -s
     
    2525CC = @CFA_BINDIR@/@CFA_NAME@
    2626
    27 TESTS = barge block create disjoint processor stack wait yield
     27TESTS = barge block create disjoint enter enter3 processor stack wait yield
    2828
    2929.INTERMEDIATE: ${TESTS}
  • src/tests/preempt_longrun/Makefile.in

    r55a68c3 r3d4b23fa  
    449449top_srcdir = @top_srcdir@
    450450repeats = 10
    451 max_time = 30
    452 preempt = 10_000ul
     451max_time = 600
     452preempt = 1_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 processor stack wait yield
     455TESTS = barge block create disjoint enter enter3 processor stack wait yield
    456456all: all-am
    457457
     
    467467          esac; \
    468468        done; \
    469         echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tests/preempt_longrun/Makefile'; \
     469        echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tests/preempt_longrun/Makefile'; \
    470470        $(am__cd) $(top_srcdir) && \
    471           $(AUTOMAKE) --gnu src/tests/preempt_longrun/Makefile
     471          $(AUTOMAKE) --foreign 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)
     665enter.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)
     672enter3.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)
    665679processor.log: processor
    666680        @p='processor'; \
  • src/tests/preempt_longrun/create.c

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

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

    r55a68c3 r3d4b23fa  
    1212}
    1313
    14 thread Worker {};
     14thread worker_t {};
    1515
    16 void main(Worker * this) {
     16void main(worker_t * 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
     30extern "C" {
     31static worker_t * workers;
     32}
     33
    3034int main(int argc, char* argv[]) {
    3135        processor p;
    3236        {
    33                 Worker w[7];
     37                worker_t w[7];
     38                workers = w;
    3439        }
    3540}
  • src/tests/preempt_longrun/yield.c

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

    r55a68c3 r3d4b23fa  
    66
    77#ifndef N
    8 #define N 100_000
     8#define N 10_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

    r55a68c3 r3d4b23fa  
    55
    66#ifndef N
    7 #define N 100_000
     7#define N 10_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

    r55a68c3 r3d4b23fa  
    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

    r55a68c3 r3d4b23fa  
    166166
    167167        # build, skipping to next test on error
    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)
     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)
    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

    r55a68c3 r3d4b23fa  
    44#include <thread>
    55
    6 // thread First;
    7 // void main(First* this);
     6thread First  { semaphore* lock; };
     7thread Second { semaphore* lock; };
    88
    9 // thread Second;
    10 // void main(Second* this);
    11 
    12 thread First  { signal_once* lock; };
    13 thread Second { signal_once* lock; };
    14 
    15 void ?{}( First * this, signal_once* lock ) { this->lock = lock; }
    16 void ?{}( Second * this, signal_once* lock ) { this->lock = lock; }
     9void ?{}( First * this, semaphore* lock ) { this->lock = lock; }
     10void ?{}( Second * this, semaphore* lock ) { this->lock = lock; }
    1711
    1812void main(First* this) {
     
    2115                yield();
    2216        }
    23         signal(this->lock);
     17        V(this->lock);
    2418}
    2519
    2620void main(Second* this) {
    27         wait(this->lock);
     21        P(this->lock);
    2822        for(int i = 0; i < 10; i++) {
    2923                sout | "Second : Suspend No." | i + 1 | endl;
     
    3428
    3529int main(int argc, char* argv[]) {
    36         signal_once lock;
     30        semaphore lock = { 0 };
    3731        sout | "User main begin" | endl;
    3832        {
  • tools/prettyprinter/Makefile.in

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