Changes in / [55a68c3:3d4b23fa]
- Files:
-
- 5 added
- 25 deleted
- 100 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.tex
r55a68c3 r3d4b23fa 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Jun 18 20:32:32201714 %% Update Count : 3 1913 %% Last Modified On : Thu Jul 13 11:44:59 2017 14 %% Update Count : 335 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 36 36 % Names used in the document. 37 37 38 \newcommand{\CFAIcon}{\text rm{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}\xspace} % Cforall symbolic name38 \newcommand{\CFAIcon}{\textsf{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}\xspace} % Cforall symbolic name 39 39 \newcommand{\CFA}{\protect\CFAIcon} % safe for section/caption 40 40 \newcommand{\CFL}{\textrm{Cforall}\xspace} % Cforall symbolic name … … 55 55 \setlength{\parindentlnth}{\parindent} 56 56 57 \newcommand{\LstKeywordStyle}[1]{{\lst@basicstyle{\lst@keywordstyle{#1}}}} 58 \newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}} 59 57 60 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly 58 61 \newlength{\columnposn} 59 62 \setlength{\gcolumnposn}{2.5in} 60 63 \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}}}} 62 65 \newcommand{\CRT}{\global\columnposn=\gcolumnposn} 63 66 … … 231 234 basicstyle=\linespread{0.9}\sf, % reduce line spacing and use sanserif font 232 235 stringstyle=\tt, % use typewriter font 233 tabsize= 4, % 4space tabbing236 tabsize=6, % N space tabbing 234 237 xleftmargin=\parindentlnth, % indent code to paragraph indentation 235 238 extendedchars=true, % allow ASCII characters in the range 128-255 -
doc/LaTeXmacros/lstlang.sty
r55a68c3 r3d4b23fa 8 8 %% Created On : Sat May 13 16:34:42 2017 9 9 %% Last Modified By : Peter A. Buhr 10 %% Last Modified On : Thu Jun 22 07:40:31201711 %% Update Count : 1 010 %% Last Modified On : Wed Jul 12 22:42:09 2017 11 %% Update Count : 12 12 12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 13 … … 112 112 finally, forall, ftype, _Generic, _Imaginary, inline, __label__, lvalue, _Noreturn, one_t, 113 113 otype, restrict, _Static_assert, throw, throwResume, trait, try, ttype, typeof, __typeof, 114 __typeof__, zero_t},114 __typeof__, with, zero_t}, 115 115 morekeywords=[2]{ 116 116 _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex, … … 118 118 moredirectives={defined,include_next}% 119 119 } 120 121 % C++ programming language 122 \lstdefinelanguage{C++}[ANSI]{C++}{} 120 123 121 124 % uC++ programming language, based on ANSI C++ -
doc/bibliography/cfa.bib
r55a68c3 r3d4b23fa 2273 2273 @manual{JavaScript, 2274 2274 keywords = {JavaScript}, 2275 contributer = {pabuhr },2275 contributer = {pabuhr@plg}, 2276 2276 title = {ECMAScript 2015 Language Specification {JavaScript}}, 2277 2277 organization= {ECAM International}, … … 2446 2446 @manual{Erlang, 2447 2447 keywords = {Erlang}, 2448 contributer = {pabuhr },2448 contributer = {pabuhr@plg}, 2449 2449 title = {Erlang Reference Manual User's Guide, Vertion 7.0}, 2450 2450 organization= {Erlang/OTP System Documentation}, … … 2771 2771 publisher = {ACM}, 2772 2772 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}, 2773 2786 } 2774 2787 … … 5052 5065 contributer = {pabuhr@plg}, 5053 5066 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}, 5055 5068 publisher = {Springer--Verlag}, 5056 year = 19 85,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} 5059 5072 } 5060 5073 -
doc/proposals/tagged-struct.txt
r55a68c3 r3d4b23fa 71 71 should be possible to do during linking. 72 72 73 If a generic/polymorphic type is tagged its tagged would then be shared 74 between all applications of that generic. Internal tags could be used to 75 seperate these structures again, however it seems in most cases simply using 76 the existing type parameters should provide the needed information. 77 73 78 74 79 Traits: … … 102 107 To allow for growth each option would have to be a structure itself. 103 108 104 Which brings us to "tagge tstruct union", ie. a union of tagged structures109 Which brings us to "tagged struct union", ie. a union of tagged structures 105 110 as opposed to tagging the union itself. This extention acts as a constraint. 106 111 If 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. 112 possible values of the union must be of that tagged type or a child type. If 113 the tagged type is omitted then they must all be tagged but of any tagged 114 type. 115 116 As a short cut union_instance->type might get the type object of the loaded 117 value. It should always be the same operation regardless so it saves 118 abritarly picking a branch of the union to get the type object. 108 119 109 120 110 Custom Type Objects (Extention):121 Type Objects Fields (Extention): 111 122 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. 123 Adding fields to the type object allows data to be shared between instances 124 of the same type. Such behaviour could be mimiced by creating a lookup 125 function on the type object pointer, but this may be cleaner and more 126 efficient. 115 127 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.) 128 The type object fields follow similar rules to the fields on the tagged 129 objects themselves, they must be additive. So any fields present on a 130 type object will be present (and in the same place) on all of its children. 118 131 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. 132 This does mean that many type object structure types will have to be auto 133 generated, and traversing up the tree might get a little wierd. That could 134 be symplified by only allowing the root type to specify fields on the type 135 object, so that the type object is consistant throughout that particular tree. 136 And hence the type_object pointers would also be consistant as the type they 137 point to would never change. 138 139 struct Example tagged { 140 tagged char const * const type_name = "Example"; 141 int data; 142 }; 143 144 Creates a tagged structure that has no parent, stores an integer and the type 145 object also has an extra field that stores a string on the type object. 146 This can be accessed by using member access on the type object, as a regular 147 structure. 148 149 Type object fields will have to allow initialization on their declaration, 150 and declarations of children as well, as they are not assotiated with the 151 later instances of the tagged structure. 152 153 ... 154 tagged void (*dtor)(tagged Example * this); 155 ... 156 157 Sub-Extention, not sure how it would work but some way to have a "dynamic" 158 field that is considered the type of the current tagged struct might be useful 159 for things like specifying a deconstructor. In this case, the following code 160 will clean up any child type of Example: 161 162 Example * ex = get_some_example(); 163 ex->type->dtor(ex); -
doc/user/Makefile
r55a68c3 r3d4b23fa 1 1 ## Define the appropriate configuration variables. 2 2 3 TeXLIB = .:../LaTeXmacros:../ LaTeXmacros/listings:../LaTeXmacros/enumitem:../bibliography/:3 TeXLIB = .:../LaTeXmacros:../bibliography/: 4 4 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error 5 5 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex -
doc/user/user.tex
r55a68c3 r3d4b23fa 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Jul 2 09:49:56201714 %% Update Count : 2 50313 %% Last Modified On : Thu Jul 13 11:44:57 2017 14 %% Update Count : 2690 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 57 57 \CFAStyle % use default CFA format-style 58 58 59 \lstnewenvironment{C++}[1][] 60 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{®}{®}#1}} 61 {} 62 59 63 % inline code ©...© (copyright symbol) emacs: C-q M-) 60 64 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. … … 137 141 138 142 \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.143 The syntax of \CFA builds from C and should look immediately familiar to C/\Index*[C++]{\CC{}} programmers. 140 144 % 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 Cperformance.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. 146 Like C, \CFA is a statically typed, procedural (non-\Index{object-oriented}) language with a low-overhead runtime, meaning there is no global \Index{garbage-collection}, but \Index{regional garbage-collection}\index{garbage-collection!regional} is possible. 143 147 The primary new features include parametric-polymorphic routines and types, exceptions, concurrency, and modules. 144 148 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. 149 One of the main design philosophies of \CFA is to ``\Index{describe not prescribe}'', which means \CFA tries to provide a pathway from low-level C programming to high-level \CFA programming, but it does not force programmers to ``do the right thing''. 150 Programmers can cautiously add \CFA extensions to their C programs in any order and at any time to incrementally move towards safer, higher-level programming. 151 A programmer is always free to reach back to C from \CFA, for any reason, and in many cases, new \CFA features can be locally switched back to there C counterpart. 152 There is no notion or requirement for \emph{rewriting} a legacy C program in \CFA; 153 instead, a programmer evolves a legacy program into \CFA by incrementally incorporating \CFA features. 154 As well, new programs can be written in \CFA using a combination of C and \CFA features. 155 156 \Index*[C++]{\CC{}} had a similar goal 30 years ago, allowing object-oriented programming to be incrementally added to C. 157 However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that cannot be updated, and active divergence of the language model from C, all of which requires significant effort and training to incrementally add \CC to a C-based project. 152 158 In contrast, \CFA has 30 years of hindsight and a clean starting point. 153 159 … … 156 162 \begin{quote2} 157 163 \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} 169 166 #include <stdio.h>§\indexc{stdio.h}§ 170 167 … … 173 170 ®printf( "%d %d %d\n", x, y, z );® 174 171 } 175 \end{ lstlisting}172 \end{cfa} 176 173 & 177 \begin{lstlisting} 174 \begin{cfa} 175 #include <fstream>§\indexc{fstream}§ 176 177 int main( void ) { 178 int x = 0, y = 1, z = 2; 179 ®sout | x | y | z | endl;®§\indexc{sout}§ 180 } 181 \end{cfa} 182 & 183 \begin{cfa} 178 184 #include <iostream>§\indexc{iostream}§ 179 185 using namespace std; … … 182 188 ®cout<<x<<" "<<y<<" "<<z<<endl;® 183 189 } 184 \end{ lstlisting}190 \end{cfa} 185 191 \end{tabular} 186 192 \end{quote2} 187 193 While 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}). 188 194 195 \subsection{Background} 196 189 197 This document is a programmer reference-manual for the \CFA programming language. 190 198 The manual covers the core features of the language and runtime-system, with simple examples illustrating syntax and semantics of each feature. 191 199 The 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 mayrefer to the \CFA Programming Language Specification for details about the language syntax and semantics.200 A reader should already have an intermediate knowledge of control flow, data structures, and concurrency issues to understand the ideas presented, as well as some experience programming in C/\CC. 201 Implementers should refer to the \CFA Programming Language Specification for details about the language syntax and semantics. 194 202 Changes to the syntax and additional features are expected to be included in later revisions. 195 203 … … 200 208 This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more. 201 209 Even 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 thelanguage of choice.210 For system programming, where direct access to hardware, storage management, and real-time issues are a requirement, C is usually the only language of choice. 203 211 The 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. 204 212 As well, for 30 years, C has been the number 1 and 2 most popular programming language: … … 216 224 \end{center} 217 225 Hence, 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 sitappeal is not diminishing.219 Unfortunately, C has too many problems and omissions to make it anacceptable programming language for modern needs.220 221 As stated, the goal of the \CFA project is to engineer modern language 226 Love it or hate it, C has been an important and influential part of computer science for 40 years and its appeal is not diminishing. 227 Unfortunately, C has many problems and omissions that make it an unacceptable programming language for modern needs. 228 229 As stated, the goal of the \CFA project is to engineer modern language-features into C in an evolutionary rather than revolutionary way. 222 230 \CC~\cite{C++14,C++} is an example of a similar project; 223 however, it largely extended the language, and did not address manyexisting problems.\footnote{%231 however, it largely extended the C language, and did not address most of C's existing problems.\footnote{% 224 232 Two 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 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. 226 234 \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 ofgarbage collection.235 These languages have different syntax and semantics from C, do not interoperate directly with C, and are not systems languages because of restrictive memory-management or garbage collection. 228 236 As 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 anew programming language.230 231 The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fix ing some of the well known C problems and containing many modern languagefeatures.237 These costs can be prohibitive for many companies with a large software-base in C/\CC, and a significant number of programmers require retraining to the new programming language. 238 239 The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fixes many of the well known C problems while containing modern language-features. 232 240 Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers; 233 241 as a result, it will fade into disuse. 234 242 Considering 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 236 While some may argue that modern language 243 While \Index*[C11]{\Celeven{}} made a few simple extensions to the language, nothing was added to address existing problems in the language or to augment the language with modern language-features. 244 While some may argue that modern language-features may make C complex and inefficient, it is clear a language without modern capabilities is insufficient for the advanced programming problems existing today. 237 245 238 246 239 247 \section{History} 240 248 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.249 The \CFA project started with \Index*{K-W C}~\cite{Buhr94a,Till89}, which extended C with new declaration syntax, multiple return values from routines, and advanced assignment capabilities using the notion of tuples. 242 250 (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): 251 The first \CFA implementation of these extensions was by Esteves~\cite{Esteves04}. 252 253 The signature feature of \CFA is \Index{overload}able \Index{parametric-polymorphic} functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a ©forall© clause (giving the language its name): 245 254 \begin{lstlisting} 246 255 ®forall( otype T )® T identity( T val ) { return val; } … … 250 259 \CFA{}\hspace{1pt}'s polymorphism was originally formalized by Ditchfiled~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}. 251 260 However, 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.261 As the saying goes, ``\Index*{What goes around, comes around.}'', and there is now renewed interest in the C programming language because of legacy code-bases, so the \CFA project has been restarted. 253 262 254 263 … … 257 266 258 267 \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.268 The most important feature of \Index{interoperability} is using the same \Index{calling convention}s, so there is no complex interface or overhead to call existing C routines. 260 269 This feature allows \CFA programmers to take advantage of the existing panoply of C libraries to access thousands of external software features. 261 270 Language developers often state that adequate \Index{library support} takes more work than designing and implementing the language itself. 262 271 Fortunately, \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 withlittle cost.272 Hence, \CFA begins by leveraging the large repository of C libraries at little cost. 264 273 265 274 \begin{comment} … … 304 313 \end{comment} 305 314 306 However, it is necessary to differentiate between C and \CFA code because of name overloading, as for \CC.315 However, it is necessary to differentiate between C and \CFA code because of name \Index{overload}ing, as for \CC. 307 316 For 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 commonname ©abs©:317 Whereas, \CFA wraps each of these routines into ones with the overloaded name ©abs©: 309 318 \begin{cfa} 310 319 char abs( char ); … … 326 335 Hence, 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. 327 336 There 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}.337 This example strongly illustrates a core idea in \CFA: \emph{the \Index{power of a name}}. 329 338 The 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 besufficient 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 shouldnot be underestimated.332 333 334 \section[Compiling CFA Program]{Compiling\CFA Program}339 Hence, knowing the name ©abs© is sufficient to apply it to any type where it is applicable. 340 The time savings and safety of using one name uniformly versus $N$ unique names cannot be underestimated. 341 342 343 \section[Compiling a CFA Program]{Compiling a \CFA Program} 335 344 336 345 The command ©cfa© is used to compile \CFA program(s), and is based on the GNU \Indexc{gcc} command, \eg: 337 346 \begin{cfa} 338 cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA §-files [ assembler/loader-files ]347 cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA{}§-files [ assembler/loader-files ] 339 348 \end{cfa} 340 349 \CFA programs having the following ©gcc© flags turned on: … … 359 368 \Indexc{-debug}\index{compilation option!-debug@©-debug©} 360 369 The 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.370 The debug version performs runtime checks to help during the debugging phase of a \CFA program, but can substantially slow program execution. 362 371 The runtime checks should only be removed after the program is completely debugged. 363 372 \textbf{This option is the default.} … … 415 424 \end{description} 416 425 These preprocessor variables allow conditional compilation of programs that must work differently in these situations. 417 For example, to toggle between C and \CFA extensions, us ingthe following:426 For example, to toggle between C and \CFA extensions, use the following: 418 427 \begin{cfa} 419 428 #ifndef __CFORALL__ … … 426 435 427 436 428 \section{Constant sUnderscores}429 430 Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, \eg:437 \section{Constant Underscores} 438 439 Numeric constants are extended to allow \Index{underscore}s\index{constant!underscore}, \eg: 431 440 \begin{cfa} 432 441 2®_®147®_®483®_®648; §\C{// decimal constant}§ … … 441 450 L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§; §\C{// wide character constant}§ 442 451 \end{cfa} 443 The rules for placement of underscores is as follows:444 \begin{enumerate} 452 The rules for placement of underscores are: 453 \begin{enumerate}[topsep=5pt,itemsep=5pt,parsep=0pt] 445 454 \item 446 455 A sequence of underscores is disallowed, \eg ©12__34© is invalid. … … 463 472 \label{s:BackquoteIdentifiers} 464 473 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. 475 Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism: 466 476 \begin{cfa} 467 477 int ®`®otype®`® = 3; §\C{// make keyword an identifier}§ … … 491 501 492 502 493 \section{ Labelled Continue/Break}503 \section{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break}}{Labelled continue / break}} 494 504 495 505 While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure. 496 506 Unfortunately, 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}.507 To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@\lstinline $continue$!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@\lstinline $break$!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85}. 498 508 For both ©continue© and ©break©, the target label must be directly associated with a ©for©, ©while© or ©do© statement; 499 509 for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement. 500 510 \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©. 501 511 The innermost loop has 7 exit points, which cause resumption or termination of one or more of the 7 \Index{nested control-structure}s. 512 Java supports both labelled ©continue© and ©break© statements. 502 513 503 514 \begin{figure} … … 622 633 623 634 624 \section{ Switch Statement}635 \section{\texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}} 625 636 626 637 C allows a number of questionable forms for the ©switch© statement: … … 663 674 ®// open input file 664 675 ®} else if ( argc == 2 ) { 665 ®// open input file 676 ®// open input file (duplicate) 666 677 667 678 ®} else { … … 676 687 \begin{cfa} 677 688 switch ( i ) { 678 case 1: case 3: case 5:// odd values679 // sameaction689 ®case 1: case 3: case 5:® // odd values 690 // odd action 680 691 break; 681 case 2: case 4: case 6:// even values682 // sameaction692 ®case 2: case 4: case 6:® // even values 693 // even action 683 694 break; 684 695 } … … 686 697 However, this situation is handled in other languages without fall-through by allowing a list of case values. 687 698 While 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 forgetthe ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through.699 Hence, default fall-through semantics results in a large number of programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through. 689 700 690 701 \item … … 770 781 and 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. 771 782 \end{itemize} 772 These observations help to put the \CFA changes to the ©switch© into perspective.783 These observations put into perspective the \CFA changes to the ©switch©. 773 784 \begin{enumerate} 774 785 \item … … 791 802 case 7: 792 803 ... 793 ®break® §\C{// explicit end of switch}§804 ®break® §\C{// redundant explicit end of switch}§ 794 805 default: 795 806 j = 3; … … 797 808 \end{cfa} 798 809 Like the ©switch© statement, the ©choose© statement retains the fall-through semantics for a list of ©case© clauses; 799 theimplicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause.800 Theexplicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement.810 An implicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause. 811 An explicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement. 801 812 As well, allowing an explicit ©break© from the ©choose© is a carry over from the ©switch© statement, and expected by C programmers. 802 813 \item … … 827 838 828 839 829 \section{ Case Clause}840 \section{\texorpdfstring{\LstKeywordStyle{case} Clause}{case Clause}} 830 841 831 842 C restricts the ©case© clause of a ©switch© statement to a single value. … … 900 911 \begin{cfa} 901 912 case ®1~5, 12~21, 35~42®: 913 \end{cfa} 914 915 916 \section{\texorpdfstring{\LstKeywordStyle{with} Clause / Statement}{with Clause / Statement}} 917 \label{s:WithClauseStatement} 918 919 In \Index{object-oriented} programming, there is an implicit first parameter, often names \textbf{©self©} or \textbf{©this©}, which is elided. 920 \begin{C++} 921 class C { 922 int i, j; 923 int mem() { ®// implicit "this" parameter 924 i = 1; ®// this->i 925 ® j = 3; ®// this->j 926 ® } 927 } 928 \end{C++} 929 Since CFA is non-object-oriented, the equivalent object-oriented program looks like: 930 \begin{cfa} 931 struct C { 932 int i, j; 933 }; 934 int mem( C &this ) { // explicit "this" parameter 935 ®this.®i = 1; // "this" is not elided 936 ®this.®j = 2; 937 } 938 \end{cfa} 939 but it is cumbersome having to write "©this.©" many times in a member. 940 \CFA provides a ©with© clause/statement to elided the "©this.©". 941 \begin{cfa} 942 int mem( C &this ) ®with this® { 943 i = 1; ®// this.i 944 ® j = 2; ®// this.j 945 ®} 946 \end{cfa} 947 which extends to multiple routine parameters: 948 \begin{cfa} 949 struct D { 950 double m, n; 951 }; 952 int mem2( C &this1, D &this2 ) ®with this1, this2® { 953 i = 1; j = 2; 954 m = 1.0; n = 2.0; 955 } 956 \end{cfa} 957 The ©with© clause/statement comes from Pascal~\cite[\S~4.F]{Pascal}. 958 959 The statement form is used within a block: 960 \begin{cfa} 961 int foo() { 962 struct S1 { ... } s1; 963 struct S2 { ... } s2; 964 ®with s1® { 965 // access fields of s1 without qualification 966 ®with s2® { // nesting 967 // access fields of s2 without qualification 968 } 969 } 970 ®with s1, s2® { 971 // access unambiguous fields of s1 and s2 without qualification 972 } 973 } 974 \end{cfa} 975 976 Names clashes when opening multiple structures are ambiguous. 977 \begin{cfa} 978 struct A { int i; int j; } a, c; 979 struct B { int i; int k; } b, c; 980 ®with a, b® { 981 j + k; §\C{// unambiguous}§ 982 i; §\C{// ambiguous}§ 983 a.i + b.i; §\C{// unambiguous}§ 984 } 985 ®with c® { §\C{// ambiguous}§ 986 // ... 987 } 902 988 \end{cfa} 903 989 … … 1136 1222 1137 1223 1138 \section{Pointer /Reference}1224 \section{Pointer / Reference} 1139 1225 1140 1226 C provides a \newterm{pointer type}; … … 2450 2536 \end{cfa} 2451 2537 \\ 2452 \begin{cfa}[ mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]2538 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2453 2539 1® ®2® ®3 2454 2540 \end{cfa} 2455 2541 & 2456 \begin{cfa}[ mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]2542 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2457 2543 1 2 3 2458 2544 \end{cfa} … … 2461 2547 The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators. 2462 2548 Similar 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 ] ]; 2465 2551 sout | t1 | t2 | endl; §\C{// print tuples}§ 2466 2552 \end{cfa} 2467 \begin{cfa}[ mathescape=off,showspaces=true,belowskip=0pt]2468 1®, ®2®, ®3 3®, ®4®, ®52553 \begin{cfa}[showspaces=true,aboveskip=0pt] 2554 1®, ®2®, ®3 4®, ®5®, ®6 2469 2555 \end{cfa} 2470 2556 Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority overloadable operator, other than assignment. … … 2485 2571 \\ 2486 2572 & 2487 \begin{cfa}[ mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]2573 \begin{cfa}[showspaces=true,aboveskip=0pt] 2488 2574 3 3 12 0 3 1 2 2489 2575 \end{cfa} … … 2503 2589 sout | 1 | 2 | 3 | endl; 2504 2590 \end{cfa} 2505 \begin{cfa}[ mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]2591 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2506 2592 1 2 3 2507 2593 \end{cfa} … … 2570 2656 \subsection{Manipulator} 2571 2657 2572 The following routines and \CC-style \Index{manipulator}s control implicit seperation.2658 The following \CC-style \Index{manipulator}s and routines control implicit seperation. 2573 2659 \begin{enumerate} 2574 2660 \item 2575 Routines \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep Get}\index{manipulator!sepGet@©sepGet©} set and get the separator string.2661 Routines \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep}\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string. 2576 2662 The 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] 2578 2664 sepSet( sout, ", $" ); §\C{// set separator from " " to ", \$"}§ 2579 sout | 1 | 2 | 3 | " \"" | ®sep Get( sout )® | "\"" | endl;2665 sout | 1 | 2 | 3 | " \"" | ®sep® | "\"" | endl; 2580 2666 \end{cfa} 2581 2667 %$ … … 2584 2670 \end{cfa} 2585 2671 %$ 2586 \begin{cfa}[ mathescape=off,aboveskip=0pt,belowskip=0pt]2672 \begin{cfa}[belowskip=0pt] 2587 2673 sepSet( sout, " " ); §\C{// reset separator to " "}§ 2588 2674 sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\"" | endl; 2589 2675 \end{cfa} 2590 \begin{cfa}[ mathescape=off,showspaces=true,aboveskip=0pt]2676 \begin{cfa}[showspaces=true,aboveskip=0pt] 2591 2677 1® ®2® ®3 ®" "® 2592 2678 \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] 2681 char store[®sepSize®]; §\C{// sepSize is the maximum separator size}§ 2682 strcpy( store, sepGet( sout ) ); 2683 sepSet( sout, "_" ); 2684 sout | 1 | 2 | 3 | endl; 2685 \end{cfa} 2686 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2687 1®_®2®_®3 2688 \end{cfa} 2689 \begin{cfa}[belowskip=0pt] 2690 sepSet( sout, store ); 2691 sout | 1 | 2 | 3 | endl; 2692 \end{cfa} 2693 \begin{cfa}[showspaces=true,aboveskip=0pt] 2694 1® ®2® ®3 2695 \end{cfa} 2696 2697 \item 2698 Routine \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepTuple}\index{manipulator!sepTuple@©sepTuple©}/\Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string. 2596 2699 The 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] 2598 2701 sepSetTuple( sout, " " ); §\C{// set tuple separator from ", " to " "}§ 2599 sout | t1 | t2 | " \"" | ®sep GetTuple( 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]2702 sout | t1 | t2 | " \"" | ®sepTuple® | "\"" | endl; 2703 \end{cfa} 2704 \begin{cfa}[showspaces=true,aboveskip=0pt] 2705 1 2 3 4 5 6 ®" "® 2706 \end{cfa} 2707 \begin{cfa}[belowskip=0pt] 2605 2708 sepSetTuple( sout, ", " ); §\C{// reset tuple separator to ", "}§ 2606 2709 sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\"" | endl; 2607 2710 \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] 2712 1, 2, 3 4, 5, 6 ®", "® 2713 \end{cfa} 2714 As for ©sepGet©, ©sepGetTuple© can be use to store a tuple separator and then restore it. 2715 2716 \item 2717 Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items. 2718 \begin{cfa}[belowskip=0pt] 2719 sout | sepDisable | 1 | 2 | 3 | endl; §\C{// globally turn off implicit separator}§ 2720 \end{cfa} 2721 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2641 2722 123 2642 2723 \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] 2725 sout | sepEnable | 1 | 2 | 3 | endl; §\C{// globally turn on implicit separator}§ 2651 2726 \end{cfa} 2652 2727 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 2653 2728 1 2 3 2654 2729 \end{cfa} 2730 2731 \item 2732 Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item. 2733 \begin{cfa}[belowskip=0pt] 2734 sout | 1 | sepOff | 2 | 3 | endl; §\C{// locally turn off implicit separator}§ 2735 \end{cfa} 2736 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2737 12 3 2738 \end{cfa} 2739 \begin{cfa}[belowskip=0pt] 2740 sout | sepDisable | 1 | sepOn | 2 | 3 | endl; §\C{// locally turn on implicit separator}§ 2741 \end{cfa} 2742 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2743 1 23 2744 \end{cfa} 2745 The tuple separator also responses to being turned on and off. 2746 \begin{cfa}[belowskip=0pt] 2747 sout | t1 | sepOff | t2 | endl; §\C{// locally turn on/off implicit separator}§ 2748 \end{cfa} 2749 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2750 1, 2, 34, 5, 6 2751 \end{cfa} 2752 ©sepOn© \emph{cannot} be used to start/end a line with a separator because separators do not appear at the start/end of a line; 2753 use ©sep© to accomplish this functionality. 2754 \begin{cfa}[belowskip=0pt] 2755 sout | sepOn | 1 | 2 | 3 | sepOn | endl ; §\C{// sepOn does nothing at start/end of line}§ 2756 \end{cfa} 2757 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2758 1 2 3 2759 \end{cfa} 2760 \begin{cfa}[belowskip=0pt] 2761 sout | sep | 1 | 2 | 3 | sep | endl ; §\C{// use sep to print separator at start/end of line}§ 2762 \end{cfa} 2763 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2764 ® ®1 2 3® ® 2765 \end{cfa} 2655 2766 \end{enumerate} 2656 2767 2657 2768 \begin{comment} 2658 2769 #include <fstream> 2770 #include <string.h> // strcpy 2659 2771 2660 2772 int main( void ) { 2661 2773 int x = 1, y = 2, z = 3; 2662 2774 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 ] ]; 2664 2776 sout | t1 | t2 | endl; // print tuples 2665 2777 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl; … … 2675 2787 2676 2788 sepSet( sout, ", $" ); // set separator from " " to ", $" 2677 sout | 1 | 2 | 3 | " \"" | sep Get( sout )| "\"" | endl;2789 sout | 1 | 2 | 3 | " \"" | sep | "\"" | endl; 2678 2790 sepSet( sout, " " ); // reset separator to " " 2679 2791 sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl; 2680 2792 2681 sout | sepOn | 1 | 2 | 3 | sepOn | endl; // separator at start of line2682 s out | 1 | sepOff | 2 | 3 | endl; // locally turn off implicit separator2683 2684 sout | sepDisable | 1 | 2 | 3 | endl; // globally turn off implicit separation2685 s out | 1 | sepOn | 2 | 3 | endl; // locally turn on implicit separator2686 sout | sepEnable | 1 | 2 | 3 | endl; // globally turn on implicit separation2793 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; 2687 2799 2688 2800 sepSetTuple( sout, " " ); // set tuple separator from ", " to " " 2689 sout | t1 | t2 | " \"" | sep GetTuple( sout )| "\"" | endl;2801 sout | t1 | t2 | " \"" | sepTuple | "\"" | endl; 2690 2802 sepSetTuple( sout, ", " ); // reset tuple separator to ", " 2691 2803 sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl; 2692 2804 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 2695 2815 } 2696 2816 … … 5224 5344 5225 5345 5226 \section{\ CFA Keywords}5346 \section{\texorpdfstring{\CFA Keywords}{Cforall Keywords}} 5227 5347 \label{s:CFAKeywords} 5228 5348 5349 \CFA introduces the following new keywords. 5350 5229 5351 \begin{quote2} 5230 \begin{tabular}{llll }5352 \begin{tabular}{lllll} 5231 5353 \begin{tabular}{@{}l@{}} 5232 ©_A T© \\5354 ©_At© \\ 5233 5355 ©catch© \\ 5234 5356 ©catchResume© \\ 5235 5357 ©choose© \\ 5236 5358 ©coroutine© \\ 5237 ©disable© \\5238 5359 \end{tabular} 5239 5360 & 5240 5361 \begin{tabular}{@{}l@{}} 5362 ©disable© \\ 5241 5363 ©dtype© \\ 5242 5364 ©enable© \\ 5243 5365 ©fallthrough© \\ 5244 5366 ©fallthru© \\ 5245 ©finally© \\5246 ©forall© \\5247 5367 \end{tabular} 5248 5368 & 5249 5369 \begin{tabular}{@{}l@{}} 5370 ©finally© \\ 5371 ©forall© \\ 5250 5372 ©ftype© \\ 5251 5373 ©lvalue© \\ 5252 5374 ©monitor© \\ 5375 \end{tabular} 5376 & 5377 \begin{tabular}{@{}l@{}} 5253 5378 ©mutex© \\ 5254 5379 ©one_t© \\ 5255 5380 ©otype© \\ 5381 ©throw© \\ 5382 ©throwResume© \\ 5256 5383 \end{tabular} 5257 5384 & 5258 5385 \begin{tabular}{@{}l@{}} 5259 ©throw© \\5260 ©throwResume© \\5261 5386 ©trait© \\ 5262 5387 ©try© \\ 5263 5388 ©ttype© \\ 5264 5389 ©zero_t© \\ 5390 \\ 5265 5391 \end{tabular} 5266 5392 \end{tabular} … … 5548 5674 // C unsafe allocation 5549 5675 extern "C" { 5550 void * mall ac( size_t size );§\indexc{memset}§5676 void * malloc( size_t size );§\indexc{memset}§ 5551 5677 void * calloc( size_t dim, size_t size );§\indexc{calloc}§ 5552 5678 void * realloc( void * ptr, size_t size );§\indexc{realloc}§ -
src/CodeGen/CodeGenerator.cc
r55a68c3 r3d4b23fa 14 14 // 15 15 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... 32 18 33 19 #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... 38 36 39 37 using namespace std; -
src/CodeGen/CodeGenerator.h
r55a68c3 r3d4b23fa 17 17 #define CODEGENV_H 18 18 19 #include <list> 19 #include <list> // for list 20 #include <ostream> // for ostream, operator<< 21 #include <string> // for string 20 22 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 29 26 30 27 namespace CodeGen { -
src/CodeGen/FixMain.cc
r55a68c3 r3d4b23fa 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // FixMain.cc -- 7 // FixMain.cc -- 8 8 // 9 9 // Author : Thierry Delisle 10 10 // 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 : 13 13 // Update Count : 0 14 14 // 15 15 16 16 17 #include "FixMain.h" 17 #include "FixMain.h" 18 18 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<< 21 23 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 24 27 25 28 namespace CodeGen { 26 29 bool FixMain::replace_main = false; 27 30 std::unique_ptr<FunctionDecl> FixMain::main_signature = nullptr; 28 29 void FixMain::registerMain(FunctionDecl* functionDecl) 31 32 void FixMain::registerMain(FunctionDecl* functionDecl) 30 33 { 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); 33 36 } 34 37 main_signature.reset( functionDecl->clone() ); -
src/CodeGen/FixNames.cc
r55a68c3 r3d4b23fa 14 14 // 15 15 16 #include <memory>16 #include "FixNames.h" 17 17 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 25 32 26 33 namespace CodeGen { … … 42 49 main_type = new FunctionType( Type::Qualifiers(), true ), nullptr ) 43 50 }; 44 main_type->get_returnVals().push_back( 51 main_type->get_returnVals().push_back( 45 52 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) 46 53 ); … … 52 59 std::string mangle_main_args() { 53 60 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, 55 62 main_type = new FunctionType( Type::Qualifiers(), false ), nullptr ) 56 63 }; 57 main_type->get_returnVals().push_back( 64 main_type->get_returnVals().push_back( 58 65 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) 59 66 ); 60 67 61 mainDecl->get_functionType()->get_parameters().push_back( 68 mainDecl->get_functionType()->get_parameters().push_back( 62 69 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) 63 70 ); 64 71 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 ) ) ), 68 75 nullptr ) 69 76 ); … … 75 82 76 83 bool is_main(const std::string& name) { 77 static std::string mains[] = { 78 mangle_main(), 84 static std::string mains[] = { 85 mangle_main(), 79 86 mangle_main_args() 80 87 }; … … 112 119 int nargs = functionDecl->get_functionType()->get_parameters().size(); 113 120 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); 115 122 } 116 123 functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new ConstantExpr( Constant::from_int( 0 ) ) ) ); -
src/CodeGen/FixNames.h
r55a68c3 r3d4b23fa 17 17 #define FIXNAMES_H 18 18 19 #include "SynTree/SynTree.h" 19 #include <list> // for list 20 21 class Declaration; 20 22 21 23 namespace CodeGen { -
src/CodeGen/GenType.cc
r55a68c3 r3d4b23fa 14 14 // 15 15 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 19 21 #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 26 26 27 27 namespace CodeGen { -
src/CodeGen/GenType.h
r55a68c3 r3d4b23fa 17 17 #define _GENTYPE_H 18 18 19 #include <string> 20 #include "SynTree/SynTree.h" 19 #include <string> // for string 20 21 class Type; 21 22 22 23 namespace CodeGen { -
src/CodeGen/Generate.cc
r55a68c3 r3d4b23fa 14 14 // 15 15 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<< 20 19 20 #include "CodeGenerator.h" // for CodeGenerator, doSemicolon, oper... 21 #include "GenType.h" // for genPrettyType 21 22 #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 29 27 30 28 using namespace std; -
src/CodeGen/Generate.h
r55a68c3 r3d4b23fa 17 17 #define GENERATE_H 18 18 19 #include < list>20 #include < iostream>19 #include <iostream> // for ostream 20 #include <list> // for list 21 21 22 #include "SynTree/SynTree.h" 22 class BaseSyntaxNode; 23 class Declaration; 23 24 24 25 namespace CodeGen { -
src/CodeGen/OperatorTable.cc
r55a68c3 r3d4b23fa 14 14 // 15 15 16 #include <map> 16 #include <map> // for map, _Rb_tree_const_iterator, map<>::const_iterator 17 #include <utility> // for pair 18 17 19 #include "OperatorTable.h" 18 20 -
src/CodeTools/DeclStats.cc
r55a68c3 r3d4b23fa 16 16 #include "DeclStats.h" 17 17 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 30 34 31 35 namespace CodeTools { 32 36 33 37 class DeclStats : public Visitor { 34 38 template<typename T> … … 75 79 sum(n_types, o.n_types); 76 80 sum(p_new, o.p_new); 77 81 78 82 return *this; 79 83 } 80 84 }; 81 85 82 86 struct Stats { 83 87 unsigned n_decls; ///< Total number of declarations … … 98 102 /// Stats for the return list 99 103 ArgPackStats returns; 100 104 101 105 /// Count of declarations with each number of assertions 102 106 std::map<unsigned, unsigned> n_assns; … … 105 109 /// Stats for the assertions' return types 106 110 ArgPackStats assn_returns; 107 111 108 112 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() {} 109 113 … … 122 126 sum( assn_params, o.assn_params ); 123 127 sum( assn_returns, o.assn_returns ); 124 128 125 129 return *this; 126 130 } … … 144 148 145 149 n += dt->size(); 146 150 147 151 std::stringstream ss; 148 152 dt->print( ss ); … … 176 180 ++pstats.n_types.at( types.size() ); 177 181 } 178 182 179 183 void analyzeFunc( FunctionType* fnTy, Stats& stats, ArgPackStats& params, ArgPackStats& returns ) { 180 184 std::unordered_set<std::string> seen; … … 186 190 auto& args = expr->get_args(); 187 191 unsigned fanout = args.size(); 188 192 189 193 ++exprs_by_fanout_at_depth[ std::make_pair(depth, fanout) ]; 190 194 for ( Expression* arg : args ) { … … 205 209 return; 206 210 } 207 211 208 212 Stats& stats = for_linkage[ decl->get_linkage() ]; 209 213 … … 323 327 } 324 328 325 void printPairMap( const std::string& name, 329 void printPairMap( const std::string& name, 326 330 const std::map<std::pair<unsigned, unsigned>, unsigned>& map ) { 327 331 for ( const auto& entry : map ) { 328 332 const auto& key = entry.first; 329 std::cout << "\"" << name << "\"," << key.first << "," << key.second << "," 333 std::cout << "\"" << name << "\"," << key.first << "," << key.second << "," 330 334 << entry.second << std::endl; 331 335 } 332 336 } 333 337 334 338 public: 335 339 void print() { … … 366 370 stats.print(); 367 371 } 368 372 369 373 } // namespace CodeTools 370 374 -
src/CodeTools/DeclStats.h
r55a68c3 r3d4b23fa 17 17 #define DECLSTATS_H 18 18 19 #include "SynTree/SynTree.h" 19 #include <list> // for list 20 21 class Declaration; 20 22 21 23 namespace CodeTools { -
src/CodeTools/TrackLoc.cc
r55a68c3 r3d4b23fa 16 16 #include "TrackLoc.h" 17 17 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 19 24 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 25 32 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" 33 class Declaration; 33 34 34 35 namespace CodeTools { -
src/CodeTools/TrackLoc.h
r55a68c3 r3d4b23fa 17 17 #define TRACKLOC_H 18 18 19 #include "SynTree/SynTree.h" 19 #include <cstddef> // for size_t 20 #include <list> // for list 21 22 class Declaration; 20 23 21 24 namespace CodeTools { -
src/Common/Assert.cc
r55a68c3 r3d4b23fa 14 14 // 15 15 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 20 19 21 20 extern const char * __progname; // global name of running executable (argv[0]) -
src/Common/SemanticError.cc
r55a68c3 r3d4b23fa 14 14 // 15 15 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 21 21 22 #include "Common/utility.h" // for to_string, CodeLocation (ptr only) 22 23 #include "SemanticError.h" 23 24 #include <unistd.h>25 24 26 25 inline const std::string& error_str() { -
src/Common/SemanticError.h
r55a68c3 r3d4b23fa 17 17 #define SEMANTICERROR_H 18 18 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 24 23 25 #include "utility.h" 24 #include "utility.h" // for CodeLocation, toString 26 25 27 26 struct error { -
src/Concurrency/Keywords.cc
r55a68c3 r3d4b23fa 17 17 #include "Concurrency/Keywords.h" 18 18 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 36 class Attribute; 27 37 28 38 namespace Concurrency { … … 322 332 if( needs_main ) { 323 333 FunctionType * main_type = new FunctionType( noQualifiers, false ); 324 334 325 335 main_type->get_parameters().push_back( this_decl->clone() ); 326 336 … … 361 371 void ConcurrentSueKeyword::addRoutines( ObjectDecl * field, FunctionDecl * func ) { 362 372 CompoundStmt * statement = new CompoundStmt( noLabels ); 363 statement->push_back( 373 statement->push_back( 364 374 new ReturnStmt( 365 375 noLabels, … … 386 396 //============================================================================================= 387 397 void MutexKeyword::visit(FunctionDecl* decl) { 388 Visitor::visit(decl); 398 Visitor::visit(decl); 389 399 390 400 std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl ); … … 510 520 void ThreadStarter::visit(FunctionDecl * decl) { 511 521 Visitor::visit(decl); 512 522 513 523 if( ! InitTweak::isConstructor(decl->get_name()) ) return; 514 524 … … 528 538 if( ! stmt ) return; 529 539 530 stmt->push_back( 540 stmt->push_back( 531 541 new ExprStmt( 532 542 noLabels, -
src/Concurrency/Keywords.h
r55a68c3 r3d4b23fa 18 18 #define KEYWORDS_H 19 19 20 #include <list> 20 #include <list> // for list 21 21 22 #include "SynTree/Declaration.h" 22 class Declaration; 23 23 24 24 namespace Concurrency { -
src/ControlStruct/ExceptTranslate.cc
r55a68c3 r3d4b23fa 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jun 30 13:30:00 201713 // Update Count : 112 // Last Modified On : Wed Jul 12 15:07:00 2017 13 // Update Count : 3 14 14 // 15 15 … … 157 157 Statement * create_terminate_throw( ThrowStmt *throwStmt ) { 158 158 // { int NAME = EXPR; __throw_terminate( &NAME ); } 159 return create_given_throw( "__cfaehm__throw_terminat ion", throwStmt );159 return create_given_throw( "__cfaehm__throw_terminate", throwStmt ); 160 160 } 161 161 Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) { … … 164 164 Statement * result = new ExprStmt( 165 165 throwStmt->get_labels(), 166 new UntypedExpr( new NameExpr( "__cfaehm__rethrow_terminat ion" ) )166 new UntypedExpr( new NameExpr( "__cfaehm__rethrow_terminate" ) ) 167 167 ); 168 168 delete throwStmt; … … 171 171 Statement * create_resume_throw( ThrowStmt *throwStmt ) { 172 172 // __throw_resume( EXPR ); 173 return create_given_throw( "__cfaehm__throw_resum ption", throwStmt );173 return create_given_throw( "__cfaehm__throw_resume", throwStmt ); 174 174 } 175 175 Statement * create_resume_rethrow( ThrowStmt *throwStmt ) { … … 593 593 594 594 PassVisitor<ExceptionMutatorCore> translator; 595 for ( Declaration * decl : translationUnit ) { 596 decl->acceptMutator( translator ); 597 } 595 mutateAll( translationUnit, translator ); 598 596 } 599 597 } -
src/GenPoly/InstantiateGeneric.cc
r55a68c3 r3d4b23fa 171 171 Type* postmutate( UnionInstType *inst ); 172 172 173 void premutate( FunctionType * ftype ) {173 void premutate( __attribute__((unused)) FunctionType * ftype ) { 174 174 GuardValue( inFunctionType ); 175 175 inFunctionType = true; -
src/InitTweak/GenInit.cc
r55a68c3 r3d4b23fa 71 71 // that need to be constructed or destructed 72 72 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; } 80 79 81 80 void previsit( CompoundStmt * compoundStmt ); … … 336 335 } 337 336 338 void CtorDtor::previsit( CompoundStmt * compoundStmt ) {337 void CtorDtor::previsit( __attribute__((unused)) CompoundStmt * compoundStmt ) { 339 338 GuardScope( managedTypes ); 340 339 } -
src/MakeLibCfa.cc
r55a68c3 r3d4b23fa 15 15 16 16 #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 25 32 26 33 namespace LibCfa { -
src/MakeLibCfa.h
r55a68c3 r3d4b23fa 17 17 #define LIBCFA_MAKELIBCFA_H 18 18 19 #include <list> 20 #include <SynTree/SynTree.h> 19 #include <list> // for list 20 21 class Declaration; 21 22 22 23 namespace LibCfa { -
src/Makefile.am
r55a68c3 r3d4b23fa 43 43 driver_cfa_cpp_SOURCES = ${SRC} 44 44 driver_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++1445 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14 46 46 driver_cfa_cpp_LDFLAGS = -Xlinker -export-dynamic 47 47 -
src/Makefile.in
r55a68c3 r3d4b23fa 544 544 driver_cfa_cpp_SOURCES = ${SRC} 545 545 driver_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++14546 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14 547 547 driver_cfa_cpp_LDFLAGS = -Xlinker -export-dynamic 548 548 all: $(BUILT_SOURCES) … … 560 560 esac; \ 561 561 done; \ 562 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/Makefile'; \562 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ 563 563 $(am__cd) $(top_srcdir) && \ 564 $(AUTOMAKE) -- gnusrc/Makefile564 $(AUTOMAKE) --foreign src/Makefile 565 565 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 566 566 @case '$?' in \ -
src/Parser/LinkageSpec.cc
r55a68c3 r3d4b23fa 10 10 // Created On : Sat May 16 13:22:09 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jun 28 11:51:00 201713 // Update Count : 2 412 // Last Modified On : Fri Jul 7 11:11:00 2017 13 // Update Count : 25 14 14 // 15 15 … … 22 22 #include "Common/SemanticError.h" 23 23 24 LinkageSpec::Spec LinkageSpec::linkageCheck( const string * spec ) { 24 namespace LinkageSpec { 25 26 Spec linkageCheck( const string * spec ) { 27 assert( spec ); 25 28 unique_ptr<const string> guard( spec ); // allocated by lexer 26 29 if ( *spec == "\"Cforall\"" ) { … … 35 38 } 36 39 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]; 40 Spec linkageUpdate( Spec old_spec, const string * cmd ) { 41 assert( cmd ); 42 unique_ptr<const string> guard( cmd ); // allocated by lexer 43 if ( *cmd == "\"Cforall\"" ) { 44 old_spec.is_mangled = true; 45 return old_spec; 46 } else if ( *cmd == "\"C\"" ) { 47 old_spec.is_mangled = false; 48 return old_spec; 49 } else { 50 throw SemanticError( "Invalid linkage specifier " + *cmd ); 51 } // if 43 52 } 44 53 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]; 54 std::string linkageName( Spec linkage ) { 55 switch ( linkage ) { 56 case Intrinsic: 57 return "intrinsic"; 58 case C: 59 return "C"; 60 case Cforall: 61 return "Cforall"; 62 case AutoGen: 63 return "autogenerated cfa"; 64 case Compiler: 65 return "compiler built-in"; 66 case BuiltinCFA: 67 return "cfa built-in"; 68 case BuiltinC: 69 return "c built-in"; 70 default: 71 return "<unnamed linkage spec>"; 72 } 54 73 } 55 74 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 88 76 89 77 // Local Variables: // -
src/Parser/LinkageSpec.h
r55a68c3 r3d4b23fa 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // LinkageSpec.h -- 7 // LinkageSpec.h -- 8 8 // 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:24:28 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jun 28 11:50:00 201713 // Update Count : 1 212 // Last Modified On : Fri Jul 7 11:03:00 2017 13 // Update Count : 13 14 14 // 15 15 … … 19 19 #include <string> 20 20 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 21 namespace LinkageSpec { 22 // All linkage specs are some combination of these flags: 23 enum { 24 Mangle = 1 << 0, 25 Generate = 1 << 1, 26 Overrideable = 1 << 2, 27 Builtin = 1 << 3, 28 29 NoOfSpecs = 1 << 4, 31 30 }; 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 }; 40 78 }; 41 79 -
src/Parser/StatementNode.cc
r55a68c3 r3d4b23fa 10 10 // Created On : Sat May 16 14:59:41 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 28 21:08:37201713 // Update Count : 33 012 // Last Modified On : Tue Jul 11 21:23:15 2017 13 // Update Count : 331 14 14 // 15 15 … … 93 93 std::list< Statement * > branches; 94 94 buildMoveList< Statement, StatementNode >( stmt, branches ); 95 assert( branches.size() >= 0 ); // size== 0 for switch (...) {}, i.e., no declaration or statements95 // branches.size() == 0 for switch (...) {}, i.e., no declaration or statements 96 96 return new SwitchStmt( noLabels, maybeMoveBuild< Expression >(ctl), branches ); 97 97 } -
src/Parser/lex.ll
r55a68c3 r3d4b23fa 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Wed Ju n 28 21:03:45201713 * Update Count : 5 2912 * Last Modified On : Wed Jul 12 18:04:44 2017 13 * Update Count : 535 14 14 */ 15 15 … … 59 59 } 60 60 61 // Stop warning due to incorrectly generated flex code. 62 #pragma GCC diagnostic ignored "-Wsign-compare" 61 63 %} 62 64 … … 272 274 __volatile__ { KEYWORD_RETURN(VOLATILE); } // GCC 273 275 while { KEYWORD_RETURN(WHILE); } 276 with { KEYWORD_RETURN(WITH); } // CFA 274 277 zero_t { NUMERIC_RETURN(ZERO_T); } // CFA 275 278 -
src/Parser/parser.yy
r55a68c3 r3d4b23fa 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Jun 30 15:38:00201713 // Update Count : 24 1511 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 12 18:23:36 2017 13 // Update Count : 2426 14 14 // 15 15 … … 129 129 %token ATTRIBUTE EXTENSION // GCC 130 130 %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 // CFA131 %token CHOOSE DISABLE ENABLE FALLTHRU TRY CATCH CATCHRESUME FINALLY THROW THROWRESUME AT WITH // CFA 132 132 %token ASM // C99, extension ISO/IEC 9899:1999 Section J.5.10(1) 133 133 %token ALIGNAS ALIGNOF GENERIC STATICASSERT // C11 … … 184 184 // statements 185 185 %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 187 188 %type<sn> fall_through_opt fall_through 188 189 %type<sn> statement statement_list 189 190 %type<sn> block_item_list block_item 190 %type<sn> case_clause191 %type<sn> with_clause_opt 191 192 %type<en> case_value 192 %type<sn> case_ value_list case_label case_label_list193 %type<sn> case_clause case_value_list case_label case_label_list 193 194 %type<sn> switch_clause_list_opt switch_clause_list choose_clause_list_opt choose_clause_list 194 195 %type<sn> /* handler_list */ handler_clause finally_clause … … 729 730 | iteration_statement 730 731 | jump_statement 732 | with_statement 731 733 | exception_statement 732 734 | asm_statement … … 934 936 | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume 935 937 { $$ = new StatementNode( build_resume_at( $2, $4 ) ); } 938 ; 939 940 with_statement: 941 WITH identifier_list compound_statement 942 { $$ = (StatementNode *)0; } // FIX ME 936 943 ; 937 944 … … 2176 2183 { 2177 2184 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 2178 linkage = LinkageSpec::linkage Check($2 );2185 linkage = LinkageSpec::linkageUpdate( linkage, $2 ); 2179 2186 } 2180 2187 '{' external_definition_list_opt '}' … … 2212 2219 ; 2213 2220 2221 with_clause_opt: 2222 // empty 2223 { $$ = (StatementNode *)0; } // FIX ME 2224 | WITH identifier_list 2225 { $$ = (StatementNode *)0; } // FIX ME 2226 ; 2227 2214 2228 function_definition: 2215 cfa_function_declaration compound_statement// CFA2229 cfa_function_declaration with_clause_opt compound_statement // CFA 2216 2230 { 2217 2231 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2218 2232 typedefTable.leaveScope(); 2219 $$ = $1->addFunctionBody( $ 2);2220 } 2221 | declaration_specifier function_declarator compound_statement2233 $$ = $1->addFunctionBody( $3 ); 2234 } 2235 | declaration_specifier function_declarator with_clause_opt compound_statement 2222 2236 { 2223 2237 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2224 2238 typedefTable.leaveScope(); 2225 $$ = $2->addFunctionBody( $ 3)->addType( $1 );2226 } 2227 | type_qualifier_list function_declarator compound_statement2239 $$ = $2->addFunctionBody( $4 )->addType( $1 ); 2240 } 2241 | type_qualifier_list function_declarator with_clause_opt compound_statement 2228 2242 { 2229 2243 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2230 2244 typedefTable.leaveScope(); 2231 $$ = $2->addFunctionBody( $ 3)->addQualifiers( $1 );2232 } 2233 | declaration_qualifier_list function_declarator compound_statement2245 $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 ); 2246 } 2247 | declaration_qualifier_list function_declarator with_clause_opt compound_statement 2234 2248 { 2235 2249 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2236 2250 typedefTable.leaveScope(); 2237 $$ = $2->addFunctionBody( $ 3)->addQualifiers( $1 );2238 } 2239 | declaration_qualifier_list type_qualifier_list function_declarator compound_statement2251 $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 ); 2252 } 2253 | declaration_qualifier_list type_qualifier_list function_declarator with_clause_opt compound_statement 2240 2254 { 2241 2255 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2242 2256 typedefTable.leaveScope(); 2243 $$ = $3->addFunctionBody( $ 4)->addQualifiers( $2 )->addQualifiers( $1 );2257 $$ = $3->addFunctionBody( $5 )->addQualifiers( $2 )->addQualifiers( $1 ); 2244 2258 } 2245 2259 2246 2260 // Old-style K&R function definition, OBSOLESCENT (see 4) 2247 | declaration_specifier KR_function_declarator push KR_declaration_list_opt compound_statement2261 | declaration_specifier KR_function_declarator push KR_declaration_list_opt with_clause_opt compound_statement 2248 2262 { 2249 2263 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2250 2264 typedefTable.leaveScope(); 2251 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $ 5)->addType( $1 );2252 } 2253 | type_qualifier_list KR_function_declarator push KR_declaration_list_opt compound_statement2265 $$ = $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 2254 2268 { 2255 2269 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2256 2270 typedefTable.leaveScope(); 2257 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $ 5)->addQualifiers( $1 );2271 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $6 )->addQualifiers( $1 ); 2258 2272 } 2259 2273 2260 2274 // 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_statement2275 | declaration_qualifier_list KR_function_declarator push KR_declaration_list_opt with_clause_opt compound_statement 2262 2276 { 2263 2277 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2264 2278 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_statement2279 $$ = $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 2268 2282 { 2269 2283 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2270 2284 typedefTable.leaveScope(); 2271 $$ = $3->addOldDeclList( $5 )->addFunctionBody( $ 6)->addQualifiers( $2 )->addQualifiers( $1 );2285 $$ = $3->addOldDeclList( $5 )->addFunctionBody( $7 )->addQualifiers( $2 )->addQualifiers( $1 ); 2272 2286 } 2273 2287 ; … … 2332 2346 | TYPEGENname 2333 2347 | CONST 2334 { $$ = Token{ new string( "__const__" ) }; }2348 { $$ = Token{ new string( "__const__" ), { nullptr, -1 } }; } 2335 2349 ; 2336 2350 -
src/ResolvExpr/CurrentObject.cc
r55a68c3 r3d4b23fa 114 114 } 115 115 116 virtual void print( std::ostream & out, Indenter indent ) const {116 virtual void print( std::ostream & out, __attribute__((unused)) Indenter indent ) const { 117 117 out << "SimpleIterator(" << type << ")"; 118 118 } -
src/benchmark/CorCtxSwitch.c
r55a68c3 r3d4b23fa 31 31 32 32 StartTime = Time(); 33 // for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) {34 // resume( this_coroutine() );35 // // resume( &s );36 // }37 33 resumer( &s, NoOfTimes ); 38 34 EndTime = Time(); -
src/benchmark/Makefile.am
r55a68c3 r3d4b23fa 20 20 CC = @CFA_BINDIR@/@CFA_NAME@ 21 21 22 noinst_PROGRAMS = bench ctxswitch-coroutine ctxswitch-thread22 noinst_PROGRAMS = bench$(EXEEXT) ctxswitch-coroutine$(EXEEXT) ctxswitch-thread$(EXEEXT) sched-int$(EXEEXT) monitor$(EXEEXT) csv-data$(EXEEXT) 23 23 24 bench :24 bench$(EXEEXT) : 25 25 @for ccflags in "-debug" "-nodebug"; do \ 26 26 echo ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -lrt bench.c;\ … … 30 30 rm -f ./a.out ; 31 31 32 ctxswitch-coroutine :32 ctxswitch-coroutine$(EXEEXT): 33 33 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 CorCtxSwitch.c 34 34 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 37 37 @rm -f ./a.out 38 38 39 ctxswitch-thread :39 ctxswitch-thread$(EXEEXT): 40 40 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 ThrdCtxSwitch.c 41 41 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 44 44 @rm -f ./a.out 45 45 46 sched-int :46 sched-int$(EXEEXT): 47 47 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c 48 48 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 51 51 @rm -f ./a.out 52 52 53 monitor :53 monitor$(EXEEXT): 54 54 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c 55 55 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 58 58 @rm -f ./a.out 59 59 60 csv-data :60 csv-data$(EXEEXT): 61 61 @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c 62 62 @./a.out -
src/benchmark/Makefile.in
r55a68c3 r3d4b23fa 92 92 build_triplet = @build@ 93 93 host_triplet = @host@ 94 noinst_PROGRAMS = bench$(EXEEXT) ctxswitch-coroutine$(EXEEXT) \95 ctxswitch-thread$(EXEEXT)96 94 subdir = src/benchmark 97 95 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 … … 108 106 bench_OBJECTS = bench.$(OBJEXT) 109 107 bench_LDADD = $(LDADD) 108 csv_data_SOURCES = csv-data.c 109 csv_data_OBJECTS = csv-data.$(OBJEXT) 110 csv_data_LDADD = $(LDADD) 110 111 ctxswitch_coroutine_SOURCES = ctxswitch-coroutine.c 111 112 ctxswitch_coroutine_OBJECTS = ctxswitch-coroutine.$(OBJEXT) … … 114 115 ctxswitch_thread_OBJECTS = ctxswitch-thread.$(OBJEXT) 115 116 ctxswitch_thread_LDADD = $(LDADD) 117 monitor_SOURCES = monitor.c 118 monitor_OBJECTS = monitor.$(OBJEXT) 119 monitor_LDADD = $(LDADD) 120 sched_int_SOURCES = sched-int.c 121 sched_int_OBJECTS = sched-int.$(OBJEXT) 122 sched_int_LDADD = $(LDADD) 116 123 AM_V_P = $(am__v_P_@AM_V@) 117 124 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) … … 142 149 am__v_CCLD_0 = @echo " CCLD " $@; 143 150 am__v_CCLD_1 = 144 SOURCES = bench.c ctxswitch-coroutine.c ctxswitch-thread.c 145 DIST_SOURCES = bench.c ctxswitch-coroutine.c ctxswitch-thread.c 151 SOURCES = bench.c csv-data.c ctxswitch-coroutine.c ctxswitch-thread.c \ 152 monitor.c sched-int.c 153 DIST_SOURCES = bench.c csv-data.c ctxswitch-coroutine.c \ 154 ctxswitch-thread.c monitor.c sched-int.c 146 155 am__can_run_installinfo = \ 147 156 case $$AM_UPDATE_INFO_DIR in \ … … 293 302 top_srcdir = @top_srcdir@ 294 303 AM_CFLAGS = -g -Wall -Wno-unused-function -O2 304 noinst_PROGRAMS = bench$(EXEEXT) ctxswitch-coroutine$(EXEEXT) ctxswitch-thread$(EXEEXT) sched-int$(EXEEXT) monitor$(EXEEXT) csv-data$(EXEEXT) 295 305 all: all-am 296 306 … … 306 316 esac; \ 307 317 done; \ 308 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/benchmark/Makefile'; \318 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/benchmark/Makefile'; \ 309 319 $(am__cd) $(top_srcdir) && \ 310 $(AUTOMAKE) -- gnusrc/benchmark/Makefile320 $(AUTOMAKE) --foreign src/benchmark/Makefile 311 321 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 312 322 @case '$?' in \ … … 337 347 338 348 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bench.Po@am__quote@ 349 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csv-data.Po@am__quote@ 339 350 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctxswitch-coroutine.Po@am__quote@ 340 351 @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@ 341 354 342 355 .c.o: … … 559 572 560 573 561 bench :574 bench$(EXEEXT) : 562 575 @for ccflags in "-debug" "-nodebug"; do \ 563 576 echo ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -lrt bench.c;\ … … 567 580 rm -f ./a.out ; 568 581 569 ctxswitch-coroutine :582 ctxswitch-coroutine$(EXEEXT): 570 583 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 CorCtxSwitch.c 571 584 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 574 587 @rm -f ./a.out 575 588 576 ctxswitch-thread :589 ctxswitch-thread$(EXEEXT): 577 590 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 ThrdCtxSwitch.c 578 591 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 581 594 @rm -f ./a.out 582 595 583 sched-int :596 sched-int$(EXEEXT): 584 597 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c 585 598 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 588 601 @rm -f ./a.out 589 602 590 monitor :603 monitor$(EXEEXT): 591 604 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c 592 605 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 595 608 @rm -f ./a.out 596 609 597 csv-data :610 csv-data$(EXEEXT): 598 611 @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c 599 612 @./a.out -
src/benchmark/bench.h
r55a68c3 r3d4b23fa 26 26 #define N 10000000 27 27 #endif 28 29 unsigned int default_preemption() { 30 return 0; 31 } -
src/benchmark/create_pthrd.c
r55a68c3 r3d4b23fa 17 17 18 18 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) { 21 21 return 1; 22 22 } 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) { 28 25 return 1; 29 26 } -
src/benchmark/csv-data.c
r55a68c3 r3d4b23fa 25 25 } 26 26 27 #ifndef N28 #define N 10000000029 #endif30 31 27 //----------------------------------------------------------------------------- 32 28 // coroutine context switch … … 38 34 39 35 StartTime = Time(); 40 // for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) {41 // resume( this_coroutine() );42 // // resume( &s );43 // }44 36 resumer( &s, NoOfTimes ); 45 37 EndTime = Time(); … … 104 96 mon_t mon1; 105 97 106 condition cond1a; 98 condition cond1a; 107 99 condition cond1b; 108 100 … … 152 144 mon_t mon2; 153 145 154 condition cond2a; 146 condition cond2a; 155 147 condition cond2b; 156 148 -
src/driver/Makefile.in
r55a68c3 r3d4b23fa 315 315 esac; \ 316 316 done; \ 317 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/driver/Makefile'; \317 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/driver/Makefile'; \ 318 318 $(am__cd) $(top_srcdir) && \ 319 $(AUTOMAKE) -- gnusrc/driver/Makefile319 $(AUTOMAKE) --foreign src/driver/Makefile 320 320 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 321 321 @case '$?' in \ -
src/examples/Makefile.in
r55a68c3 r3d4b23fa 319 319 esac; \ 320 320 done; \ 321 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/examples/Makefile'; \321 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/examples/Makefile'; \ 322 322 $(am__cd) $(top_srcdir) && \ 323 $(AUTOMAKE) -- gnusrc/examples/Makefile323 $(AUTOMAKE) --foreign src/examples/Makefile 324 324 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 325 325 @case '$?' in \ -
src/include/assert.h
r55a68c3 r3d4b23fa 15 15 16 16 #pragma once 17 // Pragmas for header cleanup tool 18 // IWYU pragma: private, include <cassert> 17 19 18 20 #include_next <assert.h> -
src/libcfa/Makefile.am
r55a68c3 r3d4b23fa 17 17 # create object files in directory with source files 18 18 AUTOMAKE_OPTIONS = subdir-objects 19 ARFLAGS = cr 19 20 20 21 libdir = ${CFA_LIBDIR} -
src/libcfa/Makefile.in
r55a68c3 r3d4b23fa 142 142 LIBRARIES = $(lib_LIBRARIES) 143 143 AR = ar 144 ARFLAGS = cru145 144 AM_V_AR = $(am__v_AR_@AM_V@) 146 145 am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) … … 409 408 # create object files in directory with source files 410 409 AUTOMAKE_OPTIONS = subdir-objects 410 ARFLAGS = cr 411 411 lib_LIBRARIES = $(am__append_1) $(am__append_2) 412 412 EXTRA_FLAGS = -g -Wall -Werror -Wno-unused-function -I${abs_top_srcdir}/src/libcfa/libhdr -imacros libcfa-prelude.c @CFA_FLAGS@ … … 439 439 esac; \ 440 440 done; \ 441 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/libcfa/Makefile'; \441 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/libcfa/Makefile'; \ 442 442 $(am__cd) $(top_srcdir) && \ 443 $(AUTOMAKE) -- gnusrc/libcfa/Makefile443 $(AUTOMAKE) --foreign src/libcfa/Makefile 444 444 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 445 445 @case '$?' in \ -
src/libcfa/concurrency/CtxSwitch-i386.S
r55a68c3 r3d4b23fa 98 98 ret 99 99 100 .text101 .align 2102 .globl CtxGet103 CtxGet:104 movl %esp,SP_OFFSET(%eax)105 movl %ebp,FP_OFFSET(%eax)106 107 ret108 109 100 // Local Variables: // 110 101 // compile-command: "make install" // -
src/libcfa/concurrency/CtxSwitch-x86_64.S
r55a68c3 r3d4b23fa 1 // -*- Mode: Asm -*- 1 // -*- Mode: Asm -*- 2 2 // 3 3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 18 18 // Free Software Foundation; either version 2.1 of the License, or (at your 19 19 // option) any later version. 20 // 20 // 21 21 // This library is distributed in the hope that it will be useful, but WITHOUT 22 22 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23 23 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 24 24 // for more details. 25 // 25 // 26 26 // You should have received a copy of the GNU Lesser General Public License 27 27 // along with this library. 28 // 28 // 29 29 30 30 // This context switch routine depends on the fact that the stack of a new … … 93 93 .globl CtxInvokeStub 94 94 CtxInvokeStub: 95 movq %rbx, %rdi 95 movq %rbx, %rdi 96 96 jmp *%r12 97 98 .text99 .align 2100 .globl CtxGet101 CtxGet:102 movq %rsp,SP_OFFSET(%rdi)103 movq %rbp,FP_OFFSET(%rdi)104 105 ret106 97 107 98 // Local Variables: // -
src/libcfa/concurrency/alarm.c
r55a68c3 r3d4b23fa 16 16 17 17 extern "C" { 18 #include <errno.h> 19 #include <stdio.h> 20 #include <string.h> 18 21 #include <time.h> 22 #include <unistd.h> 19 23 #include <sys/time.h> 20 24 } 25 26 #include "libhdr.h" 21 27 22 28 #include "alarm.h" … … 31 37 timespec curr; 32 38 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; 34 42 } 35 43 36 44 void __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 ); 37 46 itimerval val; 38 47 val.it_value.tv_sec = alarm / TIMEGRAN; // seconds … … 71 80 } 72 81 82 LIB_DEBUG_DO( bool validate( alarm_list_t * this ) { 83 alarm_node_t ** it = &this->head; 84 while( (*it) ) { 85 it = &(*it)->next; 86 } 87 88 return it == this->tail; 89 }) 90 73 91 static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) { 74 assert( !n->next );92 verify( !n->next ); 75 93 if( p == this->tail ) { 76 94 this->tail = &n->next; … … 80 98 } 81 99 *p = n; 100 101 verify( validate( this ) ); 82 102 } 83 103 … … 89 109 90 110 insert_at( this, n, it ); 111 112 verify( validate( this ) ); 91 113 } 92 114 … … 100 122 head->next = NULL; 101 123 } 124 verify( validate( this ) ); 102 125 return head; 103 126 } … … 105 128 static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) { 106 129 verify( it ); 107 verify( (*it) ->next== n );130 verify( (*it) == n ); 108 131 109 (*it) ->next= n->next;132 (*it) = n->next; 110 133 if( !n-> next ) { 111 134 this->tail = it; 112 135 } 113 136 n->next = NULL; 137 138 verify( validate( this ) ); 114 139 } 115 140 116 141 static inline void remove( alarm_list_t * this, alarm_node_t * n ) { 117 142 alarm_node_t ** it = &this->head; 118 while( (*it) && (*it) ->next!= n ) {143 while( (*it) && (*it) != n ) { 119 144 it = &(*it)->next; 120 145 } 121 146 147 verify( validate( this ) ); 148 122 149 if( *it ) { remove_at( this, n, it ); } 150 151 verify( validate( this ) ); 123 152 } 124 153 125 154 void register_self( alarm_node_t * this ) { 126 155 disable_interrupts(); 127 assert( !systemProcessor->pending_alarm );128 lock( &systemProcessor->alarm_lock );156 verify( !systemProcessor->pending_alarm ); 157 lock( &systemProcessor->alarm_lock DEBUG_CTX2 ); 129 158 { 159 verify( validate( &systemProcessor->alarms ) ); 160 bool first = !systemProcessor->alarms.head; 161 130 162 insert( &systemProcessor->alarms, this ); 131 163 if( systemProcessor->pending_alarm ) { 132 164 tick_preemption(); 133 165 } 166 if( first ) { 167 __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() ); 168 } 134 169 } 135 170 unlock( &systemProcessor->alarm_lock ); 136 171 this->set = true; 137 enable_interrupts( );172 enable_interrupts( DEBUG_CTX ); 138 173 } 139 174 140 175 void unregister_self( alarm_node_t * this ) { 176 // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : unregister %p start\n", this ); 141 177 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 } 144 183 unlock( &systemProcessor->alarm_lock ); 145 disable_interrupts();184 enable_interrupts( DEBUG_CTX ); 146 185 this->set = false; 186 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Kernel : unregister %p end\n", this ); 147 187 } -
src/libcfa/concurrency/coroutine
r55a68c3 r3d4b23fa 63 63 64 64 // Get current coroutine 65 coroutine_desc * this_coroutine(void);65 extern volatile thread_local coroutine_desc * this_coroutine; 66 66 67 67 // Private wrappers for context switch and stack creation … … 71 71 // Suspend implementation inlined for performance 72 72 static inline void suspend() { 73 coroutine_desc * src = this_coroutine (); // optimization73 coroutine_desc * src = this_coroutine; // optimization 74 74 75 75 assertf( src->last != 0, … … 88 88 forall(dtype T | is_coroutine(T)) 89 89 static inline void resume(T * cor) { 90 coroutine_desc * src = this_coroutine (); // optimization90 coroutine_desc * src = this_coroutine; // optimization 91 91 coroutine_desc * dst = get_coroutine(cor); 92 92 … … 112 112 113 113 static inline void resume(coroutine_desc * dst) { 114 coroutine_desc * src = this_coroutine (); // optimization114 coroutine_desc * src = this_coroutine; // optimization 115 115 116 116 // not resuming self ? -
src/libcfa/concurrency/coroutine.c
r55a68c3 r3d4b23fa 32 32 #include "invoke.h" 33 33 34 extern thread_local processor * this_processor;34 extern volatile thread_local processor * this_processor; 35 35 36 36 //----------------------------------------------------------------------------- … … 44 44 // Coroutine ctors and dtors 45 45 void ?{}(coStack_t* this) { 46 this->size = 10240; // size of stack46 this->size = 65000; // size of stack 47 47 this->storage = NULL; // pointer to stack 48 48 this->limit = NULL; // stack grows towards stack limit … … 50 50 this->context = NULL; // address of cfa_context_t 51 51 this->top = NULL; // address of top of storage 52 this->userStack = false; 52 this->userStack = false; 53 53 } 54 54 … … 106 106 107 107 // set state of current coroutine to inactive 108 src->state = Inactive;108 src->state = src->state == Halted ? Halted : Inactive; 109 109 110 110 // set new coroutine that task is executing 111 this_ processor->current_coroutine = dst;111 this_coroutine = dst; 112 112 113 113 // context switch to specified coroutine 114 assert( src->stack.context ); 114 115 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 116 117 117 118 // set state of new coroutine to active … … 131 132 this->size = libCeiling( storageSize, 16 ); 132 133 // use malloc/memalign because "new" raises an exception for out-of-memory 133 134 134 135 // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment 135 136 LIB_DEBUG_DO( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) ); -
src/libcfa/concurrency/invoke.c
r55a68c3 r3d4b23fa 29 29 30 30 extern void __suspend_internal(void); 31 extern void __leave_monitor_desc( struct monitor_desc * this ); 31 extern void __leave_thread_monitor( struct thread_desc * this ); 32 extern void disable_interrupts(); 33 extern void enable_interrupts( DEBUG_CTX_PARAM ); 32 34 33 35 void CtxInvokeCoroutine( 34 void (*main)(void *), 35 struct coroutine_desc *(*get_coroutine)(void *), 36 void (*main)(void *), 37 struct coroutine_desc *(*get_coroutine)(void *), 36 38 void *this 37 39 ) { … … 56 58 57 59 void 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 *), 61 63 void *this 62 64 ) { 65 // First suspend, once the thread arrives here, 66 // the function pointer to main can be invalidated without risk 63 67 __suspend_internal(); 64 68 69 // Fetch the thread handle from the user defined thread structure 65 70 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;69 71 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 71 76 main( this ); 72 77 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 75 84 //Final suspend, should never return 76 __ suspend_internal();85 __leave_thread_monitor( thrd ); 77 86 abortf("Resumed dead thread"); 78 87 } … … 80 89 81 90 void 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, 85 94 void (*invoke)(void *) 86 95 ) { … … 108 117 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke; 109 118 ((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 111 120 112 121 #elif defined( __x86_64__ ) … … 128 137 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke; 129 138 ((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 131 140 #else 132 141 #error Only __i386__ and __x86_64__ is supported for threads in cfa -
src/libcfa/concurrency/invoke.h
r55a68c3 r3d4b23fa 31 31 struct spinlock { 32 32 volatile int lock; 33 #ifdef __CFA_DEBUG__ 34 const char * prev_name; 35 void* prev_thrd; 36 #endif 33 37 }; 34 38 … … 83 87 struct __thread_queue_t entry_queue; // queue of threads that are blocked waiting for the monitor 84 88 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 monitor86 89 unsigned int recursion; // monitor routines can be called recursively, we need to keep track of that 87 90 }; … … 99 102 #ifndef _INVOKE_PRIVATE_H_ 100 103 #define _INVOKE_PRIVATE_H_ 101 104 102 105 struct machine_context_t { 103 106 void *SP; … … 109 112 extern void CtxInvokeStub( void ); 110 113 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 112 126 113 127 #endif //_INVOKE_PRIVATE_H_ -
src/libcfa/concurrency/kernel
r55a68c3 r3d4b23fa 28 28 //----------------------------------------------------------------------------- 29 29 // Locks 30 bool try_lock( spinlock * ); 31 void lock( spinlock * ); 32 void unlock( spinlock * ); 30 bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); 31 void lock ( spinlock * DEBUG_CTX_PARAM2 ); 32 void lock_yield( spinlock * DEBUG_CTX_PARAM2 ); 33 void unlock ( spinlock * ); 33 34 34 struct s ignal_once {35 volatile bool cond;36 struct spinlock lock;37 struct __thread_queue_t blocked;35 struct semaphore { 36 spinlock lock; 37 int count; 38 __thread_queue_t waiting; 38 39 }; 39 40 40 void ?{}(signal_once * this); 41 void ^?{}(signal_once * this); 41 void ?{}(semaphore * this, int count = 1); 42 void ^?{}(semaphore * this); 43 void P(semaphore * this); 44 void V(semaphore * this); 42 45 43 void wait( signal_once * );44 void signal( signal_once * );45 46 46 47 //----------------------------------------------------------------------------- … … 68 69 unsigned short thrd_count; 69 70 }; 70 static inline void ?{}(FinishAction * this) { 71 static inline void ?{}(FinishAction * this) { 71 72 this->action_code = No_Action; 72 73 this->thrd = NULL; … … 78 79 struct processorCtx_t * runner; 79 80 cluster * cltr; 80 coroutine_desc * current_coroutine;81 thread_desc * current_thread;82 81 pthread_t kernel_thread; 83 84 s ignal_once terminated;82 83 semaphore terminated; 85 84 volatile bool is_terminated; 86 85 … … 90 89 unsigned int preemption; 91 90 92 unsigned short disable_preempt_count;91 bool pending_preemption; 93 92 94 bool pending_preemption;93 char * last_enable; 95 94 }; 96 95 -
src/libcfa/concurrency/kernel.c
r55a68c3 r3d4b23fa 15 15 // 16 16 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" 25 18 26 19 //C Includes … … 35 28 36 29 //CFA Includes 37 #include " libhdr.h"30 #include "kernel_private.h" 38 31 #include "preemption.h" 32 #include "startup.h" 39 33 40 34 //Private includes … … 42 36 #include "invoke.h" 43 37 38 //Start and stop routine for the kernel, declared first to make sure they run first 39 void kernel_startup(void) __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) )); 40 void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) )); 41 44 42 //----------------------------------------------------------------------------- 45 43 // 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)] 47 45 48 46 KERNEL_STORAGE(processorCtx_t, systemProcessorCtx); … … 50 48 KERNEL_STORAGE(system_proc_t, systemProcessor); 51 49 KERNEL_STORAGE(thread_desc, mainThread); 52 KERNEL_STORAGE(machine_context_t, mainThread _context);50 KERNEL_STORAGE(machine_context_t, mainThreadCtx); 53 51 54 52 cluster * systemCluster; … … 59 57 // Global state 60 58 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 } 59 volatile thread_local processor * this_processor; 60 volatile thread_local coroutine_desc * this_coroutine; 61 volatile thread_local thread_desc * this_thread; 62 volatile thread_local bool preemption_in_progress = 0; 63 volatile thread_local unsigned short disable_preempt_count = 1; 70 64 71 65 //----------------------------------------------------------------------------- 72 66 // Main thread construction 73 67 struct current_stack_info_t { 74 machine_context_t ctx; 68 machine_context_t ctx; 75 69 unsigned int size; // size of stack 76 70 void *base; // base of stack … … 82 76 83 77 void ?{}( current_stack_info_t * this ) { 84 CtxGet( &this->ctx );78 CtxGet( this->ctx ); 85 79 this->base = this->ctx.FP; 86 80 this->storage = this->ctx.SP; … … 91 85 92 86 this->limit = (void *)(((intptr_t)this->base) - this->size); 93 this->context = &mainThread _context_storage;87 this->context = &mainThreadCtxStorage; 94 88 this->top = this->base; 95 89 } … … 106 100 107 101 void ?{}( coroutine_desc * this, current_stack_info_t * info) { 108 (&this->stack){ info }; 102 (&this->stack){ info }; 109 103 this->name = "Main Thread"; 110 104 this->errno_ = 0; … … 136 130 void ?{}(processor * this, cluster * cltr) { 137 131 this->cltr = cltr; 138 this->current_coroutine = NULL; 139 this->current_thread = NULL; 140 (&this->terminated){}; 132 (&this->terminated){ 0 }; 141 133 this->is_terminated = false; 142 134 this->preemption_alarm = NULL; 143 135 this->preemption = default_preemption(); 144 this->disable_preempt_count = 1; //Start with interrupts disabled145 136 this->pending_preemption = false; 146 137 … … 150 141 void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) { 151 142 this->cltr = cltr; 152 this->current_coroutine = NULL; 153 this->current_thread = NULL; 154 (&this->terminated){}; 143 (&this->terminated){ 0 }; 155 144 this->is_terminated = false; 156 this->disable_preempt_count = 0; 145 this->preemption_alarm = NULL; 146 this->preemption = default_preemption(); 157 147 this->pending_preemption = false; 148 this->kernel_thread = pthread_self(); 158 149 159 150 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); 161 152 runner{ this }; 162 153 } 154 155 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); ) 163 156 164 157 void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) { … … 168 161 169 162 (&this->proc){ cltr, runner }; 163 164 verify( validate( &this->alarms ) ); 170 165 } 171 166 … … 174 169 LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this); 175 170 this->is_terminated = true; 176 wait( &this->terminated ); 171 P( &this->terminated ); 172 pthread_join( this->kernel_thread, NULL ); 177 173 } 178 174 } … … 184 180 185 181 void ^?{}(cluster * this) { 186 182 187 183 } 188 184 … … 203 199 204 200 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++ ) 206 202 { 207 203 readyThread = nextThread( this->cltr ); … … 209 205 if(readyThread) 210 206 { 207 verify( disable_preempt_count > 0 ); 208 211 209 runThread(this, readyThread); 210 211 verify( disable_preempt_count > 0 ); 212 212 213 213 //Some actions need to be taken from the kernel … … 225 225 } 226 226 227 signal( &this->terminated ); 227 V( &this->terminated ); 228 228 229 LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this); 229 230 } 230 231 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 233 234 void runThread(processor * this, thread_desc * dst) { 234 235 coroutine_desc * proc_cor = get_coroutine(this->runner); 235 236 coroutine_desc * thrd_cor = get_coroutine(dst); 236 237 237 238 //Reset the terminating actions here 238 239 this->finish.action_code = No_Action; 239 240 240 241 //Update global state 241 this ->current_thread = dst;242 this_thread = dst; 242 243 243 244 // Context Switch to the thread … … 246 247 } 247 248 248 // Once a thread has finished running, some of 249 // Once a thread has finished running, some of 249 250 // its final actions must be executed from the kernel 250 251 void finishRunning(processor * this) { … … 256 257 } 257 258 else if( this->finish.action_code == Release_Schedule ) { 258 unlock( this->finish.lock ); 259 unlock( this->finish.lock ); 259 260 ScheduleThread( this->finish.thrd ); 260 261 } … … 289 290 processor * proc = (processor *) arg; 290 291 this_processor = proc; 292 this_coroutine = NULL; 293 this_thread = NULL; 294 disable_preempt_count = 1; 291 295 // SKULLDUGGERY: We want to create a context for the processor coroutine 292 296 // 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. 294 298 current_stack_info_t info; 295 299 machine_context_t ctx; … … 300 304 301 305 //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; 304 308 305 309 //We now have a proper context from which to schedule threads 306 310 LIB_DEBUG_PRINT_SAFE("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx); 307 311 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 311 315 // appropriate stack. 312 316 proc_cor_storage.__cor.state = Active; … … 315 319 316 320 // 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); 318 322 319 323 return NULL; … … 322 326 void start(processor * this) { 323 327 LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this); 324 328 325 329 pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this ); 326 330 327 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this); 331 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this); 328 332 } 329 333 … … 331 335 // Scheduler routines 332 336 void 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 ); 334 342 335 343 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 ); 338 346 append( &systemProcessor->proc.cltr->ready_queue, thrd ); 339 347 unlock( &systemProcessor->proc.cltr->lock ); 348 349 verify( disable_preempt_count > 0 ); 340 350 } 341 351 342 352 thread_desc * nextThread(cluster * this) { 343 lock( &this->lock ); 353 verify( disable_preempt_count > 0 ); 354 lock( &this->lock DEBUG_CTX2 ); 344 355 thread_desc * head = pop_head( &this->ready_queue ); 345 356 unlock( &this->lock ); 357 verify( disable_preempt_count > 0 ); 346 358 return head; 347 359 } 348 360 349 void ScheduleInternal() { 361 void BlockInternal() { 362 disable_interrupts(); 363 verify( disable_preempt_count > 0 ); 350 364 suspend(); 351 } 352 353 void ScheduleInternal( spinlock * lock ) { 365 verify( disable_preempt_count > 0 ); 366 enable_interrupts( DEBUG_CTX ); 367 } 368 369 void BlockInternal( spinlock * lock ) { 370 disable_interrupts(); 354 371 this_processor->finish.action_code = Release; 355 372 this_processor->finish.lock = lock; 373 374 verify( disable_preempt_count > 0 ); 356 375 suspend(); 357 } 358 359 void ScheduleInternal( thread_desc * thrd ) { 376 verify( disable_preempt_count > 0 ); 377 378 enable_interrupts( DEBUG_CTX ); 379 } 380 381 void BlockInternal( thread_desc * thrd ) { 382 disable_interrupts(); 383 assert( thrd->cor.state != Halted ); 360 384 this_processor->finish.action_code = Schedule; 361 385 this_processor->finish.thrd = thrd; 386 387 verify( disable_preempt_count > 0 ); 362 388 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 394 void BlockInternal( spinlock * lock, thread_desc * thrd ) { 395 disable_interrupts(); 366 396 this_processor->finish.action_code = Release_Schedule; 367 397 this_processor->finish.lock = lock; 368 398 this_processor->finish.thrd = thrd; 399 400 verify( disable_preempt_count > 0 ); 369 401 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 407 void BlockInternal(spinlock ** locks, unsigned short count) { 408 disable_interrupts(); 373 409 this_processor->finish.action_code = Release_Multi; 374 410 this_processor->finish.locks = locks; 375 411 this_processor->finish.lock_count = count; 412 413 verify( disable_preempt_count > 0 ); 376 414 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 420 void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 421 disable_interrupts(); 380 422 this_processor->finish.action_code = Release_Multi_Schedule; 381 423 this_processor->finish.locks = locks; … … 383 425 this_processor->finish.thrds = thrds; 384 426 this_processor->finish.thrd_count = thrd_count; 427 428 verify( disable_preempt_count > 0 ); 429 suspend(); 430 verify( disable_preempt_count > 0 ); 431 432 enable_interrupts( DEBUG_CTX ); 433 } 434 435 void LeaveThread(spinlock * lock, thread_desc * thrd) { 436 verify( disable_preempt_count > 0 ); 437 this_processor->finish.action_code = thrd ? Release_Schedule : Release; 438 this_processor->finish.lock = lock; 439 this_processor->finish.thrd = thrd; 440 385 441 suspend(); 386 442 } … … 392 448 // Kernel boot procedures 393 449 void kernel_startup(void) { 394 LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n"); 450 LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n"); 395 451 396 452 // Start by initializing the main thread 397 // SKULLDUGGERY: the mainThread steals the process main thread 453 // SKULLDUGGERY: the mainThread steals the process main thread 398 454 // which will then be scheduled by the systemProcessor normally 399 mainThread = (thread_desc *)&mainThread _storage;455 mainThread = (thread_desc *)&mainThreadStorage; 400 456 current_stack_info_t info; 401 457 mainThread{ &info }; … … 403 459 LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n"); 404 460 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 405 482 // Enable preemption 406 483 kernel_start_preemption(); 407 484 408 // Initialize the system cluster409 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 ctx415 // (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 queue420 // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread421 ScheduleThread(mainThread);422 423 //initialize the global state variables424 this_processor = &systemProcessor->proc;425 this_processor->current_thread = mainThread;426 this_processor->current_coroutine = &mainThread->cor;427 428 485 // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX 429 486 // 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. 431 488 resume( systemProcessor->proc.runner ); 432 489 … … 435 492 // THE SYSTEM IS NOW COMPLETELY RUNNING 436 493 LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n"); 494 495 enable_interrupts( DEBUG_CTX ); 437 496 } 438 497 439 498 void kernel_shutdown(void) { 440 499 LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n"); 500 501 disable_interrupts(); 441 502 442 503 // SKULLDUGGERY: Notify the systemProcessor it needs to terminates. … … 448 509 // THE SYSTEM IS NOW COMPLETELY STOPPED 449 510 511 // Disable preemption 512 kernel_stop_preemption(); 513 450 514 // Destroy the system processor and its context in reverse order of construction 451 515 // These were manually constructed so we need manually destroy them … … 457 521 ^(mainThread){}; 458 522 459 LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n"); 523 LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n"); 460 524 } 461 525 … … 467 531 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 468 532 // the globalAbort flag is true. 469 lock( &kernel_abort_lock );533 lock( &kernel_abort_lock DEBUG_CTX2 ); 470 534 471 535 // first task to abort ? … … 473 537 kernel_abort_called = true; 474 538 unlock( &kernel_abort_lock ); 475 } 539 } 476 540 else { 477 541 unlock( &kernel_abort_lock ); 478 542 479 543 sigset_t mask; 480 544 sigemptyset( &mask ); … … 482 546 sigaddset( &mask, SIGUSR1 ); // block SIGUSR1 signals 483 547 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; 488 552 } 489 553 … … 494 558 __lib_debug_write( STDERR_FILENO, abort_text, len ); 495 559 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 ); 498 562 __lib_debug_write( STDERR_FILENO, abort_text, len ); 499 } 563 } 500 564 else { 501 565 __lib_debug_write( STDERR_FILENO, ".\n", 2 ); … … 505 569 extern "C" { 506 570 void __lib_debug_acquire() { 507 lock( &kernel_debug_lock);571 lock( &kernel_debug_lock DEBUG_CTX2 ); 508 572 } 509 573 510 574 void __lib_debug_release() { 511 unlock( &kernel_debug_lock);575 unlock( &kernel_debug_lock ); 512 576 } 513 577 } … … 525 589 } 526 590 527 bool try_lock( spinlock * this ) {591 bool try_lock( spinlock * this DEBUG_CTX_PARAM2 ) { 528 592 return this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0; 529 593 } 530 594 531 void lock( spinlock * this ) {595 void lock( spinlock * this DEBUG_CTX_PARAM2 ) { 532 596 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 605 void lock_yield( spinlock * this DEBUG_CTX_PARAM2 ) { 606 for ( unsigned int i = 1;; i += 1 ) { 607 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; } 608 yield(); 609 } 610 LIB_DEBUG_DO( 611 this->prev_name = caller; 612 this->prev_thrd = this_thread; 613 ) 614 } 615 536 616 537 617 void unlock( spinlock * this ) { … … 539 619 } 540 620 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 } 621 void ?{}( semaphore * this, int count = 1 ) { 622 (&this->lock){}; 623 this->count = count; 624 (&this->waiting){}; 625 } 626 void ^?{}(semaphore * this) {} 627 628 void P(semaphore * this) { 629 lock( &this->lock DEBUG_CTX2 ); 630 this->count -= 1; 631 if ( this->count < 0 ) { 632 // queue current task 633 append( &this->waiting, (thread_desc *)this_thread ); 634 635 // atomically release spin lock and block 636 BlockInternal( &this->lock ); 637 } 638 else { 639 unlock( &this->lock ); 640 } 641 } 642 643 void V(semaphore * this) { 644 thread_desc * thrd = NULL; 645 lock( &this->lock DEBUG_CTX2 ); 646 this->count += 1; 647 if ( this->count <= 0 ) { 648 // remove task at head of waiting list 649 thrd = pop_head( &this->waiting ); 650 } 651 555 652 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 ); 569 656 } 570 657 … … 590 677 } 591 678 head->next = NULL; 592 } 679 } 593 680 return head; 594 681 } … … 609 696 this->top = top->next; 610 697 top->next = NULL; 611 } 698 } 612 699 return top; 613 700 } -
src/libcfa/concurrency/kernel_private.h
r55a68c3 r3d4b23fa 18 18 #define KERNEL_PRIVATE_H 19 19 20 #include "libhdr.h" 21 20 22 #include "kernel" 21 23 #include "thread" … … 23 25 #include "alarm.h" 24 26 25 #include "libhdr.h"26 27 27 28 //----------------------------------------------------------------------------- 28 29 // Scheduler 30 31 extern "C" { 32 void disable_interrupts(); 33 void enable_interrupts_noRF(); 34 void enable_interrupts( DEBUG_CTX_PARAM ); 35 } 36 29 37 void ScheduleThread( thread_desc * ); 38 static inline void WakeThread( thread_desc * thrd ) { 39 if( !thrd ) return; 40 41 disable_interrupts(); 42 ScheduleThread( thrd ); 43 enable_interrupts( DEBUG_CTX ); 44 } 30 45 thread_desc * nextThread(cluster * this); 31 46 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); 47 void BlockInternal(void); 48 void BlockInternal(spinlock * lock); 49 void BlockInternal(thread_desc * thrd); 50 void BlockInternal(spinlock * lock, thread_desc * thrd); 51 void BlockInternal(spinlock ** locks, unsigned short count); 52 void BlockInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count); 53 void LeaveThread(spinlock * lock, thread_desc * thrd); 38 54 39 55 //----------------------------------------------------------------------------- … … 60 76 extern cluster * systemCluster; 61 77 extern 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 } 78 extern volatile thread_local processor * this_processor; 79 extern volatile thread_local coroutine_desc * this_coroutine; 80 extern volatile thread_local thread_desc * this_thread; 81 extern volatile thread_local bool preemption_in_progress; 82 extern volatile thread_local unsigned short disable_preempt_count; 82 83 83 84 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/monitor
r55a68c3 r3d4b23fa 26 26 static inline void ?{}(monitor_desc * this) { 27 27 this->owner = NULL; 28 this->stack_owner = NULL;29 28 this->recursion = 0; 30 29 } -
src/libcfa/concurrency/monitor.c
r55a68c3 r3d4b23fa 19 19 #include <stdlib> 20 20 21 #include "libhdr.h" 21 22 #include "kernel_private.h" 22 #include "libhdr.h"23 23 24 24 //----------------------------------------------------------------------------- … … 44 44 45 45 extern "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); 51 51 52 52 if( !this->owner ) { … … 62 62 //Some one else has the monitor, wait in line for it 63 63 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 ourselves68 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; 69 69 } 70 70 … … 75 75 // leave pseudo code : 76 76 // 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 ); 82 82 83 83 //Leaving a recursion level, decrement the counter … … 96 96 unlock( &this->lock ); 97 97 98 LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);98 // LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner); 99 99 100 100 //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 ); 102 127 } 103 128 } … … 121 146 enter( this->m, this->count ); 122 147 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; 128 153 } 129 154 … … 131 156 leave( this->m, this->count ); 132 157 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; 135 160 } 136 161 … … 159 184 // Internal scheduling 160 185 void wait( condition * this, uintptr_t user_info = 0 ) { 161 LIB_DEBUG_PRINT_SAFE("Waiting\n");186 // LIB_DEBUG_PRINT_SAFE("Waiting\n"); 162 187 163 188 brand_condition( this ); … … 170 195 unsigned short count = this->monitor_count; 171 196 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 ScheduleInternal173 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 }; 177 202 178 203 __condition_criterion_t criteria[count]; 179 204 for(int i = 0; i < count; i++) { 180 205 (&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] ); 182 207 } 183 208 … … 201 226 } 202 227 203 LIB_DEBUG_PRINT_SAFE("Will unblock: ");228 // LIB_DEBUG_PRINT_SAFE("Will unblock: "); 204 229 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"); 208 233 209 234 // Everything is ready to go to sleep 210 ScheduleInternal( locks, count, threads, thread_count );235 BlockInternal( locks, count, threads, thread_count ); 211 236 212 237 … … 222 247 bool signal( condition * this ) { 223 248 if( is_empty( this ) ) { 224 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");249 // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 225 250 return false; 226 251 } … … 231 256 232 257 unsigned short count = this->monitor_count; 233 258 234 259 //Some more checking in debug 235 260 LIB_DEBUG_DO( 236 thread_desc * this_thrd = this_thread ();261 thread_desc * this_thrd = this_thread; 237 262 if ( this->monitor_count != this_thrd->current_monitor_count ) { 238 263 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 ); … … 248 273 //Lock all the monitors 249 274 lock_all( this->monitors, NULL, count ); 250 LIB_DEBUG_PRINT_SAFE("Signalling");275 // LIB_DEBUG_PRINT_SAFE("Signalling"); 251 276 252 277 //Pop the head of the waiting queue … … 256 281 for(int i = 0; i < count; i++) { 257 282 __condition_criterion_t * crit = &node->criteria[i]; 258 LIB_DEBUG_PRINT_SAFE(" %p", crit->target);283 // LIB_DEBUG_PRINT_SAFE(" %p", crit->target); 259 284 assert( !crit->ready ); 260 285 push( &crit->target->signal_stack, crit ); 261 286 } 262 287 263 LIB_DEBUG_PRINT_SAFE("\n");288 // LIB_DEBUG_PRINT_SAFE("\n"); 264 289 265 290 //Release … … 281 306 unsigned short count = this->monitor_count; 282 307 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 ScheduleInternal308 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 284 309 285 310 lock_all( this->monitors, locks, count ); 286 311 287 312 //create creteria 288 __condition_node_t waiter = { this_thread(), count, 0 };313 __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 }; 289 314 290 315 __condition_criterion_t criteria[count]; 291 316 for(int i = 0; i < count; i++) { 292 317 (&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] ); 294 319 push( &criteria[i].target->signal_stack, &criteria[i] ); 295 320 } … … 309 334 310 335 //Everything is ready to go to sleep 311 ScheduleInternal( locks, count, &signallee, 1 );336 BlockInternal( locks, count, &signallee, 1 ); 312 337 313 338 … … 325 350 326 351 uintptr_t front( condition * this ) { 327 verifyf( !is_empty(this), 352 verifyf( !is_empty(this), 328 353 "Attempt to access user data on an empty condition.\n" 329 354 "Possible cause is not checking if the condition is empty before reading stored data." … … 335 360 // Internal scheduling 336 361 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) { 337 // thread_desc * this = this_thread ();362 // thread_desc * this = this_thread; 338 363 339 364 // unsigned short count = this->current_monitor_count; 340 365 // 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 ScheduleInternal366 // spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 342 367 343 368 // lock_all( this->current_monitors, locks, count ); … … 348 373 349 374 // // // Everything is ready to go to sleep 350 // // ScheduleInternal( locks, count, threads, thread_count );375 // // BlockInternal( locks, count, threads, thread_count ); 351 376 352 377 … … 393 418 static inline void lock_all( spinlock ** locks, unsigned short count ) { 394 419 for( int i = 0; i < count; i++ ) { 395 lock ( locks[i]);420 lock_yield( locks[i] DEBUG_CTX2 ); 396 421 } 397 422 } … … 400 425 for( int i = 0; i < count; i++ ) { 401 426 spinlock * l = &source[i]->lock; 402 lock ( l);427 lock_yield( l DEBUG_CTX2 ); 403 428 if(locks) locks[i] = l; 404 429 } … … 443 468 for( int i = 0; i < count; i++ ) { 444 469 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 ); 446 471 if( &criteria[i] == target ) { 447 472 criteria[i].ready = true; 448 LIB_DEBUG_PRINT_SAFE( "True\n" );473 // LIB_DEBUG_PRINT_SAFE( "True\n" ); 449 474 } 450 475 … … 452 477 } 453 478 454 LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );479 // LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run ); 455 480 return ready2run ? node->waiting_thread : NULL; 456 481 } 457 482 458 483 static inline void brand_condition( condition * this ) { 459 thread_desc * thrd = this_thread ();484 thread_desc * thrd = this_thread; 460 485 if( !this->monitors ) { 461 LIB_DEBUG_PRINT_SAFE("Branding\n");486 // LIB_DEBUG_PRINT_SAFE("Branding\n"); 462 487 assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors ); 463 488 this->monitor_count = thrd->current_monitor_count; -
src/libcfa/concurrency/preemption.c
r55a68c3 r3d4b23fa 15 15 // 16 16 17 #include "libhdr.h" 17 18 #include "preemption.h" 18 19 19 20 extern "C" { 21 #include <errno.h> 22 #include <execinfo.h> 23 #define __USE_GNU 20 24 #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 24 37 25 38 __attribute__((weak)) unsigned int default_preemption() { … … 27 40 } 28 41 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 29 45 static void preempt( processor * this ); 30 46 static void timeout( thread_desc * this ); 31 47 48 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ); 49 void sigHandler_alarm ( __CFA_SIGPARMS__ ); 50 void sigHandler_segv ( __CFA_SIGPARMS__ ); 51 void sigHandler_abort ( __CFA_SIGPARMS__ ); 52 53 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ); 54 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); ) 55 56 #ifdef __x86_64__ 57 #define CFA_REG_IP REG_RIP 58 #else 59 #define CFA_REG_IP REG_EIP 60 #endif 61 62 32 63 //============================================================================================= 33 64 // Kernel Preemption logic 34 65 //============================================================================================= 35 66 36 void kernel_start_preemption() {37 38 }39 40 67 void tick_preemption() { 68 // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Ticking preemption\n" ); 69 41 70 alarm_list_t * alarms = &systemProcessor->alarms; 42 71 __cfa_time_t currtime = __kernel_get_time(); 43 72 while( alarms->head && alarms->head->alarm < currtime ) { 44 73 alarm_node_t * node = pop(alarms); 74 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking %p\n", node ); 75 45 76 if( node->kernel_alarm ) { 46 77 preempt( node->proc ); … … 50 81 } 51 82 83 verify( validate( alarms ) ); 84 52 85 if( node->period > 0 ) { 53 node->alarm +=node->period;86 node->alarm = currtime + node->period; 54 87 insert( alarms, node ); 55 88 } … … 62 95 __kernel_set_timer( alarms->head->alarm - currtime ); 63 96 } 97 98 verify( validate( alarms ) ); 99 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking preemption done\n" ); 64 100 } 65 101 66 102 void 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 68 105 alarm_node_t * alarm = this->preemption_alarm; 106 duration *= 1000; 69 107 70 108 // Alarms need to be enabled … … 89 127 } 90 128 129 //============================================================================================= 130 // Kernel Signal Tools 131 //============================================================================================= 132 133 LIB_DEBUG_DO( static thread_local void * last_interrupt = 0; ) 134 135 extern "C" { 136 void disable_interrupts() { 137 __attribute__((unused)) unsigned short new_val = __atomic_add_fetch_2( &disable_preempt_count, 1, __ATOMIC_SEQ_CST ); 138 verify( new_val < (unsigned short)65_000 ); 139 verify( new_val != (unsigned short) 0 ); 140 } 141 142 void enable_interrupts_noRF() { 143 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 144 verify( prev != (unsigned short) 0 ); 145 } 146 147 void enable_interrupts( DEBUG_CTX_PARAM ) { 148 processor * proc = this_processor; 149 thread_desc * thrd = this_thread; 150 unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 151 verify( prev != (unsigned short) 0 ); 152 if( prev == 1 && proc->pending_preemption ) { 153 proc->pending_preemption = false; 154 BlockInternal( thrd ); 155 } 156 157 LIB_DEBUG_DO( proc->last_enable = caller; ) 158 } 159 } 160 161 static inline void signal_unblock( int sig ) { 162 sigset_t mask; 163 sigemptyset( &mask ); 164 sigaddset( &mask, sig ); 165 166 if ( pthread_sigmask( SIG_UNBLOCK, &mask, NULL ) == -1 ) { 167 abortf( "internal error, pthread_sigmask" ); 168 } 169 } 170 171 static inline void signal_block( int sig ) { 172 sigset_t mask; 173 sigemptyset( &mask ); 174 sigaddset( &mask, sig ); 175 176 if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) { 177 abortf( "internal error, pthread_sigmask" ); 178 } 179 } 180 181 static inline bool preemption_ready() { 182 return disable_preempt_count == 0 && !preemption_in_progress; 183 } 184 185 static inline void defer_ctxSwitch() { 186 this_processor->pending_preemption = true; 187 } 188 189 static inline void defer_alarm() { 190 systemProcessor->pending_alarm = true; 191 } 192 193 static void preempt( processor * this ) { 194 pthread_kill( this->kernel_thread, SIGUSR1 ); 195 } 196 197 static void timeout( thread_desc * this ) { 198 //TODO : implement waking threads 199 } 200 201 //============================================================================================= 202 // Kernel Signal Startup/Shutdown logic 203 //============================================================================================= 204 205 static pthread_t alarm_thread; 206 void * alarm_loop( __attribute__((unused)) void * args ); 207 208 void kernel_start_preemption() { 209 LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n"); 210 __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO ); 211 // __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); 212 // __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); 213 214 signal_block( SIGALRM ); 215 216 pthread_create( &alarm_thread, NULL, alarm_loop, NULL ); 217 } 218 219 void kernel_stop_preemption() { 220 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopping\n"); 221 222 sigset_t mask; 223 sigfillset( &mask ); 224 sigprocmask( SIG_BLOCK, &mask, NULL ); 225 226 sigval val = { 1 }; 227 pthread_sigqueue( alarm_thread, SIGALRM, val ); 228 pthread_join( alarm_thread, NULL ); 229 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n"); 230 } 231 91 232 void ?{}( preemption_scope * this, processor * proc ) { 92 233 (&this->alarm){ proc }; … … 97 238 98 239 void ^?{}( preemption_scope * this ) { 240 disable_interrupts(); 241 99 242 update_preemption( this->proc, 0 ); 100 243 } 101 244 102 245 //============================================================================================= 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 249 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) { 250 LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); ) 119 251 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 ); 121 257 } 122 258 else { … … 125 261 } 126 262 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 } 263 void * alarm_loop( __attribute__((unused)) void * args ) { 264 sigset_t mask; 265 sigemptyset( &mask ); 266 sigaddset( &mask, SIGALRM ); 267 268 if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) { 269 abortf( "internal error, pthread_sigmask" ); 270 } 271 272 while( true ) { 273 siginfo_t info; 274 int sig = sigwaitinfo( &mask, &info ); 275 if( sig < 0 ) { 276 abortf( "internal error, sigwait" ); 277 } 278 else if( sig == SIGALRM ) 279 { 280 LIB_DEBUG_PRINT_SAFE("Kernel : Caught signal %d (%d)\n", sig, info.si_value.sival_int ); 281 if( info.si_value.sival_int == 0 ) 282 { 283 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 284 lock( &systemProcessor->alarm_lock DEBUG_CTX2 ); 285 tick_preemption(); 286 unlock( &systemProcessor->alarm_lock ); 287 } 288 else if( info.si_value.sival_int == 1 ) 289 { 290 break; 291 } 292 } 293 else 294 { 295 LIB_DEBUG_PRINT_SAFE("Kernel : Unexpected signal %d (%d)\n", sig, info.si_value.sival_int); 296 } 297 } 298 299 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread stopping\n"); 300 return NULL; 301 } 302 303 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) { 304 struct sigaction act; 305 306 act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler; 307 act.sa_flags = flags; 308 309 if ( sigaction( sig, &act, NULL ) == -1 ) { 310 LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, 311 " __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n", 312 sig, handler, flags, errno, strerror( errno ) 313 ); 314 _exit( EXIT_FAILURE ); 315 } 316 } 317 318 typedef void (*sa_handler_t)(int); 319 320 static void __kernel_sigdefault( int sig ) { 321 struct sigaction act; 322 323 // act.sa_handler = SIG_DFL; 324 act.sa_flags = 0; 325 sigemptyset( &act.sa_mask ); 326 327 if ( sigaction( sig, &act, NULL ) == -1 ) { 328 LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, 329 " __kernel_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n", 330 sig, errno, strerror( errno ) 331 ); 332 _exit( EXIT_FAILURE ); 333 } 334 } 335 336 //============================================================================================= 337 // Terminating Signals logic 338 //============================================================================================= 339 340 LIB_DEBUG_DO( 341 static void __kernel_backtrace( int start ) { 342 // skip first N stack frames 343 344 enum { Frames = 50 }; 345 void * array[Frames]; 346 int size = backtrace( array, Frames ); 347 char ** messages = backtrace_symbols( array, size ); 348 349 // find executable name 350 *index( messages[0], '(' ) = '\0'; 351 #ifdef __USE_STREAM__ 352 serr | "Stack back trace for:" | messages[0] | endl; 353 #else 354 fprintf( stderr, "Stack back trace for: %s\n", messages[0]); 355 #endif 356 357 // skip last 2 stack frames after main 358 for ( int i = start; i < size && messages != NULL; i += 1 ) { 359 char * name = NULL; 360 char * offset_begin = NULL; 361 char * offset_end = NULL; 362 363 for ( char *p = messages[i]; *p; ++p ) { 364 // find parantheses and +offset 365 if ( *p == '(' ) { 366 name = p; 367 } 368 else if ( *p == '+' ) { 369 offset_begin = p; 370 } 371 else if ( *p == ')' ) { 372 offset_end = p; 373 break; 374 } 375 } 376 377 // if line contains symbol print it 378 int frameNo = i - start; 379 if ( name && offset_begin && offset_end && name < offset_begin ) { 380 // delimit strings 381 *name++ = '\0'; 382 *offset_begin++ = '\0'; 383 *offset_end++ = '\0'; 384 385 #ifdef __USE_STREAM__ 386 serr | "(" | frameNo | ")" | messages[i] | ":" 387 | name | "+" | offset_begin | offset_end | endl; 388 #else 389 fprintf( stderr, "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end); 390 #endif 391 } 392 // otherwise, print the whole line 393 else { 394 #ifdef __USE_STREAM__ 395 serr | "(" | frameNo | ")" | messages[i] | endl; 396 #else 397 fprintf( stderr, "(%i) %s\n", frameNo, messages[i] ); 398 #endif 399 } 400 } 401 402 free( messages ); 403 } 404 ) 405 406 // void sigHandler_segv( __CFA_SIGPARMS__ ) { 407 // LIB_DEBUG_DO( 408 // #ifdef __USE_STREAM__ 409 // serr | "*CFA runtime error* program cfa-cpp terminated with" 410 // | (sig == SIGSEGV ? "segment fault." : "bus error.") 411 // | endl; 412 // #else 413 // fprintf( stderr, "*CFA runtime error* program cfa-cpp terminated with %s\n", sig == SIGSEGV ? "segment fault." : "bus error." ); 414 // #endif 415 416 // // skip first 2 stack frames 417 // __kernel_backtrace( 1 ); 418 // ) 419 // exit( EXIT_FAILURE ); 420 // } 421 422 // void sigHandler_abort( __CFA_SIGPARMS__ ) { 423 // // skip first 6 stack frames 424 // LIB_DEBUG_DO( __kernel_backtrace( 6 ); ) 425 426 // // reset default signal handler 427 // __kernel_sigdefault( SIGABRT ); 428 429 // raise( SIGABRT ); 430 // } -
src/libcfa/concurrency/thread
r55a68c3 r3d4b23fa 54 54 } 55 55 56 thread_desc * this_thread(void);56 extern volatile thread_local thread_desc * this_thread; 57 57 58 58 forall( dtype T | is_thread(T) ) -
src/libcfa/concurrency/thread.c
r55a68c3 r3d4b23fa 28 28 } 29 29 30 extern thread_local processor * this_processor;30 extern volatile thread_local processor * this_processor; 31 31 32 32 //----------------------------------------------------------------------------- … … 71 71 coroutine_desc* thrd_c = get_coroutine(this); 72 72 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; 75 74 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); 77 76 77 disable_interrupts(); 78 78 create_stack(&thrd_c->stack, thrd_c->stack.size); 79 this_coroutine = thrd_c; 79 80 CtxStart(this, CtxInvokeThread); 81 assert( thrd_c->last->stack.context ); 80 82 CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context ); 81 83 82 84 ScheduleThread(thrd_h); 85 enable_interrupts( DEBUG_CTX ); 83 86 } 84 87 85 88 void yield( void ) { 86 ScheduleInternal( this_processor->current_thread );89 BlockInternal( (thread_desc *)this_thread ); 87 90 } 88 91 … … 95 98 void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) { 96 99 // set state of current coroutine to inactive 97 src->state = Inactive;100 src->state = src->state == Halted ? Halted : Inactive; 98 101 dst->state = Active; 99 102 … … 103 106 // set new coroutine that the processor is executing 104 107 // and context switch to it 105 this_processor->current_coroutine = dst; 108 this_coroutine = dst; 109 assert( src->stack.context ); 106 110 CtxSwitch( src->stack.context, dst->stack.context ); 107 this_ processor->current_coroutine = src;111 this_coroutine = src; 108 112 109 113 // set state of new coroutine to active 110 dst->state = Inactive;114 dst->state = dst->state == Halted ? Halted : Inactive; 111 115 src->state = Active; 112 116 } -
src/libcfa/exception.c
r55a68c3 r3d4b23fa 10 10 // Created On : Mon Jun 26 15:13:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Nov 26 15:11:00 201713 // Update Count : 012 // Last Modified On : Tus Jul 11 16:36:00 2017 13 // Update Count : 1 14 14 // 15 15 … … 44 44 // RESUMPTION ================================================================ 45 45 46 void __cfaehm__throw_resum ption(exception * except) {46 void __cfaehm__throw_resume(exception * except) { 47 47 48 48 // DEBUG … … 65 65 66 66 // Fall back to termination: 67 __cfaehm__throw_terminat ion(except);67 __cfaehm__throw_terminate(except); 68 68 // TODO: Default handler for resumption. 69 69 } … … 111 111 } 112 112 113 void __cfaehm__throw_terminat ion( exception * val ) {113 void __cfaehm__throw_terminate( exception * val ) { 114 114 // Store the current exception 115 115 shared_stack.current_exception = *val; … … 147 147 148 148 // Nesting this the other way would probably be faster. 149 void __cfaehm__rethrow_terminat ion(void) {149 void __cfaehm__rethrow_terminate(void) { 150 150 // DEBUG 151 151 printf("Rethrowing termination exception\n"); 152 152 153 __cfaehm__throw_terminat ion(&shared_stack.current_exception);153 __cfaehm__throw_terminate(&shared_stack.current_exception); 154 154 } 155 155 -
src/libcfa/exception.h
r55a68c3 r3d4b23fa 10 10 // Created On : Mon Jun 26 15:11:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Nov 26 15:11:00 201713 // Update Count : 012 // Last Modified On : Tus Jul 11 16:31:00 2017 13 // Update Count : 2 14 14 // 15 15 … … 22 22 23 23 #ifdef __CFORALL__ 24 extern " BuiltinC" {24 extern "C" { 25 25 #endif 26 26 27 27 // Used in throw statement translation. 28 void __cfaehm__throw_terminat ion(exception * except) __attribute__((noreturn));29 void __cfaehm__rethrow_terminat ion() __attribute__((noreturn));30 void __cfaehm__throw_resum ption(exception * except);28 void __cfaehm__throw_terminate(exception * except) __attribute__((noreturn)); 29 void __cfaehm__rethrow_terminate() __attribute__((noreturn)); 30 void __cfaehm__throw_resume(exception * except); 31 31 32 32 // Function catches termination exceptions. -
src/libcfa/fstream
r55a68c3 r3d4b23fa 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 1 16:37:53201713 // Update Count : 11 212 // Last Modified On : Fri Jul 7 08:32:38 2017 13 // Update Count : 117 14 14 // 15 15 16 #ifndef __FSTREAM_H__ 17 #define __FSTREAM_H__ 16 #pragma once 18 17 19 18 #include "iostream" 20 19 21 enum { sep arateSize = 16 };20 enum { sepSize = 16 }; 22 21 struct ofstream { 23 22 void * file; 24 23 _Bool sepDefault; 25 24 _Bool sepOnOff; 26 _Bool lastSepOn;25 _Bool sawNL; 27 26 const char * sepCur; 28 char separator[sep arateSize];29 char tupleSeparator[sep arateSize];27 char separator[sepSize]; 28 char tupleSeparator[sepSize]; 30 29 }; // ofstream 31 30 … … 36 35 const char * sepGetCur( ofstream * ); 37 36 void sepSetCur( ofstream *, const char * ); 38 _Bool lastSepOn( ofstream * ); 37 _Bool getNL( ofstream * ); 38 void setNL( ofstream *, _Bool ); 39 39 40 40 // public … … 75 75 extern ifstream * sin; 76 76 77 #endif // __FSTREAM_H__78 79 77 // Local Variables: // 80 78 // mode: c // -
src/libcfa/fstream.c
r55a68c3 r3d4b23fa 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 1 16:37:54201713 // Update Count : 2 4212 // Last Modified On : Thu Jul 6 18:38:25 2017 13 // Update Count : 251 14 14 // 15 15 … … 33 33 this->sepDefault = sepDefault; 34 34 this->sepOnOff = sepOnOff; 35 this->lastSepOn = false;36 35 sepSet( this, separator ); 37 36 sepSetCur( this, sepGet( this ) ); … … 40 39 41 40 // 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; } 44 42 void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; } 45 43 void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; } 46 44 const char * sepGetCur( ofstream * os ) { return os->sepCur; } 47 45 void sepSetCur( ofstream * os, const char * sepCur ) { os->sepCur = sepCur; } 46 _Bool getNL( ofstream * os ) { return os->sawNL; } 47 void setNL( ofstream * os, _Bool state ) { os->sawNL = state; } 48 48 49 49 // public 50 void sepOn( ofstream * os ) { os-> lastSepOn = true; os->sepOnOff = true; }51 void sepOff( ofstream * os ) { os-> lastSepOn = false; os->sepOnOff = 0; }50 void sepOn( ofstream * os ) { os->sepOnOff = ! getNL( os ); } 51 void sepOff( ofstream * os ) { os->sepOnOff = false; } 52 52 53 53 _Bool sepDisable( ofstream *os ) { 54 54 _Bool temp = os->sepDefault; 55 55 os->sepDefault = false; 56 os->lastSepOn = false;57 56 sepReset( os ); 58 57 return temp; … … 69 68 void sepSet( ofstream * os, const char * s ) { 70 69 assert( s ); 71 strncpy( os->separator, s, sep arateSize - 1 );72 os->separator[sep arateSize - 1] = '\0';70 strncpy( os->separator, s, sepSize - 1 ); 71 os->separator[sepSize - 1] = '\0'; 73 72 } // sepSet 74 73 … … 76 75 void sepSetTuple( ofstream * os, const char * s ) { 77 76 assert( s ); 78 strncpy( os->tupleSeparator, s, sep arateSize - 1 );79 os->tupleSeparator[sep arateSize - 1] = '\0';77 strncpy( os->tupleSeparator, s, sepSize - 1 ); 78 os->tupleSeparator[sepSize - 1] = '\0'; 80 79 } // sepSet 81 80 … … 153 152 154 153 void open( ifstream * is, const char * name, const char * mode ) { 155 FILE * t= fopen( name, mode );156 if ( t == 0 ) {// do not change unless successful154 FILE *file = fopen( name, mode ); 155 if ( file == 0 ) { // do not change unless successful 157 156 fprintf( stderr, IO_MSG "open input file \"%s\", ", name ); 158 157 perror( 0 ); 159 158 exit( EXIT_FAILURE ); 160 159 } // if 161 is->file = t;160 is->file = file; 162 161 } // open 163 162 -
src/libcfa/gmp
r55a68c3 r3d4b23fa 10 10 // Created On : Tue Apr 19 08:43:43 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat May 27 09:55:51201713 // Update Count : 1 412 // Last Modified On : Fri Jul 7 09:33:20 2017 13 // Update Count : 15 14 14 // 15 15 16 16 // https://gmplib.org/gmp-man-6.1.1.pdf 17 18 #pragma once 17 19 18 20 #include <gmp.h> // GNU multi-precise integers -
src/libcfa/iostream
r55a68c3 r3d4b23fa 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jul 2 08:42:56201713 // Update Count : 11 012 // Last Modified On : Fri Jul 7 08:35:59 2017 13 // Update Count : 118 14 14 // 15 15 16 #ifndef __IOSTREAM_H__ 17 #define __IOSTREAM_H__ 16 #pragma once 18 17 19 18 #include "iterator" … … 26 25 const char * sepGetCur( ostype * ); // get current separator string 27 26 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 29 29 // public 30 30 void sepOn( ostype * ); // turn separator state on … … 82 82 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, ostype * (*)( ostype * ) ); 83 83 forall( dtype ostype | ostream( ostype ) ) ostype * endl( ostype * ); 84 forall( dtype ostype | ostream( ostype ) ) ostype * sep( ostype * ); 85 forall( dtype ostype | ostream( ostype ) ) ostype * sepTuple( ostype * ); 84 86 forall( dtype ostype | ostream( ostype ) ) ostype * sepOn( ostype * ); 85 87 forall( dtype ostype | ostream( ostype ) ) ostype * sepOff( ostype * ); … … 137 139 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_cstrC ); 138 140 139 #endif // __IOSTREAM_H140 141 141 // Local Variables: // 142 142 // mode: c // -
src/libcfa/iostream.c
r55a68c3 r3d4b23fa 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jul 2 08:54:02201713 // Update Count : 3 7512 // Last Modified On : Thu Jul 6 18:14:17 2017 13 // Update Count : 396 14 14 // 15 15 … … 18 18 extern "C" { 19 19 #include <stdio.h> 20 #include <stdbool.h> // true/false 20 21 #include <string.h> // strlen 21 22 #include <float.h> // DBL_DIG, LDBL_DIG … … 24 25 25 26 forall( dtype ostype | ostream( ostype ) ) 26 ostype * ?|?( ostype * os, char c ) { 27 fmt( os, "%c", c ); 27 ostype * ?|?( ostype * os, char ch ) { 28 fmt( os, "%c", ch ); 29 if ( ch == '\n' ) setNL( os, true ); 28 30 sepOff( os ); 29 31 return os; … … 180 182 181 183 // 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 unsigned184 size_t len = strlen( cp ); 185 ch = cp[len - 1]; // must make unsigned 184 186 if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) { 185 187 sepOn( os ); … … 187 189 sepOff( os ); 188 190 } // if 191 if ( ch == '\n' ) setNL( os, true ); // check *AFTER* sepPrt call above as it resets NL flag 189 192 return write( os, cp, len ); 190 193 } // ?|? … … 216 219 217 220 forall( dtype ostype | ostream( ostype ) ) 221 ostype * sep( ostype * os ) { 222 os | sepGet( os ); 223 return os; 224 } // sep 225 226 forall( dtype ostype | ostream( ostype ) ) 227 ostype * sepTuple( ostype * os ) { 228 os | sepGetTuple( os ); 229 return os; 230 } // sepTuple 231 232 forall( dtype ostype | ostream( ostype ) ) 218 233 ostype * endl( ostype * os ) { 219 if ( lastSepOn( os ) ) fmt( os, "%s", sepGetCur( os ) );220 234 os | '\n'; 235 setNL( os, true ); 221 236 flush( os ); 222 237 sepOff( os ); // prepare for next line -
src/libcfa/iterator
r55a68c3 r3d4b23fa 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 18:06:05 201613 // Update Count : 912 // Last Modified On : Fri Jul 7 08:37:25 2017 13 // Update Count : 10 14 14 // 15 15 16 #ifndef ITERATOR_H 17 #define ITERATOR_H 16 #pragma once 18 17 19 18 // An iterator can be used to traverse a data structure. … … 39 38 40 39 forall( 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 ) );40 void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) ); 42 41 43 42 forall( 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 43 void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) ); 47 44 48 45 // Local Variables: // -
src/libcfa/iterator.c
r55a68c3 r3d4b23fa 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 18:08:11 201613 // Update Count : 2 712 // Last Modified On : Fri Jul 7 08:38:23 2017 13 // Update Count : 28 14 14 // 15 15 … … 17 17 18 18 forall( 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 ) ) {19 void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) { 20 20 for ( iterator_type i = begin; i != end; ++i ) { 21 21 func( *i ); 22 } 23 } 22 } // for 23 } // for_each 24 24 25 25 forall( 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 ) ) {26 void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) { 27 27 for ( iterator_type i = end; i != begin; ) { 28 28 --i; 29 29 func( *i ); 30 } 31 } 30 } // for 31 } // for_each_reverse 32 32 33 33 // Local Variables: // -
src/libcfa/libhdr/libalign.h
r55a68c3 r3d4b23fa 1 // -*- Mode: C++ -*- 1 // -*- Mode: C++ -*- 2 2 // 3 3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 18 18 // Free Software Foundation; either version 2.1 of the License, or (at your 19 19 // option) any later version. 20 // 20 // 21 21 // This library is distributed in the hope that it will be useful, but WITHOUT 22 22 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23 23 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 24 24 // for more details. 25 // 25 // 26 26 // You should have received a copy of the GNU Lesser General Public License 27 27 // along with this library. 28 // 28 // 29 29 30 30 … … 33 33 34 34 #include "assert" 35 #include <stdbool.h> 35 36 36 // Minimum size used to align memory boundaries for memory allocations. 37 // Minimum size used to align memory boundaries for memory allocations. 37 38 #define libAlign() (sizeof(double)) 38 39 -
src/libcfa/libhdr/libdebug.h
r55a68c3 r3d4b23fa 18 18 19 19 #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 22 26 #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 25 33 #endif 26 34 … … 51 59 52 60 #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 ); 59 69 #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) 66 78 #endif 67 79 -
src/libcfa/limits
r55a68c3 r3d4b23fa 10 10 // Created On : Wed Apr 6 18:06:52 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Apr 6 21:08:16 201613 // Update Count : 612 // Last Modified On : Fri Jul 7 09:33:57 2017 13 // Update Count : 7 14 14 // 15 15 16 #ifndef LIMITS_H 17 #define LIMITS_H 16 #pragma once 18 17 19 18 // Integral Constants … … 110 109 extern const long _Complex _1_SQRT_2; // 1 / sqrt(2) 111 110 112 #endif // LIMITS_H113 114 111 // Local Variables: // 115 112 // mode: c // -
src/libcfa/math
r55a68c3 r3d4b23fa 10 10 // Created On : Mon Apr 18 23:37:04 2016 11 11 // 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 18 17 19 18 extern "C" { … … 345 344 long double scalbln( long double, long int ); 346 345 347 #endif // MATH_H348 349 346 // Local Variables: // 350 347 // mode: c // -
src/libcfa/rational
r55a68c3 r3d4b23fa 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Mon May 15 21:30:12201715 // Update Count : 9 014 // Last Modified On : Fri Jul 7 09:34:33 2017 15 // Update Count : 93 16 16 // 17 17 18 #ifndef RATIONAL_H 19 #define RATIONAL_H 18 #pragma once 20 19 21 20 #include "iostream" … … 47 46 // implementation 48 47 49 forall 48 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 50 49 struct Rational { 51 50 RationalImpl numerator, denominator; // invariant: denominator > 0 … … 54 53 // constructors 55 54 56 forall 55 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 57 56 void ?{}( Rational(RationalImpl) * r ); 58 57 59 forall 58 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 60 59 void ?{}( Rational(RationalImpl) * r, RationalImpl n ); 61 60 62 forall 61 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 63 62 void ?{}( Rational(RationalImpl) * r, RationalImpl n, RationalImpl d ); 64 63 65 forall 64 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 66 65 void ?{}( Rational(RationalImpl) * r, zero_t ); 67 66 68 forall 67 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 69 68 void ?{}( Rational(RationalImpl) * r, one_t ); 70 69 71 // getter for numerator/denominator70 // numerator/denominator getter 72 71 73 forall 72 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 74 73 RationalImpl numerator( Rational(RationalImpl) r ); 75 74 76 forall 75 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 77 76 RationalImpl denominator( Rational(RationalImpl) r ); 78 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 77 78 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 79 79 [ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ); 80 80 81 // setter for numerator/denominator81 // numerator/denominator setter 82 82 83 forall 83 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 84 84 RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ); 85 85 86 forall 86 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 87 87 RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ); 88 88 89 89 // comparison 90 90 91 forall 91 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 92 92 int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 93 93 94 forall 94 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 95 95 int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 96 96 97 forall 97 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 98 98 int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 99 99 100 forall 100 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 101 101 int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 102 102 103 forall 103 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 104 104 int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 105 105 106 forall 106 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 107 107 int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 108 108 109 109 // arithmetic 110 110 111 forall 111 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 112 112 Rational(RationalImpl) +?( Rational(RationalImpl) r ); 113 113 114 forall 114 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 115 115 Rational(RationalImpl) -?( Rational(RationalImpl) r ); 116 116 117 forall 117 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 118 118 Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 119 119 120 forall 120 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 121 121 Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 122 122 123 forall 123 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 124 124 Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 125 125 126 forall 126 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 127 127 Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 128 128 129 129 // conversion 130 forall 130 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) 131 131 double widen( Rational(RationalImpl) r ); 132 forall 132 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double );} ) 133 133 Rational(RationalImpl) narrow( double f, RationalImpl md ); 134 134 135 135 // I/O 136 forall 136 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 137 137 forall( dtype istype | istream( istype ) | { istype * ?|?( istype *, RationalImpl * ); } ) 138 138 istype * ?|?( istype *, Rational(RationalImpl) * ); 139 139 140 forall 140 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 141 141 forall( dtype ostype | ostream( ostype ) | { ostype * ?|?( ostype *, RationalImpl ); } ) 142 142 ostype * ?|?( ostype *, Rational(RationalImpl ) ); 143 144 #endif // RATIONAL_H145 143 146 144 // Local Variables: // -
src/libcfa/rational.c
r55a68c3 r3d4b23fa 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 15 21:29:23201713 // Update Count : 1 4912 // Last Modified On : Tue May 16 18:35:36 2017 13 // Update Count : 150 14 14 // 15 15 … … 22 22 // Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce rationals. 23 23 // alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm 24 forall 24 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 25 25 static RationalImpl gcd( RationalImpl a, RationalImpl b ) { 26 26 for ( ;; ) { // Euclid's algorithm … … 33 33 } // gcd 34 34 35 forall 35 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 36 36 static RationalImpl simplify( RationalImpl * n, RationalImpl * d ) { 37 37 if ( *d == (RationalImpl){0} ) { … … 46 46 // constructors 47 47 48 forall 48 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 49 49 void ?{}( Rational(RationalImpl) * r ) { 50 50 r{ (RationalImpl){0}, (RationalImpl){1} }; 51 51 } // rational 52 52 53 forall 53 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 54 54 void ?{}( Rational(RationalImpl) * r, RationalImpl n ) { 55 55 r{ n, (RationalImpl){1} }; 56 56 } // rational 57 57 58 forall 58 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 59 59 void ?{}( Rational(RationalImpl) * r, RationalImpl n, RationalImpl d ) { 60 60 RationalImpl t = simplify( &n, &d ); // simplify … … 66 66 // getter for numerator/denominator 67 67 68 forall 68 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 69 69 RationalImpl numerator( Rational(RationalImpl) r ) { 70 70 return r.numerator; 71 71 } // numerator 72 72 73 forall 73 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 74 74 RationalImpl denominator( Rational(RationalImpl) r ) { 75 75 return r.denominator; 76 76 } // denominator 77 77 78 forall 78 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 79 79 [ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ) { 80 80 return *dest = src.[ numerator, denominator ]; … … 83 83 // setter for numerator/denominator 84 84 85 forall 85 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 86 86 RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ) { 87 87 RationalImpl prev = r.numerator; … … 92 92 } // numerator 93 93 94 forall 94 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 95 95 RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ) { 96 96 RationalImpl prev = r.denominator; … … 104 104 // comparison 105 105 106 forall 106 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 107 107 int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 108 108 return l.numerator * r.denominator == l.denominator * r.numerator; 109 109 } // ?==? 110 110 111 forall 111 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 112 112 int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 113 113 return ! ( l == r ); 114 114 } // ?!=? 115 115 116 forall 116 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 117 117 int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 118 118 return l.numerator * r.denominator < l.denominator * r.numerator; 119 119 } // ?<? 120 120 121 forall 121 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 122 122 int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 123 123 return l.numerator * r.denominator <= l.denominator * r.numerator; 124 124 } // ?<=? 125 125 126 forall 126 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 127 127 int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 128 128 return ! ( l <= r ); 129 129 } // ?>? 130 130 131 forall 131 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 132 132 int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 133 133 return ! ( l < r ); … … 137 137 // arithmetic 138 138 139 forall 139 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 140 140 Rational(RationalImpl) +?( Rational(RationalImpl) r ) { 141 141 Rational(RationalImpl) t = { r.numerator, r.denominator }; … … 143 143 } // +? 144 144 145 forall 145 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 146 146 Rational(RationalImpl) -?( Rational(RationalImpl) r ) { 147 147 Rational(RationalImpl) t = { -r.numerator, r.denominator }; … … 149 149 } // -? 150 150 151 forall 151 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 152 152 Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 153 153 if ( l.denominator == r.denominator ) { // special case … … 160 160 } // ?+? 161 161 162 forall 162 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 163 163 Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 164 164 if ( l.denominator == r.denominator ) { // special case … … 171 171 } // ?-? 172 172 173 forall 173 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 174 174 Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 175 175 Rational(RationalImpl) t = { l.numerator * r.numerator, l.denominator * r.denominator }; … … 177 177 } // ?*? 178 178 179 forall 179 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 180 180 Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 181 181 if ( r.numerator < (RationalImpl){0} ) { … … 190 190 // conversion 191 191 192 forall 192 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) 193 193 double widen( Rational(RationalImpl) r ) { 194 194 return convert( r.numerator ) / convert( r.denominator ); … … 196 196 197 197 // http://www.ics.uci.edu/~eppstein/numth/frap.c 198 forall 198 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } ) 199 199 Rational(RationalImpl) narrow( double f, RationalImpl md ) { 200 200 if ( md <= (RationalImpl){1} ) { // maximum fractional digits too small? … … 227 227 // I/O 228 228 229 forall 229 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 230 230 forall( dtype istype | istream( istype ) | { istype * ?|?( istype *, RationalImpl * ); } ) 231 231 istype * ?|?( istype * is, Rational(RationalImpl) * r ) { … … 238 238 } // ?|? 239 239 240 forall 240 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 241 241 forall( dtype ostype | ostream( ostype ) | { ostype * ?|?( ostype *, RationalImpl ); } ) 242 242 ostype * ?|?( ostype * os, Rational(RationalImpl ) r ) { -
src/libcfa/stdlib
r55a68c3 r3d4b23fa 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // 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 18 17 19 18 //--------------------------------------- … … 232 231 void swap( T * t1, T * t2 ); 233 232 234 #endif // STDLIB_H235 236 233 // Local Variables: // 237 234 // mode: c // -
src/main.cc
r55a68c3 r3d4b23fa 10 10 // Author : Richard C. Bilson 11 11 // Created On : Fri May 15 23:12:02 2015 12 // Last Modified By : Peter A. Buhr13 // Last Modified On : Thu Jun 29 12:46:50 201714 // Update Count : 44 112 // Last Modified By : Andrew Beach 13 // Last Modified On : Fri Jul 7 11:13:00 2017 14 // Update Count : 442 15 15 // 16 16 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... 51 60 52 61 using namespace std; … … 206 215 FILE * builtins = fopen( libcfap | treep ? "../prelude/builtins.cf" : CFA_LIBDIR "/builtins.cf", "r" ); 207 216 assertf( builtins, "cannot open builtins.cf\n" ); 208 parse( builtins, LinkageSpec::Builtin );217 parse( builtins, LinkageSpec::BuiltinCFA ); 209 218 } // if 210 219 } // if -
src/prelude/Makefile.in
r55a68c3 r3d4b23fa 294 294 esac; \ 295 295 done; \ 296 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/prelude/Makefile'; \296 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/prelude/Makefile'; \ 297 297 $(am__cd) $(top_srcdir) && \ 298 $(AUTOMAKE) -- gnusrc/prelude/Makefile298 $(AUTOMAKE) --foreign src/prelude/Makefile 299 299 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 300 300 @case '$?' in \ -
src/tests/.expect/32/math.txt
r55a68c3 r3d4b23fa 22 22 cos:0.540302 0.54030230586814 0.540302305868139717 0.83373-0.988898i 0.833730025131149-0.988897705762865i 0.833730025131149049-0.988897705762865096i 23 23 tan: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.6662 4+1.06128i 0.666239432492515+1.06127506190504i 0.666239432492515255+1.06127506190503565i24 asin:1.5708 1.5707963267949 1.57079632679489662 0.666239+1.06128i 0.666239432492515+1.06127506190504i 0.666239432492515255+1.06127506190503565i 25 25 acos:0 0 0 0.904557-1.06128i 0.904556894302381-1.06127506190504i 0.904556894302381364-1.06127506190503565i 26 26 atan: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 9 9 9000 10 10 10000 11 1100012 1200013 1300014 1400015 1500016 1600017 1700018 1800019 1900020 2000021 2100022 2200023 2300024 2400025 2500026 2600027 2700028 2800029 2900030 3000031 3100032 3200033 3300034 3400035 3500036 3600037 3700038 3800039 3900040 4000041 4100042 4200043 4300044 4400045 4500046 4600047 4700048 4800049 4900050 5000051 5100052 5200053 5300054 5400055 5500056 5600057 5700058 5800059 5900060 6000061 6100062 6200063 6300064 6400065 6500066 6600067 6700068 6800069 6900070 7000071 7100072 7200073 7300074 7400075 7500076 7600077 7700078 7800079 7900080 8000081 8100082 8200083 8300084 8400085 8500086 8600087 8700088 8800089 8900090 9000091 9100092 9200093 9300094 9400095 9500096 9600097 9700098 9800099 99000100 100000101 11 All waiter done -
src/tests/.expect/io.txt
r55a68c3 r3d4b23fa 4 4 123 5 5 6 opening delimiters 6 opening delimiters 7 7 x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10 8 8 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 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 11 11 12 opening/closing delimiters 12 opening/closing delimiters 13 13 x`1`x'2'x"3"x:4:x 5 x 6 x 14 14 7 … … 19 19 x 20 20 10 21 x 21 x 22 22 23 override opening/closing delimiters 23 override opening/closing delimiters 24 24 x ( 1 ) x 2 , x 3 :x: 4 25 25 26 input bacis types 26 input bacis types 27 27 28 output basic types 28 output basic types 29 29 A 30 30 1 2 3 4 5 6 7 8 … … 32 32 1.1+2.3i 1.1-2.3i 1.1-2.3i 33 33 34 tuples 35 1, 2, 3 3, 4, 534 tuples 35 1, 2, 3 4, 5, 6 36 36 37 toggle separator 37 toggle separator 38 38 1.11.21.3 39 39 1.1+2.3i1.1-2.3i1.1-2.3i 40 abcxyz 41 abcxyz 40 1.1+2.3i 1.1-2.3i1.1-2.3i 41 1.1+2.3i 1.1-2.3i 1.1-2.3i 42 1.1+2.3i1.1-2.3i 1.1-2.3i 43 abcxyz 44 abcxyz 42 45 43 change separator 44 from " "to ", $"46 change separator 47 from " " to ", $" 45 48 1.1, $1.2, $1.3 46 49 1.1+2.3i, $1.1-2.3i, $1.1-2.3i 47 abc, $xyz , $48 1, 2, 3, $ 3, 4, 550 abc, $xyz 51 1, 2, 3, $4, 5, 6 49 52 50 from ", $" to " "53 from ", $" to " " 51 54 1.1 1.2 1.3 52 55 1.1+2.3i 1.1-2.3i 1.1-2.3i 53 abc xyz 54 1, 2, 3 3, 4, 556 abc xyz 57 1, 2, 3 4, 5, 6 55 58 56 1 2 3 59 check sepOn/sepOff 60 1 2 3 57 61 12 3 58 1 2 359 62 1 2 3 60 63 1 2 3 61 64 65 1 2 3 66 67 check enable/disable 62 68 123 63 69 1 23 … … 65 71 123 66 72 1 2 3 67 123 73 123 68 74 1 2 3 69 75 70 1 2 3 3 4 5" "71 1, 2, 3 3, 4, 5 ","72 1, 2, 3 3, 4, 576 1 2 3 4 5 6 " " 77 1, 2, 3 4, 5, 6 " " 78 1, 2, 3 4, 5, 6 73 79 74 80 3, 4, a, 7.2 75 81 3, 4, a, 7.2 76 82 3 4 a 7.2 77 83 3 4 a 7.234a7.23 4 a 7.2 78 84 3-4-a-7.2^3^4^3-4-a-7.2 -
src/tests/Makefile.am
r55a68c3 r3d4b23fa 29 29 30 30 # applies to both programs 31 EXTRA_FLAGS = 32 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ ${EXTRA_FLAGS} 31 DEBUG_FLAGS = 32 33 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ 34 if !BUILD_DEBUG 35 BUILD_FLAGS += -nodebug 36 else 37 if !BUILD_RELEASE 38 BUILD_FLAGS += -debug 39 else 40 BUILD_FLAGS += ${DEBUG_FLAGS} 41 endif 42 endif 43 33 44 TEST_FLAGS = $(if $(test), 2> .err/${@}.log, ) 34 45 AM_CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS} -
src/tests/Makefile.in
r55a68c3 r3d4b23fa 92 92 host_triplet = @host@ 93 93 @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} 94 97 EXTRA_PROGRAMS = fstream_test$(EXEEXT) vector_test$(EXEEXT) \ 95 98 avl_test$(EXEEXT) … … 320 323 321 324 # applies to both programs 322 EXTRA_FLAGS = 323 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ ${EXTRA_FLAGS} 325 DEBUG_FLAGS = 326 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ \ 327 $(am__append_2) $(am__append_3) $(am__append_4) 324 328 TEST_FLAGS = $(if $(test), 2> .err/${@}.log, ) 325 329 AM_CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS} … … 343 347 esac; \ 344 348 done; \ 345 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/tests/Makefile'; \349 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tests/Makefile'; \ 346 350 $(am__cd) $(top_srcdir) && \ 347 $(AUTOMAKE) -- gnusrc/tests/Makefile351 $(AUTOMAKE) --foreign src/tests/Makefile 348 352 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 349 353 @case '$?' in \ -
src/tests/io.c
r55a68c3 r3d4b23fa 10 10 // Created On : Wed Mar 2 16:56:02 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jul 2 09:40:58201713 // Update Count : 6812 // Last Modified On : Thu Jul 6 23:26:12 2017 13 // Update Count : 78 14 14 // 15 15 … … 104 104 105 105 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 ] ]; 107 107 sout | t1 | t2 | endl; // print tuple 108 108 sout | endl; … … 110 110 sout | "toggle separator" | endl; 111 111 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 115 118 sout | endl; 116 119 117 120 sout | "change separator" | endl; 118 sout | "from \" " | sepGet( sout )| "\"";121 sout | "from \"" | sep | "\""; 119 122 sepSet( sout, ", $" ); // change separator, maximum of 15 characters 120 sout | " to \" " | sepGet( sout )| "\"" | endl;123 sout | " to \"" | sep | "\"" | endl; 121 124 sout | f | d | ld | endl 122 125 | fc | dc | ldc | endl … … 124 127 | t1 | t2 | endl; // print tuple 125 128 sout | endl; 126 sout | "from \"" | sep Get( sout ) | "\"";129 sout | "from \"" | sep | "\" "; 127 130 sepSet( sout, " " ); // restore separator 128 sout | "to \"" | sep Get( sout )| "\"" | endl;131 sout | "to \"" | sep | "\"" | endl; 129 132 sout | f | d | ld | endl 130 133 | fc | dc | ldc | endl … … 133 136 sout | endl; 134 137 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 136 140 sout | 1 | sepOff | 2 | 3 | endl; // locally turn off implicit separator 137 sout | sepOn | 1 | 2 | 3 | sepOn | sepOff | endl; // separator at startof line138 sout | 1 | 2 | 3 | endl | sepOn; //separator at start of next line141 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 139 143 sout | 1 | 2 | 3 | endl; 140 144 sout | endl; 141 145 146 sout | "check enable/disable" | endl; 142 147 sout | sepDisable | 1 | 2 | 3 | endl; // globally turn off implicit separation 143 148 sout | 1 | sepOn | 2 | 3 | endl; // locally turn on implicit separator … … 149 154 sout | endl; 150 155 156 // sout | fmt( d, "%8.3f" ) || endl; 157 // sout | endl; 158 151 159 sepSetTuple( sout, " " ); // set tuple separator from ", " to " " 152 sout | t1 | t2 | " \"" | sep GetTuple( sout )| "\"" | endl;160 sout | t1 | t2 | " \"" | sep | "\"" | endl; 153 161 sepSetTuple( sout, ", " ); // reset tuple separator to ", " 154 sout | t1 | t2 | " \"" | sep GetTuple( sout )| "\"" | endl;162 sout | t1 | t2 | " \"" | sep | "\"" | endl; 155 163 sout | t1 | t2 | endl; // print tuple 156 164 sout | endl; -
src/tests/preempt_longrun/Makefile.am
r55a68c3 r3d4b23fa 10 10 ## Author : Thierry Delisle 11 11 ## 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 : 14 14 ## Update Count : 0 15 15 ############################################################################### 16 16 17 17 repeats=10 18 max_time= 3019 preempt=1 0_000ul18 max_time=600 19 preempt=1_000ul 20 20 21 21 REPEAT = ${abs_top_srcdir}/tools/repeat -s … … 25 25 CC = @CFA_BINDIR@/@CFA_NAME@ 26 26 27 TESTS = barge block create disjoint processor stack wait yield27 TESTS = barge block create disjoint enter enter3 processor stack wait yield 28 28 29 29 .INTERMEDIATE: ${TESTS} -
src/tests/preempt_longrun/Makefile.in
r55a68c3 r3d4b23fa 449 449 top_srcdir = @top_srcdir@ 450 450 repeats = 10 451 max_time = 30452 preempt = 1 0_000ul451 max_time = 600 452 preempt = 1_000ul 453 453 REPEAT = ${abs_top_srcdir}/tools/repeat -s 454 454 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -debug -O2 -DPREEMPTION_RATE=${preempt} 455 TESTS = barge block create disjoint processor stack wait yield455 TESTS = barge block create disjoint enter enter3 processor stack wait yield 456 456 all: all-am 457 457 … … 467 467 esac; \ 468 468 done; \ 469 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/tests/preempt_longrun/Makefile'; \469 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tests/preempt_longrun/Makefile'; \ 470 470 $(am__cd) $(top_srcdir) && \ 471 $(AUTOMAKE) -- gnusrc/tests/preempt_longrun/Makefile471 $(AUTOMAKE) --foreign src/tests/preempt_longrun/Makefile 472 472 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 473 473 @case '$?' in \ … … 663 663 $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ 664 664 "$$tst" $(AM_TESTS_FD_REDIRECT) 665 enter.log: enter 666 @p='enter'; \ 667 b='enter'; \ 668 $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ 669 --log-file $$b.log --trs-file $$b.trs \ 670 $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ 671 "$$tst" $(AM_TESTS_FD_REDIRECT) 672 enter3.log: enter3 673 @p='enter3'; \ 674 b='enter3'; \ 675 $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ 676 --log-file $$b.log --trs-file $$b.trs \ 677 $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ 678 "$$tst" $(AM_TESTS_FD_REDIRECT) 665 679 processor.log: processor 666 680 @p='processor'; \ -
src/tests/preempt_longrun/create.c
r55a68c3 r3d4b23fa 10 10 } 11 11 12 thread Worker{};12 thread worker_t {}; 13 13 14 void main( Worker* this) {}14 void main(worker_t * this) {} 15 15 16 16 int 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]; 19 20 } 20 21 } -
src/tests/preempt_longrun/processor.c
r55a68c3 r3d4b23fa 10 10 } 11 11 12 thread Worker{};12 thread worker_t {}; 13 13 14 void main( Worker* this) {}14 void main(worker_t * this) {} 15 15 16 16 int main(int argc, char* argv[]) { 17 for(int i = 0; i < 10 0_000ul; i++) {17 for(int i = 0; i < 10_000ul; i++) { 18 18 processor p; 19 19 } -
src/tests/preempt_longrun/stack.c
r55a68c3 r3d4b23fa 12 12 } 13 13 14 thread Worker{};14 thread worker_t {}; 15 15 16 void main( Worker* this) {16 void main(worker_t * this) { 17 17 volatile long p = 5_021_609ul; 18 18 volatile long a = 326_417ul; 19 19 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; 23 23 } 24 24 25 25 if( n != a ) { 26 26 abort(); … … 28 28 } 29 29 30 extern "C" { 31 static worker_t * workers; 32 } 33 30 34 int main(int argc, char* argv[]) { 31 35 processor p; 32 36 { 33 Worker w[7]; 37 worker_t w[7]; 38 workers = w; 34 39 } 35 40 } -
src/tests/preempt_longrun/yield.c
r55a68c3 r3d4b23fa 10 10 } 11 11 12 thread Worker{};12 thread worker_t {}; 13 13 14 void main( Worker* this) {15 for(int i = 0; i < 100_000ul; i++) {14 void main(worker_t * this) { 15 for(int i = 0; i < 325_000ul; i++) { 16 16 yield(); 17 17 } 18 } 19 20 extern "C" { 21 static worker_t * workers; 18 22 } 19 23 … … 21 25 processor p; 22 26 { 23 Worker w[7]; 27 worker_t w[7]; 28 workers = w; 24 29 } 25 30 } -
src/tests/sched-int-block.c
r55a68c3 r3d4b23fa 6 6 7 7 #ifndef N 8 #define N 10 0_0008 #define N 10_000 9 9 #endif 10 10 … … 31 31 //------------------------------------------------------------------------------ 32 32 void 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 ); 34 34 35 35 yield( ((unsigned)rand48()) % 10 ); … … 40 40 } 41 41 42 a->last_thread = b->last_thread = this_thread ();42 a->last_thread = b->last_thread = this_thread; 43 43 44 44 yield( ((unsigned)rand48()) % 10 ); … … 56 56 yield( ((unsigned)rand48()) % 10 ); 57 57 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; 59 59 60 60 if( !is_empty( &cond ) ) { … … 86 86 //------------------------------------------------------------------------------ 87 87 void barge_op( global_data_t * mutex a ) { 88 a->last_thread = this_thread ();88 a->last_thread = this_thread; 89 89 } 90 90 -
src/tests/sched-int-disjoint.c
r55a68c3 r3d4b23fa 5 5 6 6 #ifndef N 7 #define N 10 0_0007 #define N 10_000 8 8 #endif 9 9 … … 42 42 43 43 void main( Barger * this ) { 44 while( !all_done ) { 44 while( !all_done ) { 45 45 barge( &data ); 46 yield(); 46 yield(); 47 47 } 48 48 } … … 53 53 wait( &cond ); 54 54 if( d->state != SIGNAL ) { 55 sout | "ERROR barging!" | endl; 55 sout | "ERROR barging!" | endl; 56 56 } 57 57 … … 85 85 bool running = data.counter < N && data.counter > 0; 86 86 if( data.state != SIGNAL && running ) { 87 sout | "ERROR Eager signal" | data.state | endl; 87 sout | "ERROR Eager signal" | data.state | endl; 88 88 } 89 89 } … … 92 92 93 93 void main( Signaller * this ) { 94 while( !all_done ) { 94 while( !all_done ) { 95 95 logic( &mut ); 96 yield(); 96 yield(); 97 97 } 98 98 } … … 111 111 sout | "All waiter done" | endl; 112 112 all_done = true; 113 } 113 } 114 114 } -
src/tests/sched-int-wait.c
r55a68c3 r3d4b23fa 50 50 unsigned action = (unsigned)rand48() % 4; 51 51 switch( action ) { 52 case 0: 52 case 0: 53 53 signal( &condABC, &globalA, &globalB, &globalC ); 54 54 break; 55 case 1: 55 case 1: 56 56 signal( &condAB , &globalA, &globalB ); 57 57 break; 58 case 2: 58 case 2: 59 59 signal( &condBC , &globalB, &globalC ); 60 60 break; 61 case 3: 61 case 3: 62 62 signal( &condAC , &globalA, &globalC ); 63 63 break; … … 67 67 } 68 68 yield(); 69 } 69 } 70 70 } 71 71 -
src/tests/test.py
r55a68c3 r3d4b23fa 166 166 167 167 # 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) 169 169 170 170 retcode = 0 … … 202 202 error = myfile.read() 203 203 204 204 205 205 # clean the executable 206 206 sh("rm -f %s > /dev/null 2>&1" % test.name, dry_run) -
src/tests/thread.c
r55a68c3 r3d4b23fa 4 4 #include <thread> 5 5 6 // thread First;7 // void main(First* this);6 thread First { semaphore* lock; }; 7 thread Second { semaphore* lock; }; 8 8 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; } 9 void ?{}( First * this, semaphore* lock ) { this->lock = lock; } 10 void ?{}( Second * this, semaphore* lock ) { this->lock = lock; } 17 11 18 12 void main(First* this) { … … 21 15 yield(); 22 16 } 23 signal(this->lock);17 V(this->lock); 24 18 } 25 19 26 20 void main(Second* this) { 27 wait(this->lock);21 P(this->lock); 28 22 for(int i = 0; i < 10; i++) { 29 23 sout | "Second : Suspend No." | i + 1 | endl; … … 34 28 35 29 int main(int argc, char* argv[]) { 36 s ignal_once lock;30 semaphore lock = { 0 }; 37 31 sout | "User main begin" | endl; 38 32 { -
tools/prettyprinter/Makefile.in
r55a68c3 r3d4b23fa 350 350 esac; \ 351 351 done; \ 352 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnutools/prettyprinter/Makefile'; \352 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tools/prettyprinter/Makefile'; \ 353 353 $(am__cd) $(top_srcdir) && \ 354 $(AUTOMAKE) -- gnutools/prettyprinter/Makefile354 $(AUTOMAKE) --foreign tools/prettyprinter/Makefile 355 355 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 356 356 @case '$?' in \
Note:
See TracChangeset
for help on using the changeset viewer.