Changes in / [3d4b23fa:55a68c3]
- Files:
-
- 25 added
- 5 deleted
- 100 edited
-
doc/LaTeXmacros/common.tex (modified) (4 diffs)
-
doc/LaTeXmacros/enumitem/README (added)
-
doc/LaTeXmacros/enumitem/enumitem.pdf (added)
-
doc/LaTeXmacros/enumitem/enumitem.sty (added)
-
doc/LaTeXmacros/enumitem/enumitem.tex (added)
-
doc/LaTeXmacros/listings/README (added)
-
doc/LaTeXmacros/listings/listings-acm.prf (added)
-
doc/LaTeXmacros/listings/listings-bash.prf (added)
-
doc/LaTeXmacros/listings/listings-fortran.prf (added)
-
doc/LaTeXmacros/listings/listings-lua.prf (added)
-
doc/LaTeXmacros/listings/listings-python.prf (added)
-
doc/LaTeXmacros/listings/listings.cfg (added)
-
doc/LaTeXmacros/listings/listings.dtx (added)
-
doc/LaTeXmacros/listings/listings.ins (added)
-
doc/LaTeXmacros/listings/listings.log (added)
-
doc/LaTeXmacros/listings/listings.pdf (added)
-
doc/LaTeXmacros/listings/listings.sty (added)
-
doc/LaTeXmacros/listings/listings.sty.new (added)
-
doc/LaTeXmacros/listings/lstdoc.sty (added)
-
doc/LaTeXmacros/listings/lstdrvrs.dtx (added)
-
doc/LaTeXmacros/listings/lstdrvrs.ins (added)
-
doc/LaTeXmacros/listings/lstdrvrs.pdf (added)
-
doc/LaTeXmacros/listings/lstlang1.sty (added)
-
doc/LaTeXmacros/listings/lstlang2.sty (added)
-
doc/LaTeXmacros/listings/lstlang3.sty (added)
-
doc/LaTeXmacros/listings/lstmisc.sty (added)
-
doc/LaTeXmacros/lstlang.sty (modified) (3 diffs)
-
doc/bibliography/cfa.bib (modified) (4 diffs)
-
doc/proposals/tagged-struct.txt (modified) (2 diffs)
-
doc/user/Makefile (modified) (1 diff)
-
doc/user/user.tex (modified) (37 diffs)
-
src/CodeGen/CodeGenerator.cc (modified) (1 diff)
-
src/CodeGen/CodeGenerator.h (modified) (1 diff)
-
src/CodeGen/FixMain.cc (modified) (1 diff)
-
src/CodeGen/FixNames.cc (modified) (5 diffs)
-
src/CodeGen/FixNames.h (modified) (1 diff)
-
src/CodeGen/GenType.cc (modified) (1 diff)
-
src/CodeGen/GenType.h (modified) (1 diff)
-
src/CodeGen/Generate.cc (modified) (1 diff)
-
src/CodeGen/Generate.h (modified) (1 diff)
-
src/CodeGen/OperatorTable.cc (modified) (1 diff)
-
src/CodeTools/DeclStats.cc (modified) (11 diffs)
-
src/CodeTools/DeclStats.h (modified) (1 diff)
-
src/CodeTools/TrackLoc.cc (modified) (1 diff)
-
src/CodeTools/TrackLoc.h (modified) (1 diff)
-
src/Common/Assert.cc (modified) (1 diff)
-
src/Common/SemanticError.cc (modified) (1 diff)
-
src/Common/SemanticError.h (modified) (1 diff)
-
src/Concurrency/Keywords.cc (modified) (6 diffs)
-
src/Concurrency/Keywords.h (modified) (1 diff)
-
src/ControlStruct/ExceptTranslate.cc (modified) (5 diffs)
-
src/GenPoly/InstantiateGeneric.cc (modified) (1 diff)
-
src/InitTweak/GenInit.cc (modified) (2 diffs)
-
src/MakeLibCfa.cc (modified) (1 diff)
-
src/MakeLibCfa.h (modified) (1 diff)
-
src/Makefile.am (modified) (1 diff)
-
src/Makefile.in (modified) (2 diffs)
-
src/Parser/LinkageSpec.cc (modified) (3 diffs)
-
src/Parser/LinkageSpec.h (modified) (2 diffs)
-
src/Parser/StatementNode.cc (modified) (2 diffs)
-
src/Parser/lex.ll (modified) (3 diffs)
-
src/Parser/parser.yy (modified) (8 diffs)
-
src/ResolvExpr/CurrentObject.cc (modified) (1 diff)
-
src/benchmark/CorCtxSwitch.c (modified) (1 diff)
-
src/benchmark/Makefile.am (modified) (6 diffs)
-
src/benchmark/Makefile.in (modified) (13 diffs)
-
src/benchmark/bench.h (modified) (1 diff)
-
src/benchmark/create_pthrd.c (modified) (1 diff)
-
src/benchmark/csv-data.c (modified) (4 diffs)
-
src/benchmark/interrupt_linux.c (deleted)
-
src/driver/Makefile.in (modified) (1 diff)
-
src/examples/Makefile.in (modified) (1 diff)
-
src/include/assert.h (modified) (1 diff)
-
src/libcfa/Makefile.am (modified) (1 diff)
-
src/libcfa/Makefile.in (modified) (3 diffs)
-
src/libcfa/concurrency/CtxSwitch-i386.S (modified) (1 diff)
-
src/libcfa/concurrency/CtxSwitch-x86_64.S (modified) (3 diffs)
-
src/libcfa/concurrency/alarm.c (modified) (7 diffs)
-
src/libcfa/concurrency/coroutine (modified) (4 diffs)
-
src/libcfa/concurrency/coroutine.c (modified) (5 diffs)
-
src/libcfa/concurrency/invoke.c (modified) (5 diffs)
-
src/libcfa/concurrency/invoke.h (modified) (4 diffs)
-
src/libcfa/concurrency/kernel (modified) (4 diffs)
-
src/libcfa/concurrency/kernel.c (modified) (40 diffs)
-
src/libcfa/concurrency/kernel_private.h (modified) (3 diffs)
-
src/libcfa/concurrency/monitor (modified) (1 diff)
-
src/libcfa/concurrency/monitor.c (modified) (23 diffs)
-
src/libcfa/concurrency/preemption.c (modified) (8 diffs)
-
src/libcfa/concurrency/thread (modified) (1 diff)
-
src/libcfa/concurrency/thread.c (modified) (4 diffs)
-
src/libcfa/exception.c (modified) (5 diffs)
-
src/libcfa/exception.h (modified) (2 diffs)
-
src/libcfa/fstream (modified) (3 diffs)
-
src/libcfa/fstream.c (modified) (6 diffs)
-
src/libcfa/gmp (modified) (1 diff)
-
src/libcfa/iostream (modified) (4 diffs)
-
src/libcfa/iostream.c (modified) (6 diffs)
-
src/libcfa/iterator (modified) (2 diffs)
-
src/libcfa/iterator.c (modified) (2 diffs)
-
src/libcfa/libhdr/libalign.h (modified) (3 diffs)
-
src/libcfa/libhdr/libdebug.h (modified) (2 diffs)
-
src/libcfa/limits (modified) (2 diffs)
-
src/libcfa/math (modified) (2 diffs)
-
src/libcfa/rational (modified) (3 diffs)
-
src/libcfa/rational.c (modified) (18 diffs)
-
src/libcfa/stdlib (modified) (2 diffs)
-
src/main.cc (modified) (2 diffs)
-
src/prelude/Makefile.in (modified) (1 diff)
-
src/tests/.expect/32/math.txt (modified) (1 diff)
-
src/tests/.expect/concurrent/preempt.txt (deleted)
-
src/tests/.expect/concurrent/sched-int-disjoint.txt (modified) (1 diff)
-
src/tests/.expect/io.txt (modified) (4 diffs)
-
src/tests/Makefile.am (modified) (1 diff)
-
src/tests/Makefile.in (modified) (3 diffs)
-
src/tests/io.c (modified) (6 diffs)
-
src/tests/preempt.c (deleted)
-
src/tests/preempt_longrun/Makefile.am (modified) (2 diffs)
-
src/tests/preempt_longrun/Makefile.in (modified) (3 diffs)
-
src/tests/preempt_longrun/create.c (modified) (1 diff)
-
src/tests/preempt_longrun/enter.c (deleted)
-
src/tests/preempt_longrun/enter3.c (deleted)
-
src/tests/preempt_longrun/processor.c (modified) (1 diff)
-
src/tests/preempt_longrun/stack.c (modified) (2 diffs)
-
src/tests/preempt_longrun/yield.c (modified) (2 diffs)
-
src/tests/sched-int-block.c (modified) (5 diffs)
-
src/tests/sched-int-disjoint.c (modified) (6 diffs)
-
src/tests/sched-int-wait.c (modified) (2 diffs)
-
src/tests/test.py (modified) (2 diffs)
-
src/tests/thread.c (modified) (3 diffs)
-
tools/prettyprinter/Makefile.in (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.tex
r3d4b23fa r55a68c3 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Thu Jul 13 11:44:59201714 %% Update Count : 3 3513 %% Last Modified On : Sun Jun 18 20:32:32 2017 14 %% Update Count : 319 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 36 36 % Names used in the document. 37 37 38 \newcommand{\CFAIcon}{\text sf{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}\xspace} % Cforall symbolic name38 \newcommand{\CFAIcon}{\textrm{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 60 57 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly 61 58 \newlength{\columnposn} 62 59 \setlength{\gcolumnposn}{2.5in} 63 60 \setlength{\columnposn}{\gcolumnposn} 64 \newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\lst@ basicstyle{\LstCommentStyle{#2}}}}61 \newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\lst@commentstyle{#2}}} 65 62 \newcommand{\CRT}{\global\columnposn=\gcolumnposn} 66 63 … … 234 231 basicstyle=\linespread{0.9}\sf, % reduce line spacing and use sanserif font 235 232 stringstyle=\tt, % use typewriter font 236 tabsize= 6, % Nspace tabbing233 tabsize=4, % 4 space tabbing 237 234 xleftmargin=\parindentlnth, % indent code to paragraph indentation 238 235 extendedchars=true, % allow ASCII characters in the range 128-255 -
doc/LaTeXmacros/lstlang.sty
r3d4b23fa r55a68c3 8 8 %% Created On : Sat May 13 16:34:42 2017 9 9 %% Last Modified By : Peter A. Buhr 10 %% Last Modified On : Wed Jul 12 22:42:09201711 %% Update Count : 1 210 %% Last Modified On : Thu Jun 22 07:40:31 2017 11 %% Update Count : 10 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__, with,zero_t},114 __typeof__, 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 language122 \lstdefinelanguage{C++}[ANSI]{C++}{}123 120 124 121 % uC++ programming language, based on ANSI C++ -
doc/bibliography/cfa.bib
r3d4b23fa r55a68c3 2273 2273 @manual{JavaScript, 2274 2274 keywords = {JavaScript}, 2275 contributer = {pabuhr @plg},2275 contributer = {pabuhr}, 2276 2276 title = {ECMAScript 2015 Language Specification {JavaScript}}, 2277 2277 organization= {ECAM International}, … … 2446 2446 @manual{Erlang, 2447 2447 keywords = {Erlang}, 2448 contributer = {pabuhr @plg},2448 contributer = {pabuhr}, 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},2786 2773 } 2787 2774 … … 5065 5052 contributer = {pabuhr@plg}, 5066 5053 author = {Kathleen Jensen and Niklaus Wirth}, 5067 title = {{P}ascal User Manual and Report , ISO Pascal Standard},5054 title = {{P}ascal User Manual and Report}, 5068 5055 publisher = {Springer--Verlag}, 5069 year = 19 91,5070 edition = { 4th},5071 note = {Revised by Andrew B. Mickel and James F. Miner }5056 year = 1985, 5057 edition = {3rd}, 5058 note = {Revised by Andrew B. Mickel and James F. Miner, ISO Pascal Standard} 5072 5059 } 5073 5060 -
doc/proposals/tagged-struct.txt
r3d4b23fa r55a68c3 71 71 should be possible to do during linking. 72 72 73 If a generic/polymorphic type is tagged its tagged would then be shared74 between all applications of that generic. Internal tags could be used to75 seperate these structures again, however it seems in most cases simply using76 the existing type parameters should provide the needed information.77 78 73 79 74 Traits: … … 107 102 To allow for growth each option would have to be a structure itself. 108 103 109 Which brings us to "tagge dstruct union", ie. a union of tagged structures104 Which brings us to "tagget struct union", ie. a union of tagged structures 110 105 as opposed to tagging the union itself. This extention acts as a constraint. 111 106 If unions are declared tagged instead of creating a new tagged type, all 112 possible values of the union must be of that tagged type or a child type. If 113 the tagged type is omitted then they must all be tagged but of any tagged 114 type. 115 116 As a short cut union_instance->type might get the type object of the loaded 117 value. It should always be the same operation regardless so it saves 118 abritarly picking a branch of the union to get the type object. 107 possible values of the union must be of that tagged type or a child type. 119 108 120 109 121 Type Objects Fields (Extention):110 Custom Type Objects (Extention): 122 111 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. 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. 127 115 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. 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.) 131 118 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); 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. -
doc/user/Makefile
r3d4b23fa r55a68c3 1 1 ## Define the appropriate configuration variables. 2 2 3 TeXLIB = .:../LaTeXmacros:../ bibliography/:3 TeXLIB = .:../LaTeXmacros:../LaTeXmacros/listings:../LaTeXmacros/enumitem:../bibliography/: 4 4 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error 5 5 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex -
doc/user/user.tex
r3d4b23fa r55a68c3 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Thu Jul 13 11:44:57201714 %% Update Count : 2 69013 %% Last Modified On : Sun Jul 2 09:49:56 2017 14 %% Update Count : 2503 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 63 59 % inline code ©...© (copyright symbol) emacs: C-q M-) 64 60 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. … … 141 137 142 138 \CFA{}\index{cforall@\CFA}\footnote{Pronounced ``\Index*{C-for-all}'', and written \CFA, CFA, or \CFL.} is a modern general-purpose programming-language, designed as an evolutionary step forward for the C programming language. 143 The syntax of \CFA builds from Cand should look immediately familiar to C/\Index*[C++]{\CC{}} programmers.139 The syntax of the \CFA language builds from C, and should look immediately familiar to C/\Index*[C++]{\CC{}} programmers. 144 140 % Any language feature that is not described here can be assumed to be using the standard \Celeven syntax. 145 \CFA adds many modern programming-language features that directly lead to increased \emph{\Index{safety}} and \emph{\Index{productivity}}, while maintaining interoperability with existing C programs and achieving similarperformance.146 Like C, \CFA is a statically typed, procedural (non-\Index{object-oriented})language with a low-overhead runtime, meaning there is no global \Index{garbage-collection}, but \Index{regional garbage-collection}\index{garbage-collection!regional} is possible.141 \CFA adds many modern programming-language features that directly lead to increased \emph{\Index{safety}} and \emph{\Index{productivity}}, while maintaining interoperability with existing C programs and achieving C performance. 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. 147 143 The primary new features include parametric-polymorphic routines and types, exceptions, concurrency, and modules. 148 144 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. 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. 158 152 In contrast, \CFA has 30 years of hindsight and a clean starting point. 159 153 … … 162 156 \begin{quote2} 163 157 \begin{tabular}{@{}l@{\hspace{1.5em}}l@{\hspace{1.5em}}l@{}} 164 \multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{\CC}} \\ 165 \begin{cfa} 158 \multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CC}} \\ 159 \begin{cfa} 160 #include <fstream>§\indexc{fstream}§ 161 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} 166 169 #include <stdio.h>§\indexc{stdio.h}§ 167 170 … … 170 173 ®printf( "%d %d %d\n", x, y, z );® 171 174 } 172 \end{ cfa}175 \end{lstlisting} 173 176 & 174 \begin{cfa} 175 #include <fstream>§\indexc{fstream}§ 176 177 int main( void ) { 178 int x = 0, y = 1, z = 2; 179 ®sout | x | y | z | endl;®§\indexc{sout}§ 180 } 181 \end{cfa} 182 & 183 \begin{cfa} 177 \begin{lstlisting} 184 178 #include <iostream>§\indexc{iostream}§ 185 179 using namespace std; … … 188 182 ®cout<<x<<" "<<y<<" "<<z<<endl;® 189 183 } 190 \end{ cfa}184 \end{lstlisting} 191 185 \end{tabular} 192 186 \end{quote2} 193 187 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}). 194 188 195 \subsection{Background}196 197 189 This document is a programmer reference-manual for the \CFA programming language. 198 190 The manual covers the core features of the language and runtime-system, with simple examples illustrating syntax and semantics of each feature. 199 191 The manual does not teach programming, i.e., how to combine the new constructs to build complex programs. 200 A reader should already have an intermediate knowledge of control flow, data structures, and concurrency issues to understand the ideas presented ,as well as some experience programming in C/\CC.201 Implementers shouldrefer to the \CFA Programming Language Specification for details about the language syntax and semantics.192 A reader should already have an intermediate knowledge of control flow, data structures, and concurrency issues to understand the ideas presented as well as some experience programming in C/\CC. 193 Implementers may refer to the \CFA Programming Language Specification for details about the language syntax and semantics. 202 194 Changes to the syntax and additional features are expected to be included in later revisions. 203 195 … … 208 200 This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more. 209 201 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. 210 For system programming, where direct access to hardware , storage management, and real-time issues are a requirement, C is usually the onlylanguage of choice.202 For system programming, where direct access to hardware and dealing with real-time issues is a requirement, C is usually the language of choice. 211 203 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. 212 204 As well, for 30 years, C has been the number 1 and 2 most popular programming language: … … 224 216 \end{center} 225 217 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. 226 Love it or hate it, C has been an important and influential part of computer science for 40 years and itsappeal 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.218 Love it or hate it, C has been an important and influential part of computer science for 40 years and sit appeal is not diminishing. 219 Unfortunately, C has too many problems and omissions to make it an acceptable programming language for modern needs. 220 221 As stated, the goal of the \CFA project is to engineer modern language features into C in an evolutionary rather than revolutionary way. 230 222 \CC~\cite{C++14,C++} is an example of a similar project; 231 however, it largely extended the C language, and did not address most of C'sexisting problems.\footnote{%223 however, it largely extended the language, and did not address many existing problems.\footnote{% 232 224 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.} 233 \Index*{Fortran}~\cite{Fortran08}, \Index*{Ada}~\cite{Ada12}, and \Index*{Cobol}~\cite{Cobol14} are examples of programming languages that took an evolutionary approach, where modern language -features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language.225 \Index*{Fortran}~\cite{Fortran08}, \Index*{Ada}~\cite{Ada12}, and \Index*{Cobol}~\cite{Cobol14} are examples of programming languages that took an evolutionary approach, where modern language features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language. 234 226 \Index*{Java}~\cite{Java8}, \Index*{Go}~\cite{Go}, \Index*{Rust}~\cite{Rust} and \Index*{D}~\cite{D} are examples of the revolutionary approach for modernizing C/\CC, resulting in a new language rather than an extension of the descendent. 235 These languages have different syntax and semantics from C, do not interoperate directly with C, and are not systems languages because of restrictive memory-management orgarbage collection.227 These languages have different syntax and semantics from C, and do not interoperate directly with C, largely because of garbage collection. 236 228 As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten. 237 These costs can be prohibitive for many companies with a large software -base in C/\CC, and a significant number of programmers require retraining to thenew programming language.238 239 The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fix es many of the well known C problems while containing modern language-features.229 These costs can be prohibitive for many companies with a large software base in C/\CC, and a significant number of programmers requiring retraining to a new programming language. 230 231 The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fixing some of the well known C problems and containing many modern language features. 240 232 Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers; 241 233 as a result, it will fade into disuse. 242 234 Considering the large body of existing C code and programmers, there is significant impetus to ensure C is transformed into a modern programming language. 243 While \Index*[C11]{\Celeven{}} made a few simple extensions to the language, nothing was added to address existing problems in the language or to augment the language with modern language -features.244 While some may argue that modern language -features may make C complex and inefficient, it is clear a language without modern capabilities is insufficient for the advanced programming problems existing today.235 While \Index*[C11]{\Celeven{}} made a few simple extensions to the language, nothing was added to address existing problems in the language or to augment the language with modern language features. 236 While some may argue that modern language features may make C complex and inefficient, it is clear a language without modern capabilities is insufficient for the advanced programming problems existing today. 245 237 246 238 247 239 \section{History} 248 240 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.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. 250 242 (See~\cite{Werther96} for similar work in \Index*[C++]{\CC{}}.) 251 The first \CFA implementation of these extensions was by Esteves~\cite{Esteves04}. 252 253 The signature feature of \CFA is \Index{overload}able \Index{parametric-polymorphic} functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a ©forall© clause (giving the language its name): 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): 254 245 \begin{lstlisting} 255 246 ®forall( otype T )® T identity( T val ) { return val; } … … 259 250 \CFA{}\hspace{1pt}'s polymorphism was originally formalized by Ditchfiled~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}. 260 251 However, at that time, there was little interesting in extending C, so work did not continue. 261 As the saying goes, `` \Index*{What goes around, comes around.}'', and there is now renewed interest in the C programming language because of legacy code-bases, so the \CFA project has been restarted.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. 262 253 263 254 … … 266 257 267 258 \CFA is designed to integrate directly with existing C programs and libraries. 268 The most important feature of \Index{interoperability} is using the same \Index{calling convention}s, so there is no complex interface oroverhead to call existing C routines.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. 269 260 This feature allows \CFA programmers to take advantage of the existing panoply of C libraries to access thousands of external software features. 270 261 Language developers often state that adequate \Index{library support} takes more work than designing and implementing the language itself. 271 262 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. 272 Hence, \CFA begins by leveraging the large repository of C libraries atlittle cost.263 Hence, \CFA begins by leveraging the large repository of C libraries with little cost. 273 264 274 265 \begin{comment} … … 313 304 \end{comment} 314 305 315 However, it is necessary to differentiate between C and \CFA code because of name \Index{overload}ing, as for \CC.306 However, it is necessary to differentiate between C and \CFA code because of name overloading, as for \CC. 316 307 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©. 317 Whereas, \CFA wraps each of these routines into ones with the overloadedname ©abs©:308 Whereas, \CFA wraps each of these routines into ones with the common name ©abs©: 318 309 \begin{cfa} 319 310 char abs( char ); … … 335 326 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. 336 327 There is no way around this problem, other than C's approach of creating unique names for each pairing of operation and type. 337 This example strongly illustrates a core idea in \CFA: \emph{the \Index{power of a name}}.328 This example strongly illustrates a core idea in \CFA: \emph{the power of a name}. 338 329 The name ``©abs©'' evokes the notion of absolute value, and many mathematical types provide the notion of absolute value. 339 Hence, knowing the name ©abs© issufficient 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}330 Hence, knowing the name ©abs© should be sufficient to apply it to any type where it is applicable. 331 The time savings and safety of using one name uniformly versus $N$ unique names should not be underestimated. 332 333 334 \section[Compiling CFA Program]{Compiling \CFA Program} 344 335 345 336 The command ©cfa© is used to compile \CFA program(s), and is based on the GNU \Indexc{gcc} command, \eg: 346 337 \begin{cfa} 347 cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA {}§-files [ assembler/loader-files ]338 cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA§-files [ assembler/loader-files ] 348 339 \end{cfa} 349 340 \CFA programs having the following ©gcc© flags turned on: … … 368 359 \Indexc{-debug}\index{compilation option!-debug@©-debug©} 369 360 The program is linked with the debugging version of the runtime system. 370 The debug version performs runtime checks to help during the debugging phase of a \CFA program, but can substantially slow program execution.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. 371 362 The runtime checks should only be removed after the program is completely debugged. 372 363 \textbf{This option is the default.} … … 424 415 \end{description} 425 416 These preprocessor variables allow conditional compilation of programs that must work differently in these situations. 426 For example, to toggle between C and \CFA extensions, us ethe following:417 For example, to toggle between C and \CFA extensions, using the following: 427 418 \begin{cfa} 428 419 #ifndef __CFORALL__ … … 435 426 436 427 437 \section{Constant Underscores}438 439 Numeric constants are extended to allow \Index{underscore}s \index{constant!underscore}, \eg:428 \section{Constants Underscores} 429 430 Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, \eg: 440 431 \begin{cfa} 441 432 2®_®147®_®483®_®648; §\C{// decimal constant}§ … … 450 441 L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§; §\C{// wide character constant}§ 451 442 \end{cfa} 452 The rules for placement of underscores are:453 \begin{enumerate} [topsep=5pt,itemsep=5pt,parsep=0pt]443 The rules for placement of underscores is as follows: 444 \begin{enumerate} 454 445 \item 455 446 A sequence of underscores is disallowed, \eg ©12__34© is invalid. … … 472 463 \label{s:BackquoteIdentifiers} 473 464 474 \CFA introduces in new keywords (see \VRef{s:CFAKeywords}) that can clash with existing C variable-names in legacy code. 475 Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism: 465 \CFA accommodates keyword clashes with existing C variable-names by syntactic transformations using the \CFA backquote escape-mechanism: 476 466 \begin{cfa} 477 467 int ®`®otype®`® = 3; §\C{// make keyword an identifier}§ … … 501 491 502 492 503 \section{ \texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break}}{Labelled continue / break}}493 \section{Labelled Continue/Break} 504 494 505 495 While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure. 506 496 Unfortunately, this restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting. 507 To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@\lstinline $continue$!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@\lstinline $break$!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85 }.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}. 508 498 For both ©continue© and ©break©, the target label must be directly associated with a ©for©, ©while© or ©do© statement; 509 499 for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement. 510 500 \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©. 511 501 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.513 502 514 503 \begin{figure} … … 633 622 634 623 635 \section{ \texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}}624 \section{Switch Statement} 636 625 637 626 C allows a number of questionable forms for the ©switch© statement: … … 674 663 ®// open input file 675 664 ®} else if ( argc == 2 ) { 676 ®// open input file (duplicate)665 ®// open input file 677 666 678 667 ®} else { … … 687 676 \begin{cfa} 688 677 switch ( i ) { 689 ®case 1: case 3: case 5:®// odd values690 // oddaction678 case 1: case 3: case 5: // odd values 679 // same action 691 680 break; 692 ®case 2: case 4: case 6:®// even values693 // evenaction681 case 2: case 4: case 6: // even values 682 // same action 694 683 break; 695 684 } … … 697 686 However, this situation is handled in other languages without fall-through by allowing a list of case values. 698 687 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. 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.688 Hence, default fall-through semantics results in a large number of programming errors as programmers often forget the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through. 700 689 701 690 \item … … 781 770 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. 782 771 \end{itemize} 783 These observations put into perspective the \CFA changes to the ©switch©.772 These observations help to put the \CFA changes to the ©switch© into perspective. 784 773 \begin{enumerate} 785 774 \item … … 802 791 case 7: 803 792 ... 804 ®break® §\C{// redundantexplicit end of switch}§793 ®break® §\C{// explicit end of switch}§ 805 794 default: 806 795 j = 3; … … 808 797 \end{cfa} 809 798 Like the ©switch© statement, the ©choose© statement retains the fall-through semantics for a list of ©case© clauses; 810 Animplicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause.811 Anexplicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement.799 the implicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause. 800 The explicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement. 812 801 As well, allowing an explicit ©break© from the ©choose© is a carry over from the ©switch© statement, and expected by C programmers. 813 802 \item … … 838 827 839 828 840 \section{ \texorpdfstring{\LstKeywordStyle{case} Clause}{case Clause}}829 \section{Case Clause} 841 830 842 831 C restricts the ©case© clause of a ©switch© statement to a single value. … … 911 900 \begin{cfa} 912 901 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" parameter924 i = 1; ®// this->i925 ® j = 3; ®// this->j926 ® }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" parameter935 ®this.®i = 1; // "this" is not elided936 ®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.i944 ® j = 2; ®// this.j945 ®}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 qualification966 ®with s2® { // nesting967 // access fields of s2 without qualification968 }969 }970 ®with s1, s2® {971 // access unambiguous fields of s1 and s2 without qualification972 }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 }988 902 \end{cfa} 989 903 … … 1222 1136 1223 1137 1224 \section{Pointer /Reference}1138 \section{Pointer/Reference} 1225 1139 1226 1140 C provides a \newterm{pointer type}; … … 2536 2450 \end{cfa} 2537 2451 \\ 2538 \begin{cfa}[ showspaces=true,aboveskip=0pt,belowskip=0pt]2452 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 2539 2453 1® ®2® ®3 2540 2454 \end{cfa} 2541 2455 & 2542 \begin{cfa}[ showspaces=true,aboveskip=0pt,belowskip=0pt]2456 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 2543 2457 1 2 3 2544 2458 \end{cfa} … … 2547 2461 The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators. 2548 2462 Similar simplification occurs for \Index{tuple} I/O, which prints all tuple values separated by ``\lstinline[showspaces=true]@, @''. 2549 \begin{cfa} 2550 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6] ];2463 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt] 2464 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ]; 2551 2465 sout | t1 | t2 | endl; §\C{// print tuples}§ 2552 2466 \end{cfa} 2553 \begin{cfa}[ showspaces=true,aboveskip=0pt]2554 1®, ®2®, ®3 4®, ®5®, ®62467 \begin{cfa}[mathescape=off,showspaces=true,belowskip=0pt] 2468 1®, ®2®, ®3 3®, ®4®, ®5 2555 2469 \end{cfa} 2556 2470 Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority overloadable operator, other than assignment. … … 2571 2485 \\ 2572 2486 & 2573 \begin{cfa}[ showspaces=true,aboveskip=0pt]2487 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 2574 2488 3 3 12 0 3 1 2 2575 2489 \end{cfa} … … 2589 2503 sout | 1 | 2 | 3 | endl; 2590 2504 \end{cfa} 2591 \begin{cfa}[ showspaces=true,aboveskip=0pt,belowskip=0pt]2505 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 2592 2506 1 2 3 2593 2507 \end{cfa} … … 2656 2570 \subsection{Manipulator} 2657 2571 2658 The following \CC-style \Index{manipulator}s and routines control implicit seperation.2572 The following routines and \CC-style \Index{manipulator}s control implicit seperation. 2659 2573 \begin{enumerate} 2660 2574 \item 2661 Routines \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep }\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string.2575 Routines \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string. 2662 2576 The separator string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters). 2663 \begin{cfa}[mathescape=off, belowskip=0pt]2577 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt] 2664 2578 sepSet( sout, ", $" ); §\C{// set separator from " " to ", \$"}§ 2665 sout | 1 | 2 | 3 | " \"" | ®sep ® | "\"" | endl;2579 sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\"" | endl; 2666 2580 \end{cfa} 2667 2581 %$ … … 2670 2584 \end{cfa} 2671 2585 %$ 2672 \begin{cfa}[ belowskip=0pt]2586 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt] 2673 2587 sepSet( sout, " " ); §\C{// reset separator to " "}§ 2674 2588 sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\"" | endl; 2675 2589 \end{cfa} 2676 \begin{cfa}[ showspaces=true,aboveskip=0pt]2590 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt] 2677 2591 1® ®2® ®3 ®" "® 2678 2592 \end{cfa} 2679 ©sepGet© can be used to store a separator and then restore it: 2680 \begin{cfa}[belowskip=0pt] 2681 char store[®sepSize®]; §\C{// sepSize is the maximum separator size}§ 2682 strcpy( store, sepGet( sout ) ); 2683 sepSet( sout, "_" ); 2684 sout | 1 | 2 | 3 | endl; 2685 \end{cfa} 2686 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2687 1®_®2®_®3 2688 \end{cfa} 2689 \begin{cfa}[belowskip=0pt] 2690 sepSet( sout, store ); 2691 sout | 1 | 2 | 3 | endl; 2692 \end{cfa} 2693 \begin{cfa}[showspaces=true,aboveskip=0pt] 2694 1® ®2® ®3 2695 \end{cfa} 2696 2697 \item 2698 Routine \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepTuple}\index{manipulator!sepTuple@©sepTuple©}/\Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string. 2593 2594 \item 2595 Routine \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string. 2699 2596 The tuple separator-string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters). 2700 \begin{cfa}[ belowskip=0pt]2597 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt] 2701 2598 sepSetTuple( sout, " " ); §\C{// set tuple separator from ", " to " "}§ 2702 sout | t1 | t2 | " \"" | ®sep Tuple® | "\"" | 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]2599 sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\"" | endl; 2600 \end{cfa} 2601 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt] 2602 1 2 3 4 ®" "® 2603 \end{cfa} 2604 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt] 2708 2605 sepSetTuple( sout, ", " ); §\C{// reset tuple separator to ", "}§ 2709 2606 sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\"" | endl; 2710 2607 \end{cfa} 2711 \begin{cfa}[showspaces=true,aboveskip=0pt] 2712 1, 2, 3 4, 5, 6 ®", "® 2713 \end{cfa} 2714 As for ©sepGet©, ©sepGetTuple© can be use to store a tuple separator and then restore it. 2715 2716 \item 2717 Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items. 2718 \begin{cfa}[belowskip=0pt] 2719 sout | sepDisable | 1 | 2 | 3 | endl; §\C{// globally turn off implicit separator}§ 2720 \end{cfa} 2721 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 2608 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt] 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] 2722 2641 123 2723 2642 \end{cfa} 2724 \begin{cfa}[belowskip=0pt] 2725 sout | sepEnable | 1 | 2 | 3 | endl; §\C{// globally turn on implicit separator}§ 2643 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt] 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}§ 2726 2651 \end{cfa} 2727 2652 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 2728 2653 1 2 3 2729 2654 \end{cfa} 2730 2731 \item2732 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 32738 \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 232744 \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, 62751 \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 32759 \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}2766 2655 \end{enumerate} 2767 2656 2768 2657 \begin{comment} 2769 2658 #include <fstream> 2770 #include <string.h> // strcpy2771 2659 2772 2660 int main( void ) { 2773 2661 int x = 1, y = 2, z = 3; 2774 2662 sout | x | y | z | endl; 2775 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6] ];2663 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ]; 2776 2664 sout | t1 | t2 | endl; // print tuples 2777 2665 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl; … … 2787 2675 2788 2676 sepSet( sout, ", $" ); // set separator from " " to ", $" 2789 sout | 1 | 2 | 3 | " \"" | sep | "\"" | endl;2677 sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl; 2790 2678 sepSet( sout, " " ); // reset separator to " " 2791 2679 sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl; 2792 2680 2793 char store[sepSize];2794 s trcpy( store, sepGet( sout ) );2795 sepSet( sout, "_" ); 2796 sout | 1 | 2 | 3 | endl;2797 s epSet( sout, store );2798 sout | 1 | 2 | 3 | endl;2681 sout | sepOn | 1 | 2 | 3 | sepOn | endl; // separator at start of line 2682 sout | 1 | sepOff | 2 | 3 | endl; // locally turn off implicit separator 2683 2684 sout | sepDisable | 1 | 2 | 3 | endl; // globally turn off implicit separation 2685 sout | 1 | sepOn | 2 | 3 | endl; // locally turn on implicit separator 2686 sout | sepEnable | 1 | 2 | 3 | endl; // globally turn on implicit separation 2799 2687 2800 2688 sepSetTuple( sout, " " ); // set tuple separator from ", " to " " 2801 sout | t1 | t2 | " \"" | sep Tuple| "\"" | endl;2689 sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl; 2802 2690 sepSetTuple( sout, ", " ); // reset tuple separator to ", " 2803 2691 sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl; 2804 2692 2805 sout | sepDisable | 1 | 2 | 3 | endl; // globally turn off implicit separator 2806 sout | sepEnable | 1 | 2 | 3 | endl; // globally turn on implicit separator 2807 2808 sout | 1 | sepOff | 2 | 3 | endl; // locally turn on implicit separator 2809 sout | sepDisable | 1 | sepOn | 2 | 3 | endl; // globally turn off implicit separator 2810 sout | sepEnable; 2811 sout | t1 | sepOff | t2 | endl; // locally turn on/off implicit separator 2812 2813 sout | sepOn | 1 | 2 | 3 | sepOn | endl ; // sepOn does nothing at start/end of line 2814 sout | sep | 1 | 2 | 3 | sep | endl ; // use sep to print separator at start/end of line 2693 sout | t1 | t2 | endl; // print tuple 2694 sout | sepOn | t1 | sepOff | t2 | endl; // locally turn on/off implicit separation 2815 2695 } 2816 2696 … … 5344 5224 5345 5225 5346 \section{\ texorpdfstring{\CFA Keywords}{Cforall Keywords}}5226 \section{\CFA Keywords} 5347 5227 \label{s:CFAKeywords} 5348 5228 5349 \CFA introduces the following new keywords.5350 5351 5229 \begin{quote2} 5352 \begin{tabular}{llll l}5230 \begin{tabular}{llll} 5353 5231 \begin{tabular}{@{}l@{}} 5354 ©_A t© \\5232 ©_AT© \\ 5355 5233 ©catch© \\ 5356 5234 ©catchResume© \\ 5357 5235 ©choose© \\ 5358 5236 ©coroutine© \\ 5237 ©disable© \\ 5359 5238 \end{tabular} 5360 5239 & 5361 5240 \begin{tabular}{@{}l@{}} 5362 ©disable© \\5363 5241 ©dtype© \\ 5364 5242 ©enable© \\ 5365 5243 ©fallthrough© \\ 5366 5244 ©fallthru© \\ 5245 ©finally© \\ 5246 ©forall© \\ 5367 5247 \end{tabular} 5368 5248 & 5369 5249 \begin{tabular}{@{}l@{}} 5370 ©finally© \\5371 ©forall© \\5372 5250 ©ftype© \\ 5373 5251 ©lvalue© \\ 5374 5252 ©monitor© \\ 5253 ©mutex© \\ 5254 ©one_t© \\ 5255 ©otype© \\ 5375 5256 \end{tabular} 5376 5257 & 5377 5258 \begin{tabular}{@{}l@{}} 5378 ©mutex© \\5379 ©one_t© \\5380 ©otype© \\5381 5259 ©throw© \\ 5382 5260 ©throwResume© \\ 5383 \end{tabular}5384 &5385 \begin{tabular}{@{}l@{}}5386 5261 ©trait© \\ 5387 5262 ©try© \\ 5388 5263 ©ttype© \\ 5389 5264 ©zero_t© \\ 5390 \\5391 5265 \end{tabular} 5392 5266 \end{tabular} … … 5674 5548 // C unsafe allocation 5675 5549 extern "C" { 5676 void * mall oc( size_t size );§\indexc{memset}§5550 void * mallac( size_t size );§\indexc{memset}§ 5677 5551 void * calloc( size_t dim, size_t size );§\indexc{calloc}§ 5678 5552 void * realloc( void * ptr, size_t size );§\indexc{realloc}§ -
src/CodeGen/CodeGenerator.cc
r3d4b23fa r55a68c3 14 14 // 15 15 16 #include <cassert> // for assert, assertf 17 #include <list> // for _List_iterator, list, list<>::it... 16 #include <algorithm> 17 #include <iostream> 18 #include <cassert> 19 #include <list> 20 21 #include "Parser/ParseNode.h" 22 23 #include "SynTree/Declaration.h" 24 #include "SynTree/Expression.h" 25 #include "SynTree/Initializer.h" 26 #include "SynTree/Statement.h" 27 #include "SynTree/Type.h" 28 #include "SynTree/Attribute.h" 29 30 #include "Common/utility.h" 31 #include "Common/UnimplementedError.h" 18 32 19 33 #include "CodeGenerator.h" 20 #include "Common/SemanticError.h" // for SemanticError 21 #include "Common/UniqueName.h" // for UniqueName 22 #include "Common/utility.h" // for CodeLocation, toString 23 #include "GenType.h" // for genType 24 #include "InitTweak/InitTweak.h" // for getPointerBase 25 #include "OperatorTable.h" // for OperatorInfo, operatorLookup 26 #include "Parser/LinkageSpec.h" // for Spec, Intrinsic 27 #include "SynTree/Attribute.h" // for Attribute 28 #include "SynTree/BaseSyntaxNode.h" // for BaseSyntaxNode 29 #include "SynTree/Constant.h" // for Constant 30 #include "SynTree/Declaration.h" // for DeclarationWithType, TypeDecl 31 #include "SynTree/Expression.h" // for Expression, UntypedExpr, Applica... 32 #include "SynTree/Initializer.h" // for Initializer, ListInit, Designation 33 #include "SynTree/Label.h" // for Label, operator<< 34 #include "SynTree/Statement.h" // for Statement, AsmStmt, BranchStmt 35 #include "SynTree/Type.h" // for Type, Type::StorageClasses, Func... 34 #include "OperatorTable.h" 35 #include "GenType.h" 36 37 #include "InitTweak/InitTweak.h" 36 38 37 39 using namespace std; -
src/CodeGen/CodeGenerator.h
r3d4b23fa r55a68c3 17 17 #define CODEGENV_H 18 18 19 #include <list> // for list 20 #include <ostream> // for ostream, operator<< 21 #include <string> // for string 19 #include <list> 22 20 23 #include "SynTree/Declaration.h" // for DeclarationWithType (ptr only), Fun... 24 #include "SynTree/Visitor.h" // for Visitor 25 #include "SynTree/SynTree.h" // for Visitor Nodes 21 #include "SynTree/Declaration.h" 22 #include "SynTree/SynTree.h" 23 #include "SynTree/Visitor.h" 24 25 #include "SymTab/Indexer.h" 26 27 #include "Common/Indenter.h" 28 #include "Common/utility.h" 26 29 27 30 namespace CodeGen { -
src/CodeGen/FixMain.cc
r3d4b23fa r55a68c3 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 <cassert> // for assert, assertf 20 #include <fstream> // for operator<<, basic_ostream::operator<< 21 #include <list> // for list 22 #include <string> // for operator<< 19 #include <fstream> 20 #include <iostream> 23 21 24 #include "Common/SemanticError.h" // for SemanticError 25 #include "SynTree/Declaration.h" // for FunctionDecl, operator<< 26 #include "SynTree/Type.h" // for FunctionType 22 #include "Common/SemanticError.h" 23 #include "SynTree/Declaration.h" 27 24 28 25 namespace CodeGen { 29 26 bool FixMain::replace_main = false; 30 27 std::unique_ptr<FunctionDecl> FixMain::main_signature = nullptr; 31 32 void FixMain::registerMain(FunctionDecl* functionDecl) 28 29 void FixMain::registerMain(FunctionDecl* functionDecl) 33 30 { 34 if(main_signature) { 35 throw SemanticError("Multiple definition of main routine\n", functionDecl); 31 if(main_signature) { 32 throw SemanticError("Multiple definition of main routine\n", functionDecl); 36 33 } 37 34 main_signature.reset( functionDecl->clone() ); -
src/CodeGen/FixNames.cc
r3d4b23fa r55a68c3 14 14 // 15 15 16 #include <memory> 17 16 18 #include "FixNames.h" 17 18 #include <memory> // for unique_ptr 19 #include <string> // for string, operator!=, operator== 20 21 #include "Common/SemanticError.h" // for SemanticError 22 #include "FixMain.h" // for FixMain 23 #include "Parser/LinkageSpec.h" // for Cforall, isMangled 24 #include "SymTab/Mangler.h" // for Mangler 25 #include "SynTree/Constant.h" // for Constant 26 #include "SynTree/Declaration.h" // for FunctionDecl, ObjectDecl, Declarat... 27 #include "SynTree/Expression.h" // for ConstantExpr 28 #include "SynTree/Label.h" // for Label, noLabels 29 #include "SynTree/Statement.h" // for ReturnStmt, CompoundStmt 30 #include "SynTree/Type.h" // for Type, BasicType, Type::Qualifiers 31 #include "SynTree/Visitor.h" // for Visitor, acceptAll 19 #include "SynTree/Declaration.h" 20 #include "SynTree/Expression.h" 21 #include "SynTree/Visitor.h" 22 #include "SymTab/Mangler.h" 23 #include "OperatorTable.h" 24 #include "FixMain.h" 32 25 33 26 namespace CodeGen { … … 49 42 main_type = new FunctionType( Type::Qualifiers(), true ), nullptr ) 50 43 }; 51 main_type->get_returnVals().push_back( 44 main_type->get_returnVals().push_back( 52 45 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) 53 46 ); … … 59 52 std::string mangle_main_args() { 60 53 FunctionType* main_type; 61 std::unique_ptr<FunctionDecl> mainDecl { new FunctionDecl( "main", Type::StorageClasses(), LinkageSpec::Cforall, 54 std::unique_ptr<FunctionDecl> mainDecl { new FunctionDecl( "main", Type::StorageClasses(), LinkageSpec::Cforall, 62 55 main_type = new FunctionType( Type::Qualifiers(), false ), nullptr ) 63 56 }; 64 main_type->get_returnVals().push_back( 57 main_type->get_returnVals().push_back( 65 58 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) 66 59 ); 67 60 68 mainDecl->get_functionType()->get_parameters().push_back( 61 mainDecl->get_functionType()->get_parameters().push_back( 69 62 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) 70 63 ); 71 64 72 mainDecl->get_functionType()->get_parameters().push_back( 73 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, 74 new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Char ) ) ), 65 mainDecl->get_functionType()->get_parameters().push_back( 66 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, 67 new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Char ) ) ), 75 68 nullptr ) 76 69 ); … … 82 75 83 76 bool is_main(const std::string& name) { 84 static std::string mains[] = { 85 mangle_main(), 77 static std::string mains[] = { 78 mangle_main(), 86 79 mangle_main_args() 87 80 }; … … 119 112 int nargs = functionDecl->get_functionType()->get_parameters().size(); 120 113 if( !(nargs == 0 || nargs == 2 || nargs == 3) ) { 121 throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", functionDecl); 114 throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", functionDecl); 122 115 } 123 116 functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new ConstantExpr( Constant::from_int( 0 ) ) ) ); -
src/CodeGen/FixNames.h
r3d4b23fa r55a68c3 17 17 #define FIXNAMES_H 18 18 19 #include <list> // for list 20 21 class Declaration; 19 #include "SynTree/SynTree.h" 22 20 23 21 namespace CodeGen { -
src/CodeGen/GenType.cc
r3d4b23fa r55a68c3 14 14 // 15 15 16 #include <cassert> // for assert, assertf 17 #include <list> // for _List_iterator, _List_const_iterator 18 #include <sstream> // for operator<<, ostringstream, basic_os... 19 20 #include "CodeGenerator.h" // for CodeGenerator 16 #include <sstream> 17 #include <cassert> 18 21 19 #include "GenType.h" 22 #include "SynTree/Declaration.h" // for DeclarationWithType 23 #include "SynTree/Expression.h" // for Expression 24 #include "SynTree/Type.h" // for PointerType, Type, FunctionType 25 #include "SynTree/Visitor.h" // for Visitor 20 #include "CodeGenerator.h" 21 22 #include "SynTree/Declaration.h" 23 #include "SynTree/Expression.h" 24 #include "SynTree/Type.h" 25 #include "SynTree/Visitor.h" 26 26 27 27 namespace CodeGen { -
src/CodeGen/GenType.h
r3d4b23fa r55a68c3 17 17 #define _GENTYPE_H 18 18 19 #include <string> // for string 20 21 class Type; 19 #include <string> 20 #include "SynTree/SynTree.h" 22 21 23 22 namespace CodeGen { -
src/CodeGen/Generate.cc
r3d4b23fa r55a68c3 14 14 // 15 15 16 #include <iostream> // for ostream, endl, operator<< 17 #include <list> // for list 18 #include <string> // for operator<< 16 #include <algorithm> 17 #include <iostream> 18 #include <cassert> 19 #include <list> 19 20 20 #include "CodeGenerator.h" // for CodeGenerator, doSemicolon, oper...21 #include "GenType.h" // for genPrettyType22 21 #include "Generate.h" 23 #include "Parser/LinkageSpec.h" // for isBuiltin, isGeneratable 24 #include "SynTree/BaseSyntaxNode.h" // for BaseSyntaxNode 25 #include "SynTree/Declaration.h" // for Declaration 26 #include "SynTree/Type.h" // for Type 22 #include "SynTree/Declaration.h" 23 #include "CodeGenerator.h" 24 #include "GenType.h" 25 #include "SynTree/SynTree.h" 26 #include "SynTree/Type.h" 27 #include "SynTree/BaseSyntaxNode.h" 28 // #include "Tuples/Tuples.h" 27 29 28 30 using namespace std; -
src/CodeGen/Generate.h
r3d4b23fa r55a68c3 17 17 #define GENERATE_H 18 18 19 #include < iostream> // for ostream20 #include < list> // for list19 #include <list> 20 #include <iostream> 21 21 22 class BaseSyntaxNode; 23 class Declaration; 22 #include "SynTree/SynTree.h" 24 23 25 24 namespace CodeGen { -
src/CodeGen/OperatorTable.cc
r3d4b23fa r55a68c3 14 14 // 15 15 16 #include <map> // for map, _Rb_tree_const_iterator, map<>::const_iterator 17 #include <utility> // for pair 18 16 #include <map> 19 17 #include "OperatorTable.h" 20 18 -
src/CodeTools/DeclStats.cc
r3d4b23fa r55a68c3 16 16 #include "DeclStats.h" 17 17 18 #include <iostream> // for operator<<, basic_ostream, cout 19 #include <map> // for map 20 #include <string> // for string, operator+, operator<<, cha... 21 #include <unordered_map> // for unordered_map 22 #include <unordered_set> // for unordered_set 23 #include <utility> // for pair, make_pair 24 25 #include "Common/SemanticError.h" // for SemanticError 26 #include "Common/VectorMap.h" // for VectorMap 27 #include "GenPoly/GenPoly.h" // for hasPolyBase 28 #include "Parser/LinkageSpec.h" // for ::NoOfSpecs, Spec 29 #include "SynTree/Declaration.h" // for FunctionDecl, TypeDecl, Declaration 30 #include "SynTree/Expression.h" // for UntypedExpr, Expression 31 #include "SynTree/Statement.h" // for CompoundStmt 32 #include "SynTree/Type.h" // for Type, FunctionType, PointerType 33 #include "SynTree/Visitor.h" // for maybeAccept, Visitor, acceptAll 18 #include <iostream> 19 #include <map> 20 #include <sstream> 21 #include <string> 22 #include <unordered_map> 23 #include <unordered_set> 24 25 #include "Common/VectorMap.h" 26 #include "GenPoly/GenPoly.h" 27 #include "Parser/LinkageSpec.h" 28 #include "SynTree/Declaration.h" 29 #include "SynTree/Visitor.h" 34 30 35 31 namespace CodeTools { 36 32 37 33 class DeclStats : public Visitor { 38 34 template<typename T> … … 79 75 sum(n_types, o.n_types); 80 76 sum(p_new, o.p_new); 81 77 82 78 return *this; 83 79 } 84 80 }; 85 81 86 82 struct Stats { 87 83 unsigned n_decls; ///< Total number of declarations … … 102 98 /// Stats for the return list 103 99 ArgPackStats returns; 104 100 105 101 /// Count of declarations with each number of assertions 106 102 std::map<unsigned, unsigned> n_assns; … … 109 105 /// Stats for the assertions' return types 110 106 ArgPackStats assn_returns; 111 107 112 108 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() {} 113 109 … … 126 122 sum( assn_params, o.assn_params ); 127 123 sum( assn_returns, o.assn_returns ); 128 124 129 125 return *this; 130 126 } … … 148 144 149 145 n += dt->size(); 150 146 151 147 std::stringstream ss; 152 148 dt->print( ss ); … … 180 176 ++pstats.n_types.at( types.size() ); 181 177 } 182 178 183 179 void analyzeFunc( FunctionType* fnTy, Stats& stats, ArgPackStats& params, ArgPackStats& returns ) { 184 180 std::unordered_set<std::string> seen; … … 190 186 auto& args = expr->get_args(); 191 187 unsigned fanout = args.size(); 192 188 193 189 ++exprs_by_fanout_at_depth[ std::make_pair(depth, fanout) ]; 194 190 for ( Expression* arg : args ) { … … 209 205 return; 210 206 } 211 207 212 208 Stats& stats = for_linkage[ decl->get_linkage() ]; 213 209 … … 327 323 } 328 324 329 void printPairMap( const std::string& name, 325 void printPairMap( const std::string& name, 330 326 const std::map<std::pair<unsigned, unsigned>, unsigned>& map ) { 331 327 for ( const auto& entry : map ) { 332 328 const auto& key = entry.first; 333 std::cout << "\"" << name << "\"," << key.first << "," << key.second << "," 329 std::cout << "\"" << name << "\"," << key.first << "," << key.second << "," 334 330 << entry.second << std::endl; 335 331 } 336 332 } 337 333 338 334 public: 339 335 void print() { … … 370 366 stats.print(); 371 367 } 372 368 373 369 } // namespace CodeTools 374 370 -
src/CodeTools/DeclStats.h
r3d4b23fa r55a68c3 17 17 #define DECLSTATS_H 18 18 19 #include <list> // for list 20 21 class Declaration; 19 #include "SynTree/SynTree.h" 22 20 23 21 namespace CodeTools { -
src/CodeTools/TrackLoc.cc
r3d4b23fa r55a68c3 16 16 #include "TrackLoc.h" 17 17 18 #include <cstdlib> // for size_t, exit, EXIT_FAILURE 19 #include <iostream> // for operator<<, ostream, basic_ostream 20 #include <iterator> // for back_inserter, inserter 21 #include <stack> // for stack 22 #include <string> // for operator<<, string 23 #include <typeindex> // for type_index 18 #include <cstdlib> 24 19 25 #include "Common/PassVisitor.h" // for PassVisitor 26 #include "Common/PassVisitor.impl.h" // for acceptAll 27 #include "Common/SemanticError.h" // for SemanticError 28 #include "Common/utility.h" // for CodeLocation 29 #include "SynTree/BaseSyntaxNode.h" // for BaseSyntaxNode 30 #include "SynTree/Mutator.h" // for mutateAll 31 #include "SynTree/Visitor.h" // for acceptAll 20 #include <iostream> 21 #include <sstream> 22 #include <stack> 23 #include <string> 24 #include <typeindex> 32 25 33 class Declaration; 26 #include "Common/utility.h" 27 #include "Common/PassVisitor.h" 28 #include "Common/VectorMap.h" 29 #include "GenPoly/GenPoly.h" 30 #include "Parser/LinkageSpec.h" 31 #include "SynTree/Declaration.h" 32 #include "SynTree/Initializer.h" 34 33 35 34 namespace CodeTools { -
src/CodeTools/TrackLoc.h
r3d4b23fa r55a68c3 17 17 #define TRACKLOC_H 18 18 19 #include <cstddef> // for size_t 20 #include <list> // for list 21 22 class Declaration; 19 #include "SynTree/SynTree.h" 23 20 24 21 namespace CodeTools { -
src/Common/Assert.cc
r3d4b23fa r55a68c3 14 14 // 15 15 16 #include <cstdarg> // for va_end, va_list, va_start 17 #include <cstdio> // for fprintf, stderr, vfprintf 18 #include <cstdlib> // for abort 16 #include <assert.h> 17 #include <cstdarg> // varargs 18 #include <cstdio> // fprintf 19 #include <cstdlib> // abort 19 20 20 21 extern const char * __progname; // global name of running executable (argv[0]) -
src/Common/SemanticError.cc
r3d4b23fa r55a68c3 14 14 // 15 15 16 #include < cstdio> // for fileno, stderr17 #include < unistd.h> // for isatty18 #include < iostream> // for basic_ostream, operator<<, ostream19 #include < list> // for list, _List_iterator20 #include < string> // for string, operator<<, operator+, to_string16 #include <iostream> 17 #include <list> 18 #include <string> 19 #include <algorithm> 20 #include <iterator> 21 21 22 #include "Common/utility.h" // for to_string, CodeLocation (ptr only)23 22 #include "SemanticError.h" 23 24 #include <unistd.h> 24 25 25 26 inline const std::string& error_str() { -
src/Common/SemanticError.h
r3d4b23fa r55a68c3 17 17 #define SEMANTICERROR_H 18 18 19 #include <exception> // for exception 20 #include <iostream> // for ostream 21 #include <list> // for list 22 #include <string> // for string 19 #include <exception> 20 #include <string> 21 #include <sstream> 22 #include <list> 23 #include <iostream> 23 24 24 #include "utility.h" // for CodeLocation, toString25 #include "utility.h" 25 26 26 27 struct error { -
src/Concurrency/Keywords.cc
r3d4b23fa r55a68c3 17 17 #include "Concurrency/Keywords.h" 18 18 19 #include <cassert> // for assert 20 #include <string> // for string, operator== 21 22 #include "Common/SemanticError.h" // for SemanticError 23 #include "Common/utility.h" // for deleteAll, map_range 24 #include "InitTweak/InitTweak.h" // for isConstructor 25 #include "Parser/LinkageSpec.h" // for Cforall 26 #include "SymTab/AddVisit.h" // for acceptAndAdd 27 #include "SynTree/Constant.h" // for Constant 28 #include "SynTree/Declaration.h" // for StructDecl, FunctionDecl, ObjectDecl 29 #include "SynTree/Expression.h" // for VariableExpr, ConstantExpr, Untype... 30 #include "SynTree/Initializer.h" // for SingleInit, ListInit, Initializer ... 31 #include "SynTree/Label.h" // for Label 32 #include "SynTree/Statement.h" // for CompoundStmt, DeclStmt, ExprStmt 33 #include "SynTree/Type.h" // for StructInstType, Type, PointerType 34 #include "SynTree/Visitor.h" // for Visitor, acceptAll 35 36 class Attribute; 19 #include "InitTweak/InitTweak.h" 20 #include "SymTab/AddVisit.h" 21 #include "SynTree/Declaration.h" 22 #include "SynTree/Expression.h" 23 #include "SynTree/Initializer.h" 24 #include "SynTree/Statement.h" 25 #include "SynTree/Type.h" 26 #include "SynTree/Visitor.h" 37 27 38 28 namespace Concurrency { … … 332 322 if( needs_main ) { 333 323 FunctionType * main_type = new FunctionType( noQualifiers, false ); 334 324 335 325 main_type->get_parameters().push_back( this_decl->clone() ); 336 326 … … 371 361 void ConcurrentSueKeyword::addRoutines( ObjectDecl * field, FunctionDecl * func ) { 372 362 CompoundStmt * statement = new CompoundStmt( noLabels ); 373 statement->push_back( 363 statement->push_back( 374 364 new ReturnStmt( 375 365 noLabels, … … 396 386 //============================================================================================= 397 387 void MutexKeyword::visit(FunctionDecl* decl) { 398 Visitor::visit(decl); 388 Visitor::visit(decl); 399 389 400 390 std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl ); … … 520 510 void ThreadStarter::visit(FunctionDecl * decl) { 521 511 Visitor::visit(decl); 522 512 523 513 if( ! InitTweak::isConstructor(decl->get_name()) ) return; 524 514 … … 538 528 if( ! stmt ) return; 539 529 540 stmt->push_back( 530 stmt->push_back( 541 531 new ExprStmt( 542 532 noLabels, -
src/Concurrency/Keywords.h
r3d4b23fa r55a68c3 18 18 #define KEYWORDS_H 19 19 20 #include <list> // for list20 #include <list> 21 21 22 class Declaration; 22 #include "SynTree/Declaration.h" 23 23 24 24 namespace Concurrency { -
src/ControlStruct/ExceptTranslate.cc
r3d4b23fa r55a68c3 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jul 12 15:07:00 201713 // Update Count : 312 // Last Modified On : Fri Jun 30 13:30:00 2017 13 // Update Count : 1 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 e", throwStmt );159 return create_given_throw( "__cfaehm__throw_termination", 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 e" ) )166 new UntypedExpr( new NameExpr( "__cfaehm__rethrow_termination" ) ) 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 e", throwStmt );173 return create_given_throw( "__cfaehm__throw_resumption", throwStmt ); 174 174 } 175 175 Statement * create_resume_rethrow( ThrowStmt *throwStmt ) { … … 593 593 594 594 PassVisitor<ExceptionMutatorCore> translator; 595 mutateAll( translationUnit, translator ); 595 for ( Declaration * decl : translationUnit ) { 596 decl->acceptMutator( translator ); 597 } 596 598 } 597 599 } -
src/GenPoly/InstantiateGeneric.cc
r3d4b23fa r55a68c3 171 171 Type* postmutate( UnionInstType *inst ); 172 172 173 void premutate( __attribute__((unused))FunctionType * ftype ) {173 void premutate( FunctionType * ftype ) { 174 174 GuardValue( inFunctionType ); 175 175 inFunctionType = true; -
src/InitTweak/GenInit.cc
r3d4b23fa r55a68c3 71 71 // that need to be constructed or destructed 72 72 void previsit( StructDecl *aggregateDecl ); 73 void previsit( __attribute__((unused)) UnionDecl * aggregateDecl ) { visit_children = false; } 74 void previsit( __attribute__((unused)) EnumDecl * aggregateDecl ) { visit_children = false; } 75 void previsit( __attribute__((unused)) TraitDecl * aggregateDecl ) { visit_children = false; } 76 void previsit( __attribute__((unused)) TypeDecl * typeDecl ) { visit_children = false; } 77 void previsit( __attribute__((unused)) TypedefDecl * typeDecl ) { visit_children = false; } 78 void previsit( __attribute__((unused)) FunctionType * funcType ) { visit_children = false; } 73 void previsit( UnionDecl *aggregateDecl ) { visit_children = false; } 74 void previsit( EnumDecl *aggregateDecl ) { visit_children = false; } 75 void previsit( TraitDecl *aggregateDecl ) { visit_children = false; } 76 void previsit( TypeDecl *typeDecl ) { visit_children = false; } 77 void previsit( TypedefDecl *typeDecl ) { visit_children = false; } 78 79 void previsit( FunctionType *funcType ) { visit_children = false; } 79 80 80 81 void previsit( CompoundStmt * compoundStmt ); … … 335 336 } 336 337 337 void CtorDtor::previsit( __attribute__((unused))CompoundStmt * compoundStmt ) {338 void CtorDtor::previsit( CompoundStmt * compoundStmt ) { 338 339 GuardScope( managedTypes ); 339 340 } -
src/MakeLibCfa.cc
r3d4b23fa r55a68c3 15 15 16 16 #include "MakeLibCfa.h" 17 18 #include <cassert> // for assert 19 #include <string> // for operator==, string 20 21 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup, Ope... 22 #include "Common/SemanticError.h" // for SemanticError 23 #include "Common/UniqueName.h" // for UniqueName 24 #include "Parser/LinkageSpec.h" // for Spec, Intrinsic, C 25 #include "SynTree/Declaration.h" // for FunctionDecl, ObjectDecl, Declara... 26 #include "SynTree/Expression.h" // for NameExpr, UntypedExpr, VariableExpr 27 #include "SynTree/Initializer.h" // for SingleInit 28 #include "SynTree/Label.h" // for Label 29 #include "SynTree/Statement.h" // for CompoundStmt, ReturnStmt 30 #include "SynTree/Type.h" // for FunctionType 31 #include "SynTree/Visitor.h" // for acceptAll, Visitor 17 #include "SynTree/Visitor.h" 18 #include "SynTree/Declaration.h" 19 #include "SynTree/Type.h" 20 #include "SynTree/Expression.h" 21 #include "SynTree/Statement.h" 22 #include "SynTree/Initializer.h" 23 #include "CodeGen/OperatorTable.h" 24 #include "Common/UniqueName.h" 32 25 33 26 namespace LibCfa { -
src/MakeLibCfa.h
r3d4b23fa r55a68c3 17 17 #define LIBCFA_MAKELIBCFA_H 18 18 19 #include <list> // for list 20 21 class Declaration; 19 #include <list> 20 #include <SynTree/SynTree.h> 22 21 23 22 namespace LibCfa { -
src/Makefile.am
r3d4b23fa r55a68c3 43 43 driver_cfa_cpp_SOURCES = ${SRC} 44 44 driver_cfa_cpp_LDADD = ${LEXLIB} -ldl # yywrap 45 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall - Wextra -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++1445 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -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
r3d4b23fa r55a68c3 544 544 driver_cfa_cpp_SOURCES = ${SRC} 545 545 driver_cfa_cpp_LDADD = ${LEXLIB} -ldl # yywrap 546 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall - Wextra -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14546 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -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) -- foreignsrc/Makefile'; \562 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ 563 563 $(am__cd) $(top_srcdir) && \ 564 $(AUTOMAKE) -- foreignsrc/Makefile564 $(AUTOMAKE) --gnu src/Makefile 565 565 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 566 566 @case '$?' in \ -
src/Parser/LinkageSpec.cc
r3d4b23fa r55a68c3 10 10 // Created On : Sat May 16 13:22:09 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 7 11:11:00 201713 // Update Count : 2 512 // Last Modified On : Wed Jun 28 11:51:00 2017 13 // Update Count : 24 14 14 // 15 15 … … 22 22 #include "Common/SemanticError.h" 23 23 24 namespace LinkageSpec { 25 26 Spec linkageCheck( const string * spec ) { 27 assert( spec ); 24 LinkageSpec::Spec LinkageSpec::linkageCheck( const string * spec ) { 28 25 unique_ptr<const string> guard( spec ); // allocated by lexer 29 26 if ( *spec == "\"Cforall\"" ) { … … 38 35 } 39 36 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 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]; 52 43 } 53 44 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 } 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]; 73 54 } 74 55 75 } // LinkageSpec 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 } 76 88 77 89 // Local Variables: // -
src/Parser/LinkageSpec.h
r3d4b23fa r55a68c3 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 : Fri Jul 7 11:03:00 201713 // Update Count : 1 312 // Last Modified On : Wed Jun 28 11:50:00 2017 13 // Update Count : 12 14 14 // 15 15 … … 19 19 #include <string> 20 20 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, 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 30 31 }; 31 32 union Spec { 33 unsigned int val; 34 struct { 35 bool is_mangled : 1; 36 bool is_generatable : 1; 37 bool is_overridable : 1; 38 bool is_builtin : 1; 39 }; 40 constexpr Spec( unsigned int val ) : val( val ) {} 41 constexpr Spec( Spec const &other ) : val( other.val ) {} 42 // Operators may go here. 43 // Supports == and != 44 constexpr operator unsigned int () const { return val; } 45 }; 46 47 48 Spec linkageCheck( const std::string * ); 49 // Returns the Spec with the given name (limited to C, Cforall & BuiltinC) 50 Spec linkageUpdate( Spec old_spec, const std::string * cmd ); 51 /* If cmd = "C" returns a Spec that is old_spec with is_mangled = false 52 * If cmd = "Cforall" returns old_spec Spec with is_mangled = true 53 */ 54 55 std::string linkageName( Spec ); 56 57 // To Update: LinkageSpec::isXyz( cur_spec ) -> cur_spec.is_xyz 58 inline bool isMangled( Spec spec ) { return spec.is_mangled; } 59 inline bool isGeneratable( Spec spec ) { return spec.is_generatable; } 60 inline bool isOverridable( Spec spec ) { return spec.is_overridable; } 61 inline bool isBuiltin( Spec spec ) { return spec.is_builtin; } 62 63 // Pre-defined flag combinations: 64 // C built-in defined in prelude 65 constexpr Spec const Intrinsic = { Mangle | Generate | Overrideable | Builtin }; 66 // ordinary 67 constexpr Spec const Cforall = { Mangle | Generate }; 68 // not overloadable, not mangled 69 constexpr Spec const C = { Generate }; 70 // built by translator (struct assignment) 71 constexpr Spec const AutoGen = { Mangle | Generate | Overrideable }; 72 // gcc internal 73 constexpr Spec const Compiler = { Builtin }; 74 // mangled builtins 75 constexpr Spec const BuiltinCFA = { Mangle | Generate | Builtin }; 76 // non-mangled builtins 77 constexpr Spec const BuiltinC = { Generate | Builtin }; 32 33 static Spec linkageCheck( const std::string * ); 34 static std::string linkageName( Spec ); 35 36 static bool isMangled( Spec ); 37 static bool isGeneratable( Spec ); 38 static bool isOverridable( Spec ); 39 static bool isBuiltin( Spec ); 78 40 }; 79 41 -
src/Parser/StatementNode.cc
r3d4b23fa r55a68c3 10 10 // Created On : Sat May 16 14:59:41 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 11 21:23:15201713 // Update Count : 33 112 // Last Modified On : Wed Jun 28 21:08:37 2017 13 // Update Count : 330 14 14 // 15 15 … … 93 93 std::list< Statement * > branches; 94 94 buildMoveList< Statement, StatementNode >( stmt, branches ); 95 // branches.size()== 0 for switch (...) {}, i.e., no declaration or statements95 assert( branches.size() >= 0 ); // 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
r3d4b23fa r55a68c3 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 l 12 18:04:44201713 * Update Count : 5 3512 * Last Modified On : Wed Jun 28 21:03:45 2017 13 * Update Count : 529 14 14 */ 15 15 … … 59 59 } 60 60 61 // Stop warning due to incorrectly generated flex code.62 #pragma GCC diagnostic ignored "-Wsign-compare"63 61 %} 64 62 … … 274 272 __volatile__ { KEYWORD_RETURN(VOLATILE); } // GCC 275 273 while { KEYWORD_RETURN(WHILE); } 276 with { KEYWORD_RETURN(WITH); } // CFA277 274 zero_t { NUMERIC_RETURN(ZERO_T); } // CFA 278 275 -
src/Parser/parser.yy
r3d4b23fa r55a68c3 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jul 12 18:23:36201713 // Update Count : 24 2611 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jun 30 15:38:00 2017 13 // Update Count : 2415 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 WITH// CFA131 %token CHOOSE DISABLE ENABLE FALLTHRU TRY CATCH CATCHRESUME FINALLY THROW THROWRESUME AT // 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 187 %type<sn> with_statement exception_statement asm_statement 186 %type<sn> iteration_statement jump_statement exception_statement asm_statement 188 187 %type<sn> fall_through_opt fall_through 189 188 %type<sn> statement statement_list 190 189 %type<sn> block_item_list block_item 191 %type<sn> with_clause_opt190 %type<sn> case_clause 192 191 %type<en> case_value 193 %type<sn> case_ clause case_value_list case_label case_label_list192 %type<sn> case_value_list case_label case_label_list 194 193 %type<sn> switch_clause_list_opt switch_clause_list choose_clause_list_opt choose_clause_list 195 194 %type<sn> /* handler_list */ handler_clause finally_clause … … 730 729 | iteration_statement 731 730 | jump_statement 732 | with_statement733 731 | exception_statement 734 732 | asm_statement … … 936 934 | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume 937 935 { $$ = new StatementNode( build_resume_at( $2, $4 ) ); } 938 ;939 940 with_statement:941 WITH identifier_list compound_statement942 { $$ = (StatementNode *)0; } // FIX ME943 936 ; 944 937 … … 2183 2176 { 2184 2177 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 2185 linkage = LinkageSpec::linkage Update( linkage,$2 );2178 linkage = LinkageSpec::linkageCheck( $2 ); 2186 2179 } 2187 2180 '{' external_definition_list_opt '}' … … 2219 2212 ; 2220 2213 2221 with_clause_opt:2222 // empty2223 { $$ = (StatementNode *)0; } // FIX ME2224 | WITH identifier_list2225 { $$ = (StatementNode *)0; } // FIX ME2226 ;2227 2228 2214 function_definition: 2229 cfa_function_declaration with_clause_opt compound_statement// CFA2215 cfa_function_declaration compound_statement // CFA 2230 2216 { 2231 2217 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2232 2218 typedefTable.leaveScope(); 2233 $$ = $1->addFunctionBody( $ 3);2234 } 2235 | declaration_specifier function_declarator with_clause_optcompound_statement2219 $$ = $1->addFunctionBody( $2 ); 2220 } 2221 | declaration_specifier function_declarator compound_statement 2236 2222 { 2237 2223 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2238 2224 typedefTable.leaveScope(); 2239 $$ = $2->addFunctionBody( $ 4)->addType( $1 );2240 } 2241 | type_qualifier_list function_declarator with_clause_optcompound_statement2225 $$ = $2->addFunctionBody( $3 )->addType( $1 ); 2226 } 2227 | type_qualifier_list function_declarator compound_statement 2242 2228 { 2243 2229 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2244 2230 typedefTable.leaveScope(); 2245 $$ = $2->addFunctionBody( $ 4)->addQualifiers( $1 );2246 } 2247 | declaration_qualifier_list function_declarator with_clause_optcompound_statement2231 $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 ); 2232 } 2233 | declaration_qualifier_list function_declarator compound_statement 2248 2234 { 2249 2235 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2250 2236 typedefTable.leaveScope(); 2251 $$ = $2->addFunctionBody( $ 4)->addQualifiers( $1 );2252 } 2253 | declaration_qualifier_list type_qualifier_list function_declarator with_clause_optcompound_statement2237 $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 ); 2238 } 2239 | declaration_qualifier_list type_qualifier_list function_declarator compound_statement 2254 2240 { 2255 2241 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2256 2242 typedefTable.leaveScope(); 2257 $$ = $3->addFunctionBody( $ 5)->addQualifiers( $2 )->addQualifiers( $1 );2243 $$ = $3->addFunctionBody( $4 )->addQualifiers( $2 )->addQualifiers( $1 ); 2258 2244 } 2259 2245 2260 2246 // Old-style K&R function definition, OBSOLESCENT (see 4) 2261 | declaration_specifier KR_function_declarator push KR_declaration_list_opt with_clause_optcompound_statement2247 | declaration_specifier KR_function_declarator push KR_declaration_list_opt compound_statement 2262 2248 { 2263 2249 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2264 2250 typedefTable.leaveScope(); 2265 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $ 6)->addType( $1 );2266 } 2267 | type_qualifier_list KR_function_declarator push KR_declaration_list_opt with_clause_optcompound_statement2251 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addType( $1 ); 2252 } 2253 | type_qualifier_list KR_function_declarator push KR_declaration_list_opt compound_statement 2268 2254 { 2269 2255 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2270 2256 typedefTable.leaveScope(); 2271 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $ 6)->addQualifiers( $1 );2257 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 ); 2272 2258 } 2273 2259 2274 2260 // Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4) 2275 | declaration_qualifier_list KR_function_declarator push KR_declaration_list_opt with_clause_optcompound_statement2261 | declaration_qualifier_list KR_function_declarator push KR_declaration_list_opt compound_statement 2276 2262 { 2277 2263 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2278 2264 typedefTable.leaveScope(); 2279 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $ 6)->addQualifiers( $1 );2280 } 2281 | declaration_qualifier_list type_qualifier_list KR_function_declarator push KR_declaration_list_opt with_clause_optcompound_statement2265 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 ); 2266 } 2267 | declaration_qualifier_list type_qualifier_list KR_function_declarator push KR_declaration_list_opt compound_statement 2282 2268 { 2283 2269 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2284 2270 typedefTable.leaveScope(); 2285 $$ = $3->addOldDeclList( $5 )->addFunctionBody( $ 7)->addQualifiers( $2 )->addQualifiers( $1 );2271 $$ = $3->addOldDeclList( $5 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 ); 2286 2272 } 2287 2273 ; … … 2346 2332 | TYPEGENname 2347 2333 | CONST 2348 { $$ = Token{ new string( "__const__" ) , { nullptr, -1 }}; }2334 { $$ = Token{ new string( "__const__" ) }; } 2349 2335 ; 2350 2336 -
src/ResolvExpr/CurrentObject.cc
r3d4b23fa r55a68c3 114 114 } 115 115 116 virtual void print( std::ostream & out, __attribute__((unused))Indenter indent ) const {116 virtual void print( std::ostream & out, Indenter indent ) const { 117 117 out << "SimpleIterator(" << type << ")"; 118 118 } -
src/benchmark/CorCtxSwitch.c
r3d4b23fa r55a68c3 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 // } 33 37 resumer( &s, NoOfTimes ); 34 38 EndTime = Time(); -
src/benchmark/Makefile.am
r3d4b23fa r55a68c3 20 20 CC = @CFA_BINDIR@/@CFA_NAME@ 21 21 22 noinst_PROGRAMS = bench $(EXEEXT) ctxswitch-coroutine$(EXEEXT) ctxswitch-thread$(EXEEXT) sched-int$(EXEEXT) monitor$(EXEEXT) csv-data$(EXEEXT)22 noinst_PROGRAMS = bench ctxswitch-coroutine ctxswitch-thread 23 23 24 bench $(EXEEXT):24 bench : 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 $(EXEEXT):32 ctxswitch-coroutine: 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 $(EXEEXT):39 ctxswitch-thread: 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 $(EXEEXT):46 sched-int: 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 $(EXEEXT):53 monitor: 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 $(EXEEXT):60 csv-data: 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
r3d4b23fa r55a68c3 92 92 build_triplet = @build@ 93 93 host_triplet = @host@ 94 noinst_PROGRAMS = bench$(EXEEXT) ctxswitch-coroutine$(EXEEXT) \ 95 ctxswitch-thread$(EXEEXT) 94 96 subdir = src/benchmark 95 97 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 … … 106 108 bench_OBJECTS = bench.$(OBJEXT) 107 109 bench_LDADD = $(LDADD) 108 csv_data_SOURCES = csv-data.c109 csv_data_OBJECTS = csv-data.$(OBJEXT)110 csv_data_LDADD = $(LDADD)111 110 ctxswitch_coroutine_SOURCES = ctxswitch-coroutine.c 112 111 ctxswitch_coroutine_OBJECTS = ctxswitch-coroutine.$(OBJEXT) … … 115 114 ctxswitch_thread_OBJECTS = ctxswitch-thread.$(OBJEXT) 116 115 ctxswitch_thread_LDADD = $(LDADD) 117 monitor_SOURCES = monitor.c118 monitor_OBJECTS = monitor.$(OBJEXT)119 monitor_LDADD = $(LDADD)120 sched_int_SOURCES = sched-int.c121 sched_int_OBJECTS = sched-int.$(OBJEXT)122 sched_int_LDADD = $(LDADD)123 116 AM_V_P = $(am__v_P_@AM_V@) 124 117 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) … … 149 142 am__v_CCLD_0 = @echo " CCLD " $@; 150 143 am__v_CCLD_1 = 151 SOURCES = bench.c csv-data.c ctxswitch-coroutine.c ctxswitch-thread.c \ 152 monitor.c sched-int.c 153 DIST_SOURCES = bench.c csv-data.c ctxswitch-coroutine.c \ 154 ctxswitch-thread.c monitor.c sched-int.c 144 SOURCES = bench.c ctxswitch-coroutine.c ctxswitch-thread.c 145 DIST_SOURCES = bench.c ctxswitch-coroutine.c ctxswitch-thread.c 155 146 am__can_run_installinfo = \ 156 147 case $$AM_UPDATE_INFO_DIR in \ … … 302 293 top_srcdir = @top_srcdir@ 303 294 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)305 295 all: all-am 306 296 … … 316 306 esac; \ 317 307 done; \ 318 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- foreignsrc/benchmark/Makefile'; \308 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/benchmark/Makefile'; \ 319 309 $(am__cd) $(top_srcdir) && \ 320 $(AUTOMAKE) -- foreignsrc/benchmark/Makefile310 $(AUTOMAKE) --gnu src/benchmark/Makefile 321 311 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 322 312 @case '$?' in \ … … 347 337 348 338 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bench.Po@am__quote@ 349 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csv-data.Po@am__quote@350 339 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctxswitch-coroutine.Po@am__quote@ 351 340 @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@354 341 355 342 .c.o: … … 572 559 573 560 574 bench $(EXEEXT):561 bench : 575 562 @for ccflags in "-debug" "-nodebug"; do \ 576 563 echo ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -lrt bench.c;\ … … 580 567 rm -f ./a.out ; 581 568 582 ctxswitch-coroutine $(EXEEXT):569 ctxswitch-coroutine: 583 570 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 CorCtxSwitch.c 584 571 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 587 574 @rm -f ./a.out 588 575 589 ctxswitch-thread $(EXEEXT):576 ctxswitch-thread: 590 577 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 ThrdCtxSwitch.c 591 578 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 594 581 @rm -f ./a.out 595 582 596 sched-int $(EXEEXT):583 sched-int: 597 584 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c 598 585 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 601 588 @rm -f ./a.out 602 589 603 monitor $(EXEEXT):590 monitor: 604 591 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c 605 592 @for number in 1 2 3 4 5 6 7 8 9 10; do \ … … 608 595 @rm -f ./a.out 609 596 610 csv-data $(EXEEXT):597 csv-data: 611 598 @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c 612 599 @./a.out -
src/benchmark/bench.h
r3d4b23fa r55a68c3 26 26 #define N 10000000 27 27 #endif 28 29 unsigned int default_preemption() {30 return 0;31 } -
src/benchmark/create_pthrd.c
r3d4b23fa r55a68c3 17 17 18 18 for (size_t i = 0; i < n; i++) { 19 pthread_ t thread;20 if (pthread_ create(&thread, NULL, foo, NULL) < 0) {19 pthread_attr_t attr; 20 if (pthread_attr_init(&attr) < 0) { 21 21 return 1; 22 22 } 23 24 if (pthread_join( thread, NULL) < 0) { 23 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) < 0) { 24 return 1; 25 } 26 pthread_t thread; 27 if (pthread_create(&thread, &attr, foo, NULL) < 0) { 25 28 return 1; 26 29 } -
src/benchmark/csv-data.c
r3d4b23fa r55a68c3 25 25 } 26 26 27 #ifndef N 28 #define N 100000000 29 #endif 30 27 31 //----------------------------------------------------------------------------- 28 32 // coroutine context switch … … 34 38 35 39 StartTime = Time(); 40 // for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) { 41 // resume( this_coroutine() ); 42 // // resume( &s ); 43 // } 36 44 resumer( &s, NoOfTimes ); 37 45 EndTime = Time(); … … 96 104 mon_t mon1; 97 105 98 condition cond1a; 106 condition cond1a; 99 107 condition cond1b; 100 108 … … 144 152 mon_t mon2; 145 153 146 condition cond2a; 154 condition cond2a; 147 155 condition cond2b; 148 156 -
src/driver/Makefile.in
r3d4b23fa r55a68c3 315 315 esac; \ 316 316 done; \ 317 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- foreignsrc/driver/Makefile'; \317 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/driver/Makefile'; \ 318 318 $(am__cd) $(top_srcdir) && \ 319 $(AUTOMAKE) -- foreignsrc/driver/Makefile319 $(AUTOMAKE) --gnu src/driver/Makefile 320 320 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 321 321 @case '$?' in \ -
src/examples/Makefile.in
r3d4b23fa r55a68c3 319 319 esac; \ 320 320 done; \ 321 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- foreignsrc/examples/Makefile'; \321 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/examples/Makefile'; \ 322 322 $(am__cd) $(top_srcdir) && \ 323 $(AUTOMAKE) -- foreignsrc/examples/Makefile323 $(AUTOMAKE) --gnu src/examples/Makefile 324 324 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 325 325 @case '$?' in \ -
src/include/assert.h
r3d4b23fa r55a68c3 15 15 16 16 #pragma once 17 // Pragmas for header cleanup tool18 // IWYU pragma: private, include <cassert>19 17 20 18 #include_next <assert.h> -
src/libcfa/Makefile.am
r3d4b23fa r55a68c3 17 17 # create object files in directory with source files 18 18 AUTOMAKE_OPTIONS = subdir-objects 19 ARFLAGS = cr20 19 21 20 libdir = ${CFA_LIBDIR} -
src/libcfa/Makefile.in
r3d4b23fa r55a68c3 142 142 LIBRARIES = $(lib_LIBRARIES) 143 143 AR = ar 144 ARFLAGS = cru 144 145 AM_V_AR = $(am__v_AR_@AM_V@) 145 146 am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) … … 408 409 # create object files in directory with source files 409 410 AUTOMAKE_OPTIONS = subdir-objects 410 ARFLAGS = cr411 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) -- foreignsrc/libcfa/Makefile'; \441 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcfa/Makefile'; \ 442 442 $(am__cd) $(top_srcdir) && \ 443 $(AUTOMAKE) -- foreignsrc/libcfa/Makefile443 $(AUTOMAKE) --gnu src/libcfa/Makefile 444 444 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 445 445 @case '$?' in \ -
src/libcfa/concurrency/CtxSwitch-i386.S
r3d4b23fa r55a68c3 98 98 ret 99 99 100 .text 101 .align 2 102 .globl CtxGet 103 CtxGet: 104 movl %esp,SP_OFFSET(%eax) 105 movl %ebp,FP_OFFSET(%eax) 106 107 ret 108 100 109 // Local Variables: // 101 110 // compile-command: "make install" // -
src/libcfa/concurrency/CtxSwitch-x86_64.S
r3d4b23fa r55a68c3 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 .text 99 .align 2 100 .globl CtxGet 101 CtxGet: 102 movq %rsp,SP_OFFSET(%rdi) 103 movq %rbp,FP_OFFSET(%rdi) 104 105 ret 97 106 98 107 // Local Variables: // -
src/libcfa/concurrency/alarm.c
r3d4b23fa r55a68c3 16 16 17 17 extern "C" { 18 #include <errno.h>19 #include <stdio.h>20 #include <string.h>21 18 #include <time.h> 22 #include <unistd.h>23 19 #include <sys/time.h> 24 20 } 25 26 #include "libhdr.h"27 21 28 22 #include "alarm.h" … … 37 31 timespec curr; 38 32 clock_gettime( CLOCK_REALTIME, &curr ); 39 __cfa_time_t curr_time = ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec; 40 // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : current time is %lu\n", curr_time ); 41 return curr_time; 33 return ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec; 42 34 } 43 35 44 36 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 );46 37 itimerval val; 47 38 val.it_value.tv_sec = alarm / TIMEGRAN; // seconds … … 80 71 } 81 72 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 91 73 static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) { 92 verify( !n->next );74 assert( !n->next ); 93 75 if( p == this->tail ) { 94 76 this->tail = &n->next; … … 98 80 } 99 81 *p = n; 100 101 verify( validate( this ) );102 82 } 103 83 … … 109 89 110 90 insert_at( this, n, it ); 111 112 verify( validate( this ) );113 91 } 114 92 … … 122 100 head->next = NULL; 123 101 } 124 verify( validate( this ) );125 102 return head; 126 103 } … … 128 105 static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) { 129 106 verify( it ); 130 verify( (*it) == n );107 verify( (*it)->next == n ); 131 108 132 (*it) = n->next;109 (*it)->next = n->next; 133 110 if( !n-> next ) { 134 111 this->tail = it; 135 112 } 136 113 n->next = NULL; 137 138 verify( validate( this ) );139 114 } 140 115 141 116 static inline void remove( alarm_list_t * this, alarm_node_t * n ) { 142 117 alarm_node_t ** it = &this->head; 143 while( (*it) && (*it) != n ) {118 while( (*it) && (*it)->next != n ) { 144 119 it = &(*it)->next; 145 120 } 146 121 147 verify( validate( this ) );148 149 122 if( *it ) { remove_at( this, n, it ); } 150 151 verify( validate( this ) );152 123 } 153 124 154 125 void register_self( alarm_node_t * this ) { 155 126 disable_interrupts(); 156 verify( !systemProcessor->pending_alarm );157 lock( &systemProcessor->alarm_lock DEBUG_CTX2);127 assert( !systemProcessor->pending_alarm ); 128 lock( &systemProcessor->alarm_lock ); 158 129 { 159 verify( validate( &systemProcessor->alarms ) );160 bool first = !systemProcessor->alarms.head;161 162 130 insert( &systemProcessor->alarms, this ); 163 131 if( systemProcessor->pending_alarm ) { 164 132 tick_preemption(); 165 133 } 166 if( first ) {167 __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() );168 }169 134 } 170 135 unlock( &systemProcessor->alarm_lock ); 171 136 this->set = true; 172 enable_interrupts( DEBUG_CTX);137 enable_interrupts(); 173 138 } 174 139 175 140 void unregister_self( alarm_node_t * this ) { 176 // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : unregister %p start\n", this );177 141 disable_interrupts(); 178 lock( &systemProcessor->alarm_lock DEBUG_CTX2 ); 179 { 180 verify( validate( &systemProcessor->alarms ) ); 181 remove( &systemProcessor->alarms, this ); 182 } 142 lock( &systemProcessor->alarm_lock ); 143 remove( &systemProcessor->alarms, this ); 183 144 unlock( &systemProcessor->alarm_lock ); 184 enable_interrupts( DEBUG_CTX);145 disable_interrupts(); 185 146 this->set = false; 186 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Kernel : unregister %p end\n", this );187 147 } -
src/libcfa/concurrency/coroutine
r3d4b23fa r55a68c3 63 63 64 64 // Get current coroutine 65 extern volatile thread_local coroutine_desc * this_coroutine;65 coroutine_desc * this_coroutine(void); 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
r3d4b23fa r55a68c3 32 32 #include "invoke.h" 33 33 34 extern volatilethread_local processor * this_processor;34 extern thread_local processor * this_processor; 35 35 36 36 //----------------------------------------------------------------------------- … … 44 44 // Coroutine ctors and dtors 45 45 void ?{}(coStack_t* this) { 46 this->size = 65000; // size of stack46 this->size = 10240; // 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 = src->state == Halted ? Halted :Inactive;108 src->state = Inactive; 109 109 110 110 // set new coroutine that task is executing 111 this_ coroutine = dst;111 this_processor->current_coroutine = dst; 112 112 113 113 // context switch to specified coroutine 114 assert( src->stack.context );115 114 CtxSwitch( src->stack.context, dst->stack.context ); 116 // when CtxSwitch returns we are back in the src coroutine 115 // when CtxSwitch returns we are back in the src coroutine 117 116 118 117 // set state of new coroutine to active … … 132 131 this->size = libCeiling( storageSize, 16 ); 133 132 // use malloc/memalign because "new" raises an exception for out-of-memory 134 133 135 134 // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment 136 135 LIB_DEBUG_DO( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) ); -
src/libcfa/concurrency/invoke.c
r3d4b23fa r55a68c3 29 29 30 30 extern void __suspend_internal(void); 31 extern void __leave_thread_monitor( struct thread_desc * this ); 32 extern void disable_interrupts(); 33 extern void enable_interrupts( DEBUG_CTX_PARAM ); 31 extern void __leave_monitor_desc( struct monitor_desc * this ); 34 32 35 33 void CtxInvokeCoroutine( 36 void (*main)(void *), 37 struct coroutine_desc *(*get_coroutine)(void *), 34 void (*main)(void *), 35 struct coroutine_desc *(*get_coroutine)(void *), 38 36 void *this 39 37 ) { … … 58 56 59 57 void CtxInvokeThread( 60 void (*dtor)(void *), 61 void (*main)(void *), 62 struct thread_desc *(*get_thread)(void *), 58 void (*dtor)(void *), 59 void (*main)(void *), 60 struct thread_desc *(*get_thread)(void *), 63 61 void *this 64 62 ) { 65 // First suspend, once the thread arrives here,66 // the function pointer to main can be invalidated without risk67 63 __suspend_internal(); 68 64 69 // Fetch the thread handle from the user defined thread structure70 65 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; 71 69 72 // Officially start the thread by enabling preemption 73 enable_interrupts( DEBUG_CTX ); 74 75 // Call the main of the thread 70 // LIB_DEBUG_PRINTF("Invoke Thread : invoking main %p (args %p)\n", main, this); 76 71 main( this ); 77 72 78 // To exit a thread we must : 79 // 1 - Mark it as halted 80 // 2 - Leave its monitor 81 // 3 - Disable the interupts 82 // 4 - Final suspend 83 // The order of these 4 operations is very important 73 __leave_monitor_desc( mon ); 74 84 75 //Final suspend, should never return 85 __ leave_thread_monitor( thrd);76 __suspend_internal(); 86 77 abortf("Resumed dead thread"); 87 78 } … … 89 80 90 81 void CtxStart( 91 void (*main)(void *), 92 struct coroutine_desc *(*get_coroutine)(void *), 93 void *this, 82 void (*main)(void *), 83 struct coroutine_desc *(*get_coroutine)(void *), 84 void *this, 94 85 void (*invoke)(void *) 95 86 ) { … … 117 108 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke; 118 109 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 119 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 110 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 120 111 121 112 #elif defined( __x86_64__ ) … … 137 128 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke; 138 129 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 139 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 130 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 140 131 #else 141 132 #error Only __i386__ and __x86_64__ is supported for threads in cfa -
src/libcfa/concurrency/invoke.h
r3d4b23fa r55a68c3 31 31 struct spinlock { 32 32 volatile int lock; 33 #ifdef __CFA_DEBUG__34 const char * prev_name;35 void* prev_thrd;36 #endif37 33 }; 38 34 … … 87 83 struct __thread_queue_t entry_queue; // queue of threads that are blocked waiting for the monitor 88 84 struct __condition_stack_t signal_stack; // stack of conditions to run next once we exit the monitor 85 struct monitor_desc * stack_owner; // if bulk acquiring was used we need to synchronize signals with an other monitor 89 86 unsigned int recursion; // monitor routines can be called recursively, we need to keep track of that 90 87 }; … … 102 99 #ifndef _INVOKE_PRIVATE_H_ 103 100 #define _INVOKE_PRIVATE_H_ 104 101 105 102 struct machine_context_t { 106 103 void *SP; … … 112 109 extern void CtxInvokeStub( void ); 113 110 void CtxSwitch( void * from, void * to ) asm ("CtxSwitch"); 114 115 #if defined( __x86_64__ ) 116 #define CtxGet( ctx ) __asm__ ( \ 117 "movq %%rsp,%0\n" \ 118 "movq %%rbp,%1\n" \ 119 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 120 #elif defined( __i386__ ) 121 #define CtxGet( ctx ) __asm__ ( \ 122 "movl %%esp,%0\n" \ 123 "movl %%ebp,%1\n" \ 124 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 125 #endif 111 void CtxGet( void * this ) asm ("CtxGet"); 126 112 127 113 #endif //_INVOKE_PRIVATE_H_ -
src/libcfa/concurrency/kernel
r3d4b23fa r55a68c3 28 28 //----------------------------------------------------------------------------- 29 29 // Locks 30 bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); 31 void lock ( spinlock * DEBUG_CTX_PARAM2 ); 32 void lock_yield( spinlock * DEBUG_CTX_PARAM2 ); 33 void unlock ( spinlock * ); 30 bool try_lock( spinlock * ); 31 void lock( spinlock * ); 32 void unlock( spinlock * ); 34 33 35 struct s emaphore {36 spinlock lock;37 int count;38 __thread_queue_t waiting;34 struct signal_once { 35 volatile bool cond; 36 struct spinlock lock; 37 struct __thread_queue_t blocked; 39 38 }; 40 39 41 void ?{}(semaphore * this, int count = 1); 42 void ^?{}(semaphore * this); 43 void P(semaphore * this); 44 void V(semaphore * this); 40 void ?{}(signal_once * this); 41 void ^?{}(signal_once * this); 45 42 43 void wait( signal_once * ); 44 void signal( signal_once * ); 46 45 47 46 //----------------------------------------------------------------------------- … … 69 68 unsigned short thrd_count; 70 69 }; 71 static inline void ?{}(FinishAction * this) { 70 static inline void ?{}(FinishAction * this) { 72 71 this->action_code = No_Action; 73 72 this->thrd = NULL; … … 79 78 struct processorCtx_t * runner; 80 79 cluster * cltr; 80 coroutine_desc * current_coroutine; 81 thread_desc * current_thread; 81 82 pthread_t kernel_thread; 82 83 s emaphore terminated;83 84 signal_once terminated; 84 85 volatile bool is_terminated; 85 86 … … 89 90 unsigned int preemption; 90 91 92 unsigned short disable_preempt_count; 93 91 94 bool pending_preemption; 92 93 char * last_enable;94 95 }; 95 96 -
src/libcfa/concurrency/kernel.c
r3d4b23fa r55a68c3 15 15 // 16 16 17 #include "libhdr.h" 17 #include "startup.h" 18 19 //Start and stop routine for the kernel, declared first to make sure they run first 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" 18 25 19 26 //C Includes … … 28 35 29 36 //CFA Includes 30 #include " kernel_private.h"37 #include "libhdr.h" 31 38 #include "preemption.h" 32 #include "startup.h"33 39 34 40 //Private includes … … 36 42 #include "invoke.h" 37 43 38 //Start and stop routine for the kernel, declared first to make sure they run first39 void kernel_startup(void) __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));40 void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));41 42 44 //----------------------------------------------------------------------------- 43 45 // Kernel storage 44 #define KERNEL_STORAGE(T,X) static char X## Storage[sizeof(T)]46 #define KERNEL_STORAGE(T,X) static char X##_storage[sizeof(T)] 45 47 46 48 KERNEL_STORAGE(processorCtx_t, systemProcessorCtx); … … 48 50 KERNEL_STORAGE(system_proc_t, systemProcessor); 49 51 KERNEL_STORAGE(thread_desc, mainThread); 50 KERNEL_STORAGE(machine_context_t, mainThread Ctx);52 KERNEL_STORAGE(machine_context_t, mainThread_context); 51 53 52 54 cluster * systemCluster; … … 57 59 // Global state 58 60 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; 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 } 64 70 65 71 //----------------------------------------------------------------------------- 66 72 // Main thread construction 67 73 struct current_stack_info_t { 68 machine_context_t ctx; 74 machine_context_t ctx; 69 75 unsigned int size; // size of stack 70 76 void *base; // base of stack … … 76 82 77 83 void ?{}( current_stack_info_t * this ) { 78 CtxGet( this->ctx );84 CtxGet( &this->ctx ); 79 85 this->base = this->ctx.FP; 80 86 this->storage = this->ctx.SP; … … 85 91 86 92 this->limit = (void *)(((intptr_t)this->base) - this->size); 87 this->context = &mainThread CtxStorage;93 this->context = &mainThread_context_storage; 88 94 this->top = this->base; 89 95 } … … 100 106 101 107 void ?{}( coroutine_desc * this, current_stack_info_t * info) { 102 (&this->stack){ info }; 108 (&this->stack){ info }; 103 109 this->name = "Main Thread"; 104 110 this->errno_ = 0; … … 130 136 void ?{}(processor * this, cluster * cltr) { 131 137 this->cltr = cltr; 132 (&this->terminated){ 0 }; 138 this->current_coroutine = NULL; 139 this->current_thread = NULL; 140 (&this->terminated){}; 133 141 this->is_terminated = false; 134 142 this->preemption_alarm = NULL; 135 143 this->preemption = default_preemption(); 144 this->disable_preempt_count = 1; //Start with interrupts disabled 136 145 this->pending_preemption = false; 137 146 … … 141 150 void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) { 142 151 this->cltr = cltr; 143 (&this->terminated){ 0 }; 152 this->current_coroutine = NULL; 153 this->current_thread = NULL; 154 (&this->terminated){}; 144 155 this->is_terminated = false; 145 this->preemption_alarm = NULL; 146 this->preemption = default_preemption(); 156 this->disable_preempt_count = 0; 147 157 this->pending_preemption = false; 148 this->kernel_thread = pthread_self();149 158 150 159 this->runner = runner; 151 LIB_DEBUG_PRINT_SAFE("Kernel : constructing systemprocessor context %p\n", runner);160 LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner); 152 161 runner{ this }; 153 162 } 154 155 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )156 163 157 164 void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) { … … 161 168 162 169 (&this->proc){ cltr, runner }; 163 164 verify( validate( &this->alarms ) );165 170 } 166 171 … … 169 174 LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this); 170 175 this->is_terminated = true; 171 P( &this->terminated ); 172 pthread_join( this->kernel_thread, NULL ); 176 wait( &this->terminated ); 173 177 } 174 178 } … … 180 184 181 185 void ^?{}(cluster * this) { 182 186 183 187 } 184 188 … … 199 203 200 204 thread_desc * readyThread = NULL; 201 for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ ) 205 for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ ) 202 206 { 203 207 readyThread = nextThread( this->cltr ); … … 205 209 if(readyThread) 206 210 { 207 verify( disable_preempt_count > 0 );208 209 211 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 V( &this->terminated ); 228 227 signal( &this->terminated ); 229 228 LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this); 230 229 } 231 230 232 // runThread runs a thread by context switching 233 // from the processor coroutine to the target thread 231 // runThread runs a thread by context switching 232 // from the processor coroutine to the target thread 234 233 void runThread(processor * this, thread_desc * dst) { 235 234 coroutine_desc * proc_cor = get_coroutine(this->runner); 236 235 coroutine_desc * thrd_cor = get_coroutine(dst); 237 236 238 237 //Reset the terminating actions here 239 238 this->finish.action_code = No_Action; 240 239 241 240 //Update global state 242 this _thread = dst;241 this->current_thread = dst; 243 242 244 243 // Context Switch to the thread … … 247 246 } 248 247 249 // Once a thread has finished running, some of 248 // Once a thread has finished running, some of 250 249 // its final actions must be executed from the kernel 251 250 void finishRunning(processor * this) { … … 257 256 } 258 257 else if( this->finish.action_code == Release_Schedule ) { 259 unlock( this->finish.lock ); 258 unlock( this->finish.lock ); 260 259 ScheduleThread( this->finish.thrd ); 261 260 } … … 290 289 processor * proc = (processor *) arg; 291 290 this_processor = proc; 292 this_coroutine = NULL;293 this_thread = NULL;294 disable_preempt_count = 1;295 291 // SKULLDUGGERY: We want to create a context for the processor coroutine 296 292 // which is needed for the 2-step context switch. However, there is no reason 297 // to waste the perfectly valid stack create by pthread. 293 // to waste the perfectly valid stack create by pthread. 298 294 current_stack_info_t info; 299 295 machine_context_t ctx; … … 304 300 305 301 //Set global state 306 this_coroutine = &proc->runner->__cor;307 this_thread = NULL;302 proc->current_coroutine = &proc->runner->__cor; 303 proc->current_thread = NULL; 308 304 309 305 //We now have a proper context from which to schedule threads 310 306 LIB_DEBUG_PRINT_SAFE("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx); 311 307 312 // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't 313 // resume it to start it like it normally would, it will just context switch 314 // back to here. Instead directly call the main since we already are on the 308 // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't 309 // resume it to start it like it normally would, it will just context switch 310 // back to here. Instead directly call the main since we already are on the 315 311 // appropriate stack. 316 312 proc_cor_storage.__cor.state = Active; … … 319 315 320 316 // Main routine of the core returned, the core is now fully terminated 321 LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner); 317 LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner); 322 318 323 319 return NULL; … … 326 322 void start(processor * this) { 327 323 LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this); 328 324 329 325 pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this ); 330 326 331 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this); 327 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this); 332 328 } 333 329 … … 335 331 // Scheduler routines 336 332 void ScheduleThread( thread_desc * thrd ) { 337 // if( !thrd ) return; 338 assert( thrd ); 339 assert( thrd->cor.state != Halted ); 340 341 verify( disable_preempt_count > 0 ); 333 if( !thrd ) return; 342 334 343 335 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 344 345 lock( &systemProcessor->proc.cltr->lock DEBUG_CTX2);336 337 lock( &systemProcessor->proc.cltr->lock ); 346 338 append( &systemProcessor->proc.cltr->ready_queue, thrd ); 347 339 unlock( &systemProcessor->proc.cltr->lock ); 348 349 verify( disable_preempt_count > 0 );350 340 } 351 341 352 342 thread_desc * nextThread(cluster * this) { 353 verify( disable_preempt_count > 0 ); 354 lock( &this->lock DEBUG_CTX2 ); 343 lock( &this->lock ); 355 344 thread_desc * head = pop_head( &this->ready_queue ); 356 345 unlock( &this->lock ); 357 verify( disable_preempt_count > 0 );358 346 return head; 359 347 } 360 348 361 void BlockInternal() { 362 disable_interrupts(); 363 verify( disable_preempt_count > 0 ); 349 void ScheduleInternal() { 364 350 suspend(); 365 verify( disable_preempt_count > 0 ); 366 enable_interrupts( DEBUG_CTX ); 367 } 368 369 void BlockInternal( spinlock * lock ) { 370 disable_interrupts(); 351 } 352 353 void ScheduleInternal( spinlock * lock ) { 371 354 this_processor->finish.action_code = Release; 372 355 this_processor->finish.lock = lock; 373 374 verify( disable_preempt_count > 0 );375 356 suspend(); 376 verify( disable_preempt_count > 0 ); 377 378 enable_interrupts( DEBUG_CTX ); 379 } 380 381 void BlockInternal( thread_desc * thrd ) { 382 disable_interrupts(); 383 assert( thrd->cor.state != Halted ); 357 } 358 359 void ScheduleInternal( thread_desc * thrd ) { 384 360 this_processor->finish.action_code = Schedule; 385 361 this_processor->finish.thrd = thrd; 386 387 verify( disable_preempt_count > 0 );388 362 suspend(); 389 verify( disable_preempt_count > 0 ); 390 391 enable_interrupts( DEBUG_CTX ); 392 } 393 394 void BlockInternal( spinlock * lock, thread_desc * thrd ) { 395 disable_interrupts(); 363 } 364 365 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) { 396 366 this_processor->finish.action_code = Release_Schedule; 397 367 this_processor->finish.lock = lock; 398 368 this_processor->finish.thrd = thrd; 399 400 verify( disable_preempt_count > 0 );401 369 suspend(); 402 verify( disable_preempt_count > 0 ); 403 404 enable_interrupts( DEBUG_CTX ); 405 } 406 407 void BlockInternal(spinlock ** locks, unsigned short count) { 408 disable_interrupts(); 370 } 371 372 void ScheduleInternal(spinlock ** locks, unsigned short count) { 409 373 this_processor->finish.action_code = Release_Multi; 410 374 this_processor->finish.locks = locks; 411 375 this_processor->finish.lock_count = count; 412 413 verify( disable_preempt_count > 0 );414 376 suspend(); 415 verify( disable_preempt_count > 0 ); 416 417 enable_interrupts( DEBUG_CTX ); 418 } 419 420 void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 421 disable_interrupts(); 377 } 378 379 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 422 380 this_processor->finish.action_code = Release_Multi_Schedule; 423 381 this_processor->finish.locks = locks; … … 425 383 this_processor->finish.thrds = thrds; 426 384 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 441 385 suspend(); 442 386 } … … 448 392 // Kernel boot procedures 449 393 void kernel_startup(void) { 450 LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n"); 394 LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n"); 451 395 452 396 // Start by initializing the main thread 453 // SKULLDUGGERY: the mainThread steals the process main thread 397 // SKULLDUGGERY: the mainThread steals the process main thread 454 398 // which will then be scheduled by the systemProcessor normally 455 mainThread = (thread_desc *)&mainThread Storage;399 mainThread = (thread_desc *)&mainThread_storage; 456 400 current_stack_info_t info; 457 401 mainThread{ &info }; … … 459 403 LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n"); 460 404 405 // Enable preemption 406 kernel_start_preemption(); 407 461 408 // Initialize the system cluster 462 systemCluster = (cluster *)&systemCluster Storage;409 systemCluster = (cluster *)&systemCluster_storage; 463 410 systemCluster{}; 464 411 … … 467 414 // Initialize the system processor and the system processor ctx 468 415 // (the coroutine that contains the processing control flow) 469 systemProcessor = (system_proc_t *)&systemProcessor Storage;470 systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtx Storage };471 472 // Add the main thread to the ready queue 416 systemProcessor = (system_proc_t *)&systemProcessor_storage; 417 systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtx_storage }; 418 419 // Add the main thread to the ready queue 473 420 // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread 474 421 ScheduleThread(mainThread); … … 476 423 //initialize the global state variables 477 424 this_processor = &systemProcessor->proc; 478 this_thread = mainThread; 479 this_coroutine = &mainThread->cor; 480 disable_preempt_count = 1; 481 482 // Enable preemption 483 kernel_start_preemption(); 425 this_processor->current_thread = mainThread; 426 this_processor->current_coroutine = &mainThread->cor; 484 427 485 428 // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX 486 429 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 487 // mainThread is on the ready queue when this call is made. 430 // mainThread is on the ready queue when this call is made. 488 431 resume( systemProcessor->proc.runner ); 489 432 … … 492 435 // THE SYSTEM IS NOW COMPLETELY RUNNING 493 436 LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n"); 494 495 enable_interrupts( DEBUG_CTX );496 437 } 497 438 498 439 void kernel_shutdown(void) { 499 440 LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n"); 500 501 disable_interrupts();502 441 503 442 // SKULLDUGGERY: Notify the systemProcessor it needs to terminates. … … 509 448 // THE SYSTEM IS NOW COMPLETELY STOPPED 510 449 511 // Disable preemption512 kernel_stop_preemption();513 514 450 // Destroy the system processor and its context in reverse order of construction 515 451 // These were manually constructed so we need manually destroy them … … 521 457 ^(mainThread){}; 522 458 523 LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n"); 459 LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n"); 524 460 } 525 461 … … 531 467 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 532 468 // the globalAbort flag is true. 533 lock( &kernel_abort_lock DEBUG_CTX2);469 lock( &kernel_abort_lock ); 534 470 535 471 // first task to abort ? … … 537 473 kernel_abort_called = true; 538 474 unlock( &kernel_abort_lock ); 539 } 475 } 540 476 else { 541 477 unlock( &kernel_abort_lock ); 542 478 543 479 sigset_t mask; 544 480 sigemptyset( &mask ); … … 546 482 sigaddset( &mask, SIGUSR1 ); // block SIGUSR1 signals 547 483 sigsuspend( &mask ); // block the processor to prevent further damage during abort 548 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it 549 } 550 551 return this_thread ;484 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it 485 } 486 487 return this_thread(); 552 488 } 553 489 … … 558 494 __lib_debug_write( STDERR_FILENO, abort_text, len ); 559 495 560 if ( thrd != this_coroutine ) {561 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine ->name, this_coroutine);496 if ( thrd != this_coroutine() ) { 497 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine()->name, this_coroutine() ); 562 498 __lib_debug_write( STDERR_FILENO, abort_text, len ); 563 } 499 } 564 500 else { 565 501 __lib_debug_write( STDERR_FILENO, ".\n", 2 ); … … 569 505 extern "C" { 570 506 void __lib_debug_acquire() { 571 lock( &kernel_debug_lock DEBUG_CTX2);507 lock(&kernel_debug_lock); 572 508 } 573 509 574 510 void __lib_debug_release() { 575 unlock( &kernel_debug_lock);511 unlock(&kernel_debug_lock); 576 512 } 577 513 } … … 589 525 } 590 526 591 bool try_lock( spinlock * this DEBUG_CTX_PARAM2) {527 bool try_lock( spinlock * this ) { 592 528 return this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0; 593 529 } 594 530 595 void lock( spinlock * this DEBUG_CTX_PARAM2) {531 void lock( spinlock * this ) { 596 532 for ( unsigned int i = 1;; i += 1 ) { 597 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; } 598 } 599 LIB_DEBUG_DO( 600 this->prev_name = caller; 601 this->prev_thrd = this_thread; 602 ) 603 } 604 605 void lock_yield( spinlock * this DEBUG_CTX_PARAM2 ) { 606 for ( unsigned int i = 1;; i += 1 ) { 607 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; } 608 yield(); 609 } 610 LIB_DEBUG_DO( 611 this->prev_name = caller; 612 this->prev_thrd = this_thread; 613 ) 614 } 615 533 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) break; 534 } 535 } 616 536 617 537 void unlock( spinlock * this ) { … … 619 539 } 620 540 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 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 } 652 555 unlock( &this->lock ); 653 654 // make new owner 655 WakeThread( thrd ); 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 ); 656 569 } 657 570 … … 677 590 } 678 591 head->next = NULL; 679 } 592 } 680 593 return head; 681 594 } … … 696 609 this->top = top->next; 697 610 top->next = NULL; 698 } 611 } 699 612 return top; 700 613 } -
src/libcfa/concurrency/kernel_private.h
r3d4b23fa r55a68c3 18 18 #define KERNEL_PRIVATE_H 19 19 20 #include "libhdr.h"21 22 20 #include "kernel" 23 21 #include "thread" … … 25 23 #include "alarm.h" 26 24 25 #include "libhdr.h" 27 26 28 27 //----------------------------------------------------------------------------- 29 28 // Scheduler 30 31 extern "C" {32 void disable_interrupts();33 void enable_interrupts_noRF();34 void enable_interrupts( DEBUG_CTX_PARAM );35 }36 37 29 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 }45 30 thread_desc * nextThread(cluster * this); 46 31 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); 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); 54 38 55 39 //----------------------------------------------------------------------------- … … 76 60 extern cluster * systemCluster; 77 61 extern system_proc_t * systemProcessor; 78 extern volatile thread_local processor * this_processor; 79 extern volatile thread_local coroutine_desc * this_coroutine; 80 extern volatile thread_local thread_desc * this_thread; 81 extern volatile thread_local bool preemption_in_progress; 82 extern volatile thread_local unsigned short disable_preempt_count; 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 } 83 82 84 83 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/monitor
r3d4b23fa r55a68c3 26 26 static inline void ?{}(monitor_desc * this) { 27 27 this->owner = NULL; 28 this->stack_owner = NULL; 28 29 this->recursion = 0; 29 30 } -
src/libcfa/concurrency/monitor.c
r3d4b23fa r55a68c3 19 19 #include <stdlib> 20 20 21 #include "kernel_private.h" 21 22 #include "libhdr.h" 22 #include "kernel_private.h"23 23 24 24 //----------------------------------------------------------------------------- … … 44 44 45 45 extern "C" { 46 void __enter_monitor_desc( monitor_desc * this) {47 lock _yield( &this->lock DEBUG_CTX2);48 thread_desc * thrd = this_thread ;49 50 //LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);46 void __enter_monitor_desc(monitor_desc * this) { 47 lock( &this->lock ); 48 thread_desc * thrd = this_thread(); 49 50 LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion); 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 BlockInternal( &this->lock );66 67 // BlockInternal will unlock spinlock, no need to unlock ourselves68 return; 64 LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd); 65 ScheduleInternal( &this->lock ); 66 67 //ScheduleInternal will unlock spinlock, no need to unlock ourselves 68 return; 69 69 } 70 70 … … 75 75 // leave pseudo code : 76 76 // TODO 77 void __leave_monitor_desc( monitor_desc * this) {78 lock _yield( &this->lock DEBUG_CTX2);79 80 // LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i). ", this_thread, this, this->owner, this->recursion);81 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion );77 void __leave_monitor_desc(monitor_desc * this) { 78 lock( &this->lock ); 79 80 LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion); 81 verifyf( this_thread() == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread(), this->owner, this->recursion ); 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 WakeThread( new_owner ); 102 } 103 104 void __leave_thread_monitor( thread_desc * thrd ) { 105 monitor_desc * this = &thrd->mon; 106 lock_yield( &this->lock DEBUG_CTX2 ); 107 108 disable_interrupts(); 109 110 thrd->cor.state = Halted; 111 112 verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion ); 113 114 //Leaving a recursion level, decrement the counter 115 this->recursion -= 1; 116 117 //If we haven't left the last level of recursion 118 //it means we don't need to do anything 119 if( this->recursion != 0) { 120 unlock( &this->lock ); 121 return; 122 } 123 124 thread_desc * new_owner = next_thread( this ); 125 126 LeaveThread( &this->lock, new_owner ); 101 ScheduleThread( new_owner ); 127 102 } 128 103 } … … 146 121 enter( this->m, this->count ); 147 122 148 this->prev_mntrs = this_thread ->current_monitors;149 this->prev_count = this_thread ->current_monitor_count;150 151 this_thread ->current_monitors = m;152 this_thread ->current_monitor_count = count;123 this->prev_mntrs = this_thread()->current_monitors; 124 this->prev_count = this_thread()->current_monitor_count; 125 126 this_thread()->current_monitors = m; 127 this_thread()->current_monitor_count = count; 153 128 } 154 129 … … 156 131 leave( this->m, this->count ); 157 132 158 this_thread ->current_monitors = this->prev_mntrs;159 this_thread ->current_monitor_count = this->prev_count;133 this_thread()->current_monitors = this->prev_mntrs; 134 this_thread()->current_monitor_count = this->prev_count; 160 135 } 161 136 … … 184 159 // Internal scheduling 185 160 void wait( condition * this, uintptr_t user_info = 0 ) { 186 //LIB_DEBUG_PRINT_SAFE("Waiting\n");161 LIB_DEBUG_PRINT_SAFE("Waiting\n"); 187 162 188 163 brand_condition( this ); … … 195 170 unsigned short count = this->monitor_count; 196 171 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 197 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal198 199 //LIB_DEBUG_PRINT_SAFE("count %i\n", count);200 201 __condition_node_t waiter = { (thread_desc*)this_thread, count, user_info };172 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal 173 174 LIB_DEBUG_PRINT_SAFE("count %i\n", count); 175 176 __condition_node_t waiter = { this_thread(), count, user_info }; 202 177 203 178 __condition_criterion_t criteria[count]; 204 179 for(int i = 0; i < count; i++) { 205 180 (&criteria[i]){ this->monitors[i], &waiter }; 206 //LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );181 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 207 182 } 208 183 … … 226 201 } 227 202 228 //LIB_DEBUG_PRINT_SAFE("Will unblock: ");203 LIB_DEBUG_PRINT_SAFE("Will unblock: "); 229 204 for(int i = 0; i < thread_count; i++) { 230 //LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);231 } 232 //LIB_DEBUG_PRINT_SAFE("\n");205 LIB_DEBUG_PRINT_SAFE("%p ", threads[i]); 206 } 207 LIB_DEBUG_PRINT_SAFE("\n"); 233 208 234 209 // Everything is ready to go to sleep 235 BlockInternal( locks, count, threads, thread_count );210 ScheduleInternal( locks, count, threads, thread_count ); 236 211 237 212 … … 247 222 bool signal( condition * this ) { 248 223 if( is_empty( this ) ) { 249 //LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");224 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 250 225 return false; 251 226 } … … 256 231 257 232 unsigned short count = this->monitor_count; 258 233 259 234 //Some more checking in debug 260 235 LIB_DEBUG_DO( 261 thread_desc * this_thrd = this_thread ;236 thread_desc * this_thrd = this_thread(); 262 237 if ( this->monitor_count != this_thrd->current_monitor_count ) { 263 238 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 ); … … 273 248 //Lock all the monitors 274 249 lock_all( this->monitors, NULL, count ); 275 //LIB_DEBUG_PRINT_SAFE("Signalling");250 LIB_DEBUG_PRINT_SAFE("Signalling"); 276 251 277 252 //Pop the head of the waiting queue … … 281 256 for(int i = 0; i < count; i++) { 282 257 __condition_criterion_t * crit = &node->criteria[i]; 283 //LIB_DEBUG_PRINT_SAFE(" %p", crit->target);258 LIB_DEBUG_PRINT_SAFE(" %p", crit->target); 284 259 assert( !crit->ready ); 285 260 push( &crit->target->signal_stack, crit ); 286 261 } 287 262 288 //LIB_DEBUG_PRINT_SAFE("\n");263 LIB_DEBUG_PRINT_SAFE("\n"); 289 264 290 265 //Release … … 306 281 unsigned short count = this->monitor_count; 307 282 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 308 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal283 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal 309 284 310 285 lock_all( this->monitors, locks, count ); 311 286 312 287 //create creteria 313 __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };288 __condition_node_t waiter = { this_thread(), count, 0 }; 314 289 315 290 __condition_criterion_t criteria[count]; 316 291 for(int i = 0; i < count; i++) { 317 292 (&criteria[i]){ this->monitors[i], &waiter }; 318 //LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );293 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 319 294 push( &criteria[i].target->signal_stack, &criteria[i] ); 320 295 } … … 334 309 335 310 //Everything is ready to go to sleep 336 BlockInternal( locks, count, &signallee, 1 );311 ScheduleInternal( locks, count, &signallee, 1 ); 337 312 338 313 … … 350 325 351 326 uintptr_t front( condition * this ) { 352 verifyf( !is_empty(this), 327 verifyf( !is_empty(this), 353 328 "Attempt to access user data on an empty condition.\n" 354 329 "Possible cause is not checking if the condition is empty before reading stored data." … … 360 335 // Internal scheduling 361 336 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) { 362 // thread_desc * this = this_thread ;337 // thread_desc * this = this_thread(); 363 338 364 339 // unsigned short count = this->current_monitor_count; 365 340 // unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 366 // spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal341 // spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal 367 342 368 343 // lock_all( this->current_monitors, locks, count ); … … 373 348 374 349 // // // Everything is ready to go to sleep 375 // // BlockInternal( locks, count, threads, thread_count );350 // // ScheduleInternal( locks, count, threads, thread_count ); 376 351 377 352 … … 418 393 static inline void lock_all( spinlock ** locks, unsigned short count ) { 419 394 for( int i = 0; i < count; i++ ) { 420 lock _yield( locks[i] DEBUG_CTX2);395 lock( locks[i] ); 421 396 } 422 397 } … … 425 400 for( int i = 0; i < count; i++ ) { 426 401 spinlock * l = &source[i]->lock; 427 lock _yield( l DEBUG_CTX2);402 lock( l ); 428 403 if(locks) locks[i] = l; 429 404 } … … 468 443 for( int i = 0; i < count; i++ ) { 469 444 470 //LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );445 LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target ); 471 446 if( &criteria[i] == target ) { 472 447 criteria[i].ready = true; 473 //LIB_DEBUG_PRINT_SAFE( "True\n" );448 LIB_DEBUG_PRINT_SAFE( "True\n" ); 474 449 } 475 450 … … 477 452 } 478 453 479 //LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );454 LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run ); 480 455 return ready2run ? node->waiting_thread : NULL; 481 456 } 482 457 483 458 static inline void brand_condition( condition * this ) { 484 thread_desc * thrd = this_thread ;459 thread_desc * thrd = this_thread(); 485 460 if( !this->monitors ) { 486 //LIB_DEBUG_PRINT_SAFE("Branding\n");461 LIB_DEBUG_PRINT_SAFE("Branding\n"); 487 462 assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors ); 488 463 this->monitor_count = thrd->current_monitor_count; -
src/libcfa/concurrency/preemption.c
r3d4b23fa r55a68c3 15 15 // 16 16 17 #include "libhdr.h"18 17 #include "preemption.h" 19 18 20 19 extern "C" { 21 #include <errno.h>22 #include <execinfo.h>23 #define __USE_GNU24 20 #include <signal.h> 25 #undef __USE_GNU26 #include <stdio.h>27 #include <string.h>28 #include <unistd.h>29 21 } 30 22 31 32 #ifdef __USE_STREAM__ 33 #include "fstream" 34 #endif 35 36 #define __CFA_DEFAULT_PREEMPTION__ 10000 23 #define __CFA_DEFAULT_PREEMPTION__ 10 37 24 38 25 __attribute__((weak)) unsigned int default_preemption() { … … 40 27 } 41 28 42 #define __CFA_SIGCXT__ ucontext_t *43 #define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt44 45 29 static void preempt( processor * this ); 46 30 static void timeout( thread_desc * this ); 47 48 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );49 void sigHandler_alarm ( __CFA_SIGPARMS__ );50 void sigHandler_segv ( __CFA_SIGPARMS__ );51 void sigHandler_abort ( __CFA_SIGPARMS__ );52 53 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );54 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )55 56 #ifdef __x86_64__57 #define CFA_REG_IP REG_RIP58 #else59 #define CFA_REG_IP REG_EIP60 #endif61 62 31 63 32 //============================================================================================= … … 65 34 //============================================================================================= 66 35 36 void kernel_start_preemption() { 37 38 } 39 67 40 void tick_preemption() { 68 // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Ticking preemption\n" );69 70 41 alarm_list_t * alarms = &systemProcessor->alarms; 71 42 __cfa_time_t currtime = __kernel_get_time(); 72 43 while( alarms->head && alarms->head->alarm < currtime ) { 73 44 alarm_node_t * node = pop(alarms); 74 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking %p\n", node );75 76 45 if( node->kernel_alarm ) { 77 46 preempt( node->proc ); … … 81 50 } 82 51 83 verify( validate( alarms ) );84 85 52 if( node->period > 0 ) { 86 node->alarm = currtime +node->period;53 node->alarm += node->period; 87 54 insert( alarms, node ); 88 55 } … … 95 62 __kernel_set_timer( alarms->head->alarm - currtime ); 96 63 } 97 98 verify( validate( alarms ) );99 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking preemption done\n" );100 64 } 101 65 102 66 void update_preemption( processor * this, __cfa_time_t duration ) { 103 LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Processor : %p updating preemption to %lu\n", this, duration ); 104 67 // assert( THREAD_GETMEM( disableInt ) && THREAD_GETMEM( disableIntCnt ) == 1 ); 105 68 alarm_node_t * alarm = this->preemption_alarm; 106 duration *= 1000;107 69 108 70 // Alarms need to be enabled … … 127 89 } 128 90 91 void ?{}( preemption_scope * this, processor * proc ) { 92 (&this->alarm){ proc }; 93 this->proc = proc; 94 this->proc->preemption_alarm = &this->alarm; 95 update_preemption( this->proc, this->proc->preemption ); 96 } 97 98 void ^?{}( preemption_scope * this ) { 99 update_preemption( this->proc, 0 ); 100 } 101 129 102 //============================================================================================= 130 // Kernel Signal Tools103 // Kernel Signal logic 131 104 //============================================================================================= 132 105 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 106 static inline bool preemption_ready() { 182 return disable_preempt_count == 0 && !preemption_in_progress;107 return this_processor->disable_preempt_count == 0; 183 108 } 184 109 … … 191 116 } 192 117 118 void sigHandler_ctxSwitch( __attribute__((unused)) int sig ) { 119 if( preemption_ready() ) { 120 ScheduleInternal( this_processor->current_thread ); 121 } 122 else { 123 defer_ctxSwitch(); 124 } 125 } 126 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 193 137 static void preempt( processor * this ) { 194 138 pthread_kill( this->kernel_thread, SIGUSR1 ); … … 198 142 //TODO : implement waking threads 199 143 } 200 201 //=============================================================================================202 // Kernel Signal Startup/Shutdown logic203 //=============================================================================================204 205 static pthread_t alarm_thread;206 void * alarm_loop( __attribute__((unused)) void * args );207 208 void kernel_start_preemption() {209 LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n");210 __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO );211 // __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO );212 // __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO );213 214 signal_block( SIGALRM );215 216 pthread_create( &alarm_thread, NULL, alarm_loop, NULL );217 }218 219 void kernel_stop_preemption() {220 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopping\n");221 222 sigset_t mask;223 sigfillset( &mask );224 sigprocmask( SIG_BLOCK, &mask, NULL );225 226 sigval val = { 1 };227 pthread_sigqueue( alarm_thread, SIGALRM, val );228 pthread_join( alarm_thread, NULL );229 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n");230 }231 232 void ?{}( preemption_scope * this, processor * proc ) {233 (&this->alarm){ proc };234 this->proc = proc;235 this->proc->preemption_alarm = &this->alarm;236 update_preemption( this->proc, this->proc->preemption );237 }238 239 void ^?{}( preemption_scope * this ) {240 disable_interrupts();241 242 update_preemption( this->proc, 0 );243 }244 245 //=============================================================================================246 // Kernel Signal Handlers247 //=============================================================================================248 249 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {250 LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); )251 if( preemption_ready() ) {252 preemption_in_progress = true;253 signal_unblock( SIGUSR1 );254 this_processor->pending_preemption = false;255 preemption_in_progress = false;256 BlockInternal( (thread_desc*)this_thread );257 }258 else {259 defer_ctxSwitch();260 }261 }262 263 void * alarm_loop( __attribute__((unused)) void * args ) {264 sigset_t mask;265 sigemptyset( &mask );266 sigaddset( &mask, SIGALRM );267 268 if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {269 abortf( "internal error, pthread_sigmask" );270 }271 272 while( true ) {273 siginfo_t info;274 int sig = sigwaitinfo( &mask, &info );275 if( sig < 0 ) {276 abortf( "internal error, sigwait" );277 }278 else if( sig == SIGALRM )279 {280 LIB_DEBUG_PRINT_SAFE("Kernel : Caught signal %d (%d)\n", sig, info.si_value.sival_int );281 if( info.si_value.sival_int == 0 )282 {283 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");284 lock( &systemProcessor->alarm_lock DEBUG_CTX2 );285 tick_preemption();286 unlock( &systemProcessor->alarm_lock );287 }288 else if( info.si_value.sival_int == 1 )289 {290 break;291 }292 }293 else294 {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 logic338 //=============================================================================================339 340 LIB_DEBUG_DO(341 static void __kernel_backtrace( int start ) {342 // skip first N stack frames343 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 name350 *index( messages[0], '(' ) = '\0';351 #ifdef __USE_STREAM__352 serr | "Stack back trace for:" | messages[0] | endl;353 #else354 fprintf( stderr, "Stack back trace for: %s\n", messages[0]);355 #endif356 357 // skip last 2 stack frames after main358 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 +offset365 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 it378 int frameNo = i - start;379 if ( name && offset_begin && offset_end && name < offset_begin ) {380 // delimit strings381 *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 #else389 fprintf( stderr, "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end);390 #endif391 }392 // otherwise, print the whole line393 else {394 #ifdef __USE_STREAM__395 serr | "(" | frameNo | ")" | messages[i] | endl;396 #else397 fprintf( stderr, "(%i) %s\n", frameNo, messages[i] );398 #endif399 }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 // #else413 // fprintf( stderr, "*CFA runtime error* program cfa-cpp terminated with %s\n", sig == SIGSEGV ? "segment fault." : "bus error." );414 // #endif415 416 // // skip first 2 stack frames417 // __kernel_backtrace( 1 );418 // )419 // exit( EXIT_FAILURE );420 // }421 422 // void sigHandler_abort( __CFA_SIGPARMS__ ) {423 // // skip first 6 stack frames424 // LIB_DEBUG_DO( __kernel_backtrace( 6 ); )425 426 // // reset default signal handler427 // __kernel_sigdefault( SIGABRT );428 429 // raise( SIGABRT );430 // } -
src/libcfa/concurrency/thread
r3d4b23fa r55a68c3 54 54 } 55 55 56 extern volatile thread_local thread_desc * this_thread;56 thread_desc * this_thread(void); 57 57 58 58 forall( dtype T | is_thread(T) ) -
src/libcfa/concurrency/thread.c
r3d4b23fa r55a68c3 28 28 } 29 29 30 extern volatilethread_local processor * this_processor;30 extern 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; 73 thrd_c->last = this_coroutine(); 74 this_processor->current_coroutine = thrd_c; 74 75 75 //LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);76 LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h); 76 77 77 disable_interrupts();78 78 create_stack(&thrd_c->stack, thrd_c->stack.size); 79 this_coroutine = thrd_c;80 79 CtxStart(this, CtxInvokeThread); 81 assert( thrd_c->last->stack.context );82 80 CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context ); 83 81 84 82 ScheduleThread(thrd_h); 85 enable_interrupts( DEBUG_CTX );86 83 } 87 84 88 85 void yield( void ) { 89 BlockInternal( (thread_desc *)this_thread );86 ScheduleInternal( this_processor->current_thread ); 90 87 } 91 88 … … 98 95 void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) { 99 96 // set state of current coroutine to inactive 100 src->state = src->state == Halted ? Halted :Inactive;97 src->state = Inactive; 101 98 dst->state = Active; 102 99 … … 106 103 // set new coroutine that the processor is executing 107 104 // and context switch to it 108 this_coroutine = dst; 109 assert( src->stack.context ); 105 this_processor->current_coroutine = dst; 110 106 CtxSwitch( src->stack.context, dst->stack.context ); 111 this_ coroutine = src;107 this_processor->current_coroutine = src; 112 108 113 109 // set state of new coroutine to active 114 dst->state = dst->state == Halted ? Halted :Inactive;110 dst->state = Inactive; 115 111 src->state = Active; 116 112 } -
src/libcfa/exception.c
r3d4b23fa r55a68c3 10 10 // Created On : Mon Jun 26 15:13:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus Jul 11 16:36:00 201713 // Update Count : 112 // Last Modified On : Mon Nov 26 15:11:00 2017 13 // Update Count : 0 14 14 // 15 15 … … 44 44 // RESUMPTION ================================================================ 45 45 46 void __cfaehm__throw_resum e(exception * except) {46 void __cfaehm__throw_resumption(exception * except) { 47 47 48 48 // DEBUG … … 65 65 66 66 // Fall back to termination: 67 __cfaehm__throw_terminat e(except);67 __cfaehm__throw_termination(except); 68 68 // TODO: Default handler for resumption. 69 69 } … … 111 111 } 112 112 113 void __cfaehm__throw_terminat e( exception * val ) {113 void __cfaehm__throw_termination( 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 e(void) {149 void __cfaehm__rethrow_termination(void) { 150 150 // DEBUG 151 151 printf("Rethrowing termination exception\n"); 152 152 153 __cfaehm__throw_terminat e(&shared_stack.current_exception);153 __cfaehm__throw_termination(&shared_stack.current_exception); 154 154 } 155 155 -
src/libcfa/exception.h
r3d4b23fa r55a68c3 10 10 // Created On : Mon Jun 26 15:11:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus Jul 11 16:31:00 201713 // Update Count : 212 // Last Modified On : Mon Nov 26 15:11:00 2017 13 // Update Count : 0 14 14 // 15 15 … … 22 22 23 23 #ifdef __CFORALL__ 24 extern " C" {24 extern "BuiltinC" { 25 25 #endif 26 26 27 27 // Used in throw statement translation. 28 void __cfaehm__throw_terminat e(exception * except) __attribute__((noreturn));29 void __cfaehm__rethrow_terminat e() __attribute__((noreturn));30 void __cfaehm__throw_resum e(exception * except);28 void __cfaehm__throw_termination(exception * except) __attribute__((noreturn)); 29 void __cfaehm__rethrow_termination() __attribute__((noreturn)); 30 void __cfaehm__throw_resumption(exception * except); 31 31 32 32 // Function catches termination exceptions. -
src/libcfa/fstream
r3d4b23fa r55a68c3 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 7 08:32:38201713 // Update Count : 11 712 // Last Modified On : Sat Jul 1 16:37:53 2017 13 // Update Count : 112 14 14 // 15 15 16 #pragma once 16 #ifndef __FSTREAM_H__ 17 #define __FSTREAM_H__ 17 18 18 19 #include "iostream" 19 20 20 enum { sep Size = 16 };21 enum { separateSize = 16 }; 21 22 struct ofstream { 22 23 void * file; 23 24 _Bool sepDefault; 24 25 _Bool sepOnOff; 25 _Bool sawNL;26 _Bool lastSepOn; 26 27 const char * sepCur; 27 char separator[sep Size];28 char tupleSeparator[sep Size];28 char separator[separateSize]; 29 char tupleSeparator[separateSize]; 29 30 }; // ofstream 30 31 … … 35 36 const char * sepGetCur( ofstream * ); 36 37 void sepSetCur( ofstream *, const char * ); 37 _Bool getNL( ofstream * ); 38 void setNL( ofstream *, _Bool ); 38 _Bool lastSepOn( ofstream * ); 39 39 40 40 // public … … 75 75 extern ifstream * sin; 76 76 77 #endif // __FSTREAM_H__ 78 77 79 // Local Variables: // 78 80 // mode: c // -
src/libcfa/fstream.c
r3d4b23fa r55a68c3 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 6 18:38:25201713 // Update Count : 2 5112 // Last Modified On : Sat Jul 1 16:37:54 2017 13 // Update Count : 242 14 14 // 15 15 … … 33 33 this->sepDefault = sepDefault; 34 34 this->sepOnOff = sepOnOff; 35 this->lastSepOn = false; 35 36 sepSet( this, separator ); 36 37 sepSetCur( this, sepGet( this ) ); … … 39 40 40 41 // private 41 _Bool sepPrt( ofstream * os ) { setNL( os, false ); return os->sepOnOff; } 42 _Bool lastSepOn( ofstream * os ) { return os->lastSepOn; } 43 _Bool sepPrt( ofstream * os ) { os->lastSepOn = false; return os->sepOnOff; } 42 44 void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; } 43 45 void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; } 44 46 const char * sepGetCur( ofstream * os ) { return os->sepCur; } 45 47 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-> sepOnOff = ! getNL( os ); }51 void sepOff( ofstream * os ) { os-> sepOnOff = false; }50 void sepOn( ofstream * os ) { os->lastSepOn = true; os->sepOnOff = true; } 51 void sepOff( ofstream * os ) { os->lastSepOn = false; os->sepOnOff = 0; } 52 52 53 53 _Bool sepDisable( ofstream *os ) { 54 54 _Bool temp = os->sepDefault; 55 55 os->sepDefault = false; 56 os->lastSepOn = false; 56 57 sepReset( os ); 57 58 return temp; … … 68 69 void sepSet( ofstream * os, const char * s ) { 69 70 assert( s ); 70 strncpy( os->separator, s, sep Size - 1 );71 os->separator[sep Size - 1] = '\0';71 strncpy( os->separator, s, separateSize - 1 ); 72 os->separator[separateSize - 1] = '\0'; 72 73 } // sepSet 73 74 … … 75 76 void sepSetTuple( ofstream * os, const char * s ) { 76 77 assert( s ); 77 strncpy( os->tupleSeparator, s, sep Size - 1 );78 os->tupleSeparator[sep Size - 1] = '\0';78 strncpy( os->tupleSeparator, s, separateSize - 1 ); 79 os->tupleSeparator[separateSize - 1] = '\0'; 79 80 } // sepSet 80 81 … … 152 153 153 154 void open( ifstream * is, const char * name, const char * mode ) { 154 FILE * file= fopen( name, mode );155 if ( file == 0 ) {// do not change unless successful155 FILE *t = fopen( name, mode ); 156 if ( t == 0 ) { // do not change unless successful 156 157 fprintf( stderr, IO_MSG "open input file \"%s\", ", name ); 157 158 perror( 0 ); 158 159 exit( EXIT_FAILURE ); 159 160 } // if 160 is->file = file;161 is->file = t; 161 162 } // open 162 163 -
src/libcfa/gmp
r3d4b23fa r55a68c3 10 10 // Created On : Tue Apr 19 08:43:43 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 7 09:33:20201713 // Update Count : 1 512 // Last Modified On : Sat May 27 09:55:51 2017 13 // Update Count : 14 14 14 // 15 15 16 16 // https://gmplib.org/gmp-man-6.1.1.pdf 17 18 #pragma once19 17 20 18 #include <gmp.h> // GNU multi-precise integers -
src/libcfa/iostream
r3d4b23fa r55a68c3 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 7 08:35:59201713 // Update Count : 11 812 // Last Modified On : Sun Jul 2 08:42:56 2017 13 // Update Count : 110 14 14 // 15 15 16 #pragma once 16 #ifndef __IOSTREAM_H__ 17 #define __IOSTREAM_H__ 17 18 18 19 #include "iterator" … … 25 26 const char * sepGetCur( ostype * ); // get current separator string 26 27 void sepSetCur( ostype *, const char * ); // set current separator string 27 _Bool getNL( ostype * ); // check newline 28 void setNL( ostype *, _Bool ); // saw newline 28 _Bool lastSepOn( ostype * ); // last manipulator is setOn (context sensitive) 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 * );86 84 forall( dtype ostype | ostream( ostype ) ) ostype * sepOn( ostype * ); 87 85 forall( dtype ostype | ostream( ostype ) ) ostype * sepOff( ostype * ); … … 139 137 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_cstrC ); 140 138 139 #endif // __IOSTREAM_H 140 141 141 // Local Variables: // 142 142 // mode: c // -
src/libcfa/iostream.c
r3d4b23fa r55a68c3 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 6 18:14:17201713 // Update Count : 3 9612 // Last Modified On : Sun Jul 2 08:54:02 2017 13 // Update Count : 375 14 14 // 15 15 … … 18 18 extern "C" { 19 19 #include <stdio.h> 20 #include <stdbool.h> // true/false21 20 #include <string.h> // strlen 22 21 #include <float.h> // DBL_DIG, LDBL_DIG … … 25 24 26 25 forall( dtype ostype | ostream( ostype ) ) 27 ostype * ?|?( ostype * os, char ch ) { 28 fmt( os, "%c", ch ); 29 if ( ch == '\n' ) setNL( os, true ); 26 ostype * ?|?( ostype * os, char c ) { 27 fmt( os, "%c", c ); 30 28 sepOff( os ); 31 29 return os; … … 182 180 183 181 // last character IS spacing or opening punctuation => turn off separator for next item 184 size_t len = strlen( cp );185 ch = cp[ len - 1];// must make unsigned182 unsigned int len = strlen( cp ), posn = len - 1; 183 ch = cp[posn]; // must make unsigned 186 184 if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) { 187 185 sepOn( os ); … … 189 187 sepOff( os ); 190 188 } // if 191 if ( ch == '\n' ) setNL( os, true ); // check *AFTER* sepPrt call above as it resets NL flag192 189 return write( os, cp, len ); 193 190 } // ?|? … … 219 216 220 217 forall( dtype ostype | ostream( ostype ) ) 221 ostype * sep( ostype * os ) {222 os | sepGet( os );223 return os;224 } // sep225 226 forall( dtype ostype | ostream( ostype ) )227 ostype * sepTuple( ostype * os ) {228 os | sepGetTuple( os );229 return os;230 } // sepTuple231 232 forall( dtype ostype | ostream( ostype ) )233 218 ostype * endl( ostype * os ) { 219 if ( lastSepOn( os ) ) fmt( os, "%s", sepGetCur( os ) ); 234 220 os | '\n'; 235 setNL( os, true );236 221 flush( os ); 237 222 sepOff( os ); // prepare for next line -
src/libcfa/iterator
r3d4b23fa r55a68c3 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 7 08:37:25 201713 // Update Count : 1012 // Last Modified On : Wed Mar 2 18:06:05 2016 13 // Update Count : 9 14 14 // 15 15 16 #pragma once 16 #ifndef ITERATOR_H 17 #define ITERATOR_H 17 18 18 19 // An iterator can be used to traverse a data structure. … … 38 39 39 40 forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) ) 40 void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) );41 void for_each( iterator_type begin, iterator_type end, void (*func)( elt_type ) ); 41 42 42 43 forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) ) 43 void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) ); 44 void for_each_reverse( iterator_type begin, iterator_type end, void (*func)( elt_type ) ); 45 46 #endif // ITERATOR_H 44 47 45 48 // Local Variables: // -
src/libcfa/iterator.c
r3d4b23fa r55a68c3 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 7 08:38:23 201713 // Update Count : 2 812 // Last Modified On : Wed Mar 2 18:08:11 2016 13 // Update Count : 27 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 } // for23 } // for_each22 } 23 } 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 } // for31 } // for_each_reverse30 } 31 } 32 32 33 33 // Local Variables: // -
src/libcfa/libhdr/libalign.h
r3d4b23fa r55a68c3 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>36 35 37 // Minimum size used to align memory boundaries for memory allocations. 36 // Minimum size used to align memory boundaries for memory allocations. 38 37 #define libAlign() (sizeof(double)) 39 38 -
src/libcfa/libhdr/libdebug.h
r3d4b23fa r55a68c3 18 18 19 19 #ifdef __CFA_DEBUG__ 20 #define LIB_DEBUG_DO(...) __VA_ARGS__ 21 #define LIB_NO_DEBUG_DO(...) 22 #define DEBUG_CTX __PRETTY_FUNCTION__ 23 #define DEBUG_CTX2 , __PRETTY_FUNCTION__ 24 #define DEBUG_CTX_PARAM const char * caller 25 #define DEBUG_CTX_PARAM2 , const char * caller 20 #define LIB_DEBUG_DO(x) x 21 #define LIB_NO_DEBUG_DO(x) ((void)0) 26 22 #else 27 #define LIB_DEBUG_DO(...) 28 #define LIB_NO_DEBUG_DO(...) __VA_ARGS__ 29 #define DEBUG_CTX 30 #define DEBUG_CTX2 31 #define DEBUG_CTX_PARAM 32 #define DEBUG_CTX_PARAM2 23 #define LIB_DEBUG_DO(x) ((void)0) 24 #define LIB_NO_DEBUG_DO(x) x 33 25 #endif 34 26 … … 59 51 60 52 #ifdef __CFA_DEBUG_PRINT__ 61 #define LIB_DEBUG_WRITE( fd, buffer, len ) __lib_debug_write( fd, buffer, len ) 62 #define LIB_DEBUG_ACQUIRE() __lib_debug_acquire() 63 #define LIB_DEBUG_RELEASE() __lib_debug_release() 64 #define LIB_DEBUG_PRINT_SAFE(...) __lib_debug_print_safe (__VA_ARGS__) 65 #define LIB_DEBUG_PRINT_NOLOCK(...) __lib_debug_print_nolock (__VA_ARGS__) 66 #define LIB_DEBUG_PRINT_BUFFER(...) __lib_debug_print_buffer (__VA_ARGS__) 67 #define LIB_DEBUG_PRINT_BUFFER_DECL(fd, ...) char text[256]; int len = snprintf( text, 256, __VA_ARGS__ ); __lib_debug_write( fd, text, len ); 68 #define LIB_DEBUG_PRINT_BUFFER_LOCAL(fd, ...) len = snprintf( text, 256, __VA_ARGS__ ); __lib_debug_write( fd, text, len ); 53 #define LIB_DEBUG_WRITE( fd, buffer, len ) __lib_debug_write( fd, buffer, len ) 54 #define LIB_DEBUG_ACQUIRE() __lib_debug_acquire() 55 #define LIB_DEBUG_RELEASE() __lib_debug_release() 56 #define LIB_DEBUG_PRINT_SAFE(...) __lib_debug_print_safe (__VA_ARGS__) 57 #define LIB_DEBUG_PRINT_NOLOCK(...) __lib_debug_print_nolock (__VA_ARGS__) 58 #define LIB_DEBUG_PRINT_BUFFER(...) __lib_debug_print_buffer (__VA_ARGS__) 69 59 #else 70 #define LIB_DEBUG_WRITE(...) ((void)0) 71 #define LIB_DEBUG_ACQUIRE() ((void)0) 72 #define LIB_DEBUG_RELEASE() ((void)0) 73 #define LIB_DEBUG_PRINT_SAFE(...) ((void)0) 74 #define LIB_DEBUG_PRINT_NOLOCK(...) ((void)0) 75 #define LIB_DEBUG_PRINT_BUFFER(...) ((void)0) 76 #define LIB_DEBUG_PRINT_BUFFER_DECL(...) ((void)0) 77 #define LIB_DEBUG_PRINT_BUFFER_LOCAL(...) ((void)0) 60 #define LIB_DEBUG_WRITE(...) ((void)0) 61 #define LIB_DEBUG_ACQUIRE() ((void)0) 62 #define LIB_DEBUG_RELEASE() ((void)0) 63 #define LIB_DEBUG_PRINT_SAFE(...) ((void)0) 64 #define LIB_DEBUG_PRINT_NOLOCK(...) ((void)0) 65 #define LIB_DEBUG_PRINT_BUFFER(...) ((void)0) 78 66 #endif 79 67 -
src/libcfa/limits
r3d4b23fa r55a68c3 10 10 // Created On : Wed Apr 6 18:06:52 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 7 09:33:57 201713 // Update Count : 712 // Last Modified On : Wed Apr 6 21:08:16 2016 13 // Update Count : 6 14 14 // 15 15 16 #pragma once 16 #ifndef LIMITS_H 17 #define LIMITS_H 17 18 18 19 // Integral Constants … … 109 110 extern const long _Complex _1_SQRT_2; // 1 / sqrt(2) 110 111 112 #endif // LIMITS_H 113 111 114 // Local Variables: // 112 115 // mode: c // -
src/libcfa/math
r3d4b23fa r55a68c3 10 10 // Created On : Mon Apr 18 23:37:04 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 7 09:34:15 2017 13 // Update Count : 61 14 // 15 16 #pragma once 12 // Last Modified On : Wed May 24 17:40:39 2017 13 // Update Count : 60 14 // 15 16 #ifndef MATH_H 17 #define MATH_H 17 18 18 19 extern "C" { … … 344 345 long double scalbln( long double, long int ); 345 346 347 #endif // MATH_H 348 346 349 // Local Variables: // 347 350 // mode: c // -
src/libcfa/rational
r3d4b23fa r55a68c3 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Fri Jul 7 09:34:33201715 // Update Count : 9 314 // Last Modified On : Mon May 15 21:30:12 2017 15 // Update Count : 90 16 16 // 17 17 18 #pragma once 18 #ifndef RATIONAL_H 19 #define RATIONAL_H 19 20 20 21 #include "iostream" … … 46 47 // implementation 47 48 48 forall ( otype RationalImpl | arithmetic( RationalImpl ) )49 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 49 50 struct Rational { 50 51 RationalImpl numerator, denominator; // invariant: denominator > 0 … … 53 54 // constructors 54 55 55 forall ( otype RationalImpl | arithmetic( RationalImpl ) )56 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 56 57 void ?{}( Rational(RationalImpl) * r ); 57 58 58 forall ( otype RationalImpl | arithmetic( RationalImpl ) )59 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 59 60 void ?{}( Rational(RationalImpl) * r, RationalImpl n ); 60 61 61 forall ( otype RationalImpl | arithmetic( RationalImpl ) )62 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 62 63 void ?{}( Rational(RationalImpl) * r, RationalImpl n, RationalImpl d ); 63 64 64 forall ( otype RationalImpl | arithmetic( RationalImpl ) )65 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 65 66 void ?{}( Rational(RationalImpl) * r, zero_t ); 66 67 67 forall ( otype RationalImpl | arithmetic( RationalImpl ) )68 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 68 69 void ?{}( Rational(RationalImpl) * r, one_t ); 69 70 70 // numerator/denominator getter71 // getter for numerator/denominator 71 72 72 forall ( otype RationalImpl | arithmetic( RationalImpl ) )73 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 73 74 RationalImpl numerator( Rational(RationalImpl) r ); 74 75 75 forall ( otype RationalImpl | arithmetic( RationalImpl ) )76 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 76 77 RationalImpl denominator( Rational(RationalImpl) r ); 77 78 forall( otype RationalImpl | arithmetic( RationalImpl ) ) 78 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 79 79 [ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ); 80 80 81 // numerator/denominator setter81 // setter for numerator/denominator 82 82 83 forall ( otype RationalImpl | arithmetic( RationalImpl ) )83 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 84 84 RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ); 85 85 86 forall ( otype RationalImpl | arithmetic( RationalImpl ) )86 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 87 87 RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ); 88 88 89 89 // comparison 90 90 91 forall ( otype RationalImpl | arithmetic( RationalImpl ) )91 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 92 92 int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 93 93 94 forall ( otype RationalImpl | arithmetic( RationalImpl ) )94 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 95 95 int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 96 96 97 forall ( otype RationalImpl | arithmetic( RationalImpl ) )97 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 98 98 int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 99 99 100 forall ( otype RationalImpl | arithmetic( RationalImpl ) )100 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 101 101 int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 102 102 103 forall ( otype RationalImpl | arithmetic( RationalImpl ) )103 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 104 104 int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 105 105 106 forall ( otype RationalImpl | arithmetic( RationalImpl ) )106 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 107 107 int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 108 108 109 109 // arithmetic 110 110 111 forall ( otype RationalImpl | arithmetic( RationalImpl ) )111 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 112 112 Rational(RationalImpl) +?( Rational(RationalImpl) r ); 113 113 114 forall ( otype RationalImpl | arithmetic( RationalImpl ) )114 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 115 115 Rational(RationalImpl) -?( Rational(RationalImpl) r ); 116 116 117 forall ( otype RationalImpl | arithmetic( RationalImpl ) )117 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 118 118 Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 119 119 120 forall ( otype RationalImpl | arithmetic( RationalImpl ) )120 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 121 121 Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 122 122 123 forall ( otype RationalImpl | arithmetic( RationalImpl ) )123 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 124 124 Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 125 125 126 forall ( otype RationalImpl | arithmetic( RationalImpl ) )126 forall ( otype RationalImpl | arithmetic( RationalImpl ) ) 127 127 Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ); 128 128 129 129 // conversion 130 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )130 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) 131 131 double widen( Rational(RationalImpl) r ); 132 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double );} )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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_H 143 145 144 146 // Local Variables: // -
src/libcfa/rational.c
r3d4b23fa r55a68c3 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 16 18:35:36201713 // Update Count : 1 5012 // Last Modified On : Mon May 15 21:29:23 2017 13 // Update Count : 149 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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )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 ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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 ( otype RationalImpl | arithmetic( RationalImpl ) )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
r3d4b23fa r55a68c3 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 7 09:34:49 2017 13 // Update Count : 219 14 // 15 16 #pragma once 12 // Last Modified On : Fri Jun 2 15:51:03 2017 13 // Update Count : 218 14 // 15 16 #ifndef STDLIB_H 17 #define STDLIB_H 17 18 18 19 //--------------------------------------- … … 231 232 void swap( T * t1, T * t2 ); 232 233 234 #endif // STDLIB_H 235 233 236 // Local Variables: // 234 237 // mode: c // -
src/main.cc
r3d4b23fa r55a68c3 10 10 // Author : Richard C. Bilson 11 11 // Created On : Fri May 15 23:12:02 2015 12 // Last Modified By : Andrew Beach13 // Last Modified On : Fri Jul 7 11:13:00 201714 // Update Count : 44 212 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Thu Jun 29 12:46:50 2017 14 // Update Count : 441 15 15 // 16 16 17 #include <cassert> // for assertf 18 #include <cxxabi.h> // for __cxa_demangle 19 #include <execinfo.h> // for backtrace, backtrace_symbols 20 #include <getopt.h> // for no_argument, optind, geto... 21 #include <signal.h> // for signal, SIGABRT, SIGSEGV 22 #include <cstdio> // for fopen, FILE, fclose, stdin 23 #include <cstdlib> // for exit, free, abort, EXIT_F... 24 #include <cstring> // for index 25 #include <fstream> // for ofstream 26 #include <iostream> // for operator<<, basic_ostream 27 #include <iterator> // for back_inserter 28 #include <list> // for list 29 #include <string> // for operator<<, allocator 30 31 #include "../config.h" // for CFA_LIBDIR 32 #include "CodeGen/FixMain.h" // for FixMain 33 #include "CodeGen/FixNames.h" // for fixNames 34 #include "CodeGen/Generate.h" // for generate 35 #include "CodeTools/DeclStats.h" // for printDeclStats 36 #include "CodeTools/TrackLoc.h" // for fillLocations 37 #include "Common/CompilerError.h" // for CompilerError 38 #include "Common/SemanticError.h" // for SemanticError 39 #include "Common/UnimplementedError.h" // for UnimplementedError 40 #include "Common/utility.h" // for deleteAll, filter, printAll 41 #include "ControlStruct/ExceptTranslate.h" // for translateEHM 42 #include "ControlStruct/Mutate.h" // for mutate 43 #include "GenPoly/Box.h" // for box 44 #include "GenPoly/CopyParams.h" // for copyParams 45 #include "GenPoly/InstantiateGeneric.h" // for instantiateGeneric 46 #include "GenPoly/Lvalue.h" // for convertLvalue 47 #include "GenPoly/Specialize.h" // for convertSpecializations 48 #include "InitTweak/FixInit.h" // for fix 49 #include "InitTweak/GenInit.h" // for genInit 50 #include "MakeLibCfa.h" // for makeLibCfa 51 #include "Parser/LinkageSpec.h" // for Spec, Cforall, Intrinsic 52 #include "Parser/ParseNode.h" // for DeclarationNode, buildList 53 #include "Parser/TypedefTable.h" // for TypedefTable 54 #include "ResolvExpr/AlternativePrinter.h" // for AlternativePrinter 55 #include "ResolvExpr/Resolver.h" // for resolve 56 #include "SymTab/Validate.h" // for validate 57 #include "SynTree/Declaration.h" // for Declaration 58 #include "SynTree/Visitor.h" // for acceptAll 59 #include "Tuples/Tuples.h" // for expandMemberTuples, expan... 17 #include <iostream> 18 #include <fstream> 19 #include <signal.h> // signal 20 #include <getopt.h> // getopt 21 #include <execinfo.h> // backtrace, backtrace_symbols 22 #include <cxxabi.h> // __cxa_demangle 23 #include <cstring> // index 24 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" 60 51 61 52 using namespace std; … … 215 206 FILE * builtins = fopen( libcfap | treep ? "../prelude/builtins.cf" : CFA_LIBDIR "/builtins.cf", "r" ); 216 207 assertf( builtins, "cannot open builtins.cf\n" ); 217 parse( builtins, LinkageSpec::Builtin CFA);208 parse( builtins, LinkageSpec::Builtin ); 218 209 } // if 219 210 } // if -
src/prelude/Makefile.in
r3d4b23fa r55a68c3 294 294 esac; \ 295 295 done; \ 296 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- foreignsrc/prelude/Makefile'; \296 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/prelude/Makefile'; \ 297 297 $(am__cd) $(top_srcdir) && \ 298 $(AUTOMAKE) -- foreignsrc/prelude/Makefile298 $(AUTOMAKE) --gnu src/prelude/Makefile 299 299 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 300 300 @case '$?' in \ -
src/tests/.expect/32/math.txt
r3d4b23fa r55a68c3 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 39+1.06128i 0.666239432492515+1.06127506190504i 0.666239432492515255+1.06127506190503565i24 asin:1.5708 1.5707963267949 1.57079632679489662 0.66624+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
r3d4b23fa r55a68c3 9 9 9000 10 10 10000 11 11000 12 12000 13 13000 14 14000 15 15000 16 16000 17 17000 18 18000 19 19000 20 20000 21 21000 22 22000 23 23000 24 24000 25 25000 26 26000 27 27000 28 28000 29 29000 30 30000 31 31000 32 32000 33 33000 34 34000 35 35000 36 36000 37 37000 38 38000 39 39000 40 40000 41 41000 42 42000 43 43000 44 44000 45 45000 46 46000 47 47000 48 48000 49 49000 50 50000 51 51000 52 52000 53 53000 54 54000 55 55000 56 56000 57 57000 58 58000 59 59000 60 60000 61 61000 62 62000 63 63000 64 64000 65 65000 66 66000 67 67000 68 68000 69 69000 70 70000 71 71000 72 72000 73 73000 74 74000 75 75000 76 76000 77 77000 78 78000 79 79000 80 80000 81 81000 82 82000 83 83000 84 84000 85 85000 86 86000 87 87000 88 88000 89 89000 90 90000 91 91000 92 92000 93 93000 94 94000 95 95000 96 96000 97 97000 98 98000 99 99000 100 100000 11 101 All waiter done -
src/tests/.expect/io.txt
r3d4b23fa r55a68c3 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 4, 5, 634 tuples 35 1, 2, 3 3, 4, 5 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 1.1+2.3i 1.1-2.3i1.1-2.3i 41 1.1+2.3i 1.1-2.3i 1.1-2.3i 42 1.1+2.3i1.1-2.3i 1.1-2.3i 43 abcxyz 44 abcxyz 40 abcxyz 41 abcxyz 45 42 46 change separator 47 from " " to ", $"43 change separator 44 from " "to " , $" 48 45 1.1, $1.2, $1.3 49 46 1.1+2.3i, $1.1-2.3i, $1.1-2.3i 50 abc, $xyz 51 1, 2, 3, $ 4, 5, 647 abc, $xyz, $ 48 1, 2, 3, $3, 4, 5 52 49 53 from ", $" to " "50 from ", $"to " " 54 51 1.1 1.2 1.3 55 52 1.1+2.3i 1.1-2.3i 1.1-2.3i 56 abc xyz 57 1, 2, 3 4, 5, 653 abc xyz 54 1, 2, 3 3, 4, 5 58 55 59 check sepOn/sepOff 56 1 2 3 57 12 3 58 1 2 3 60 59 1 2 3 61 12 3 62 1 2 3 63 1 2 3 60 1 2 3 64 61 65 1 2 366 67 check enable/disable68 62 123 69 63 1 23 … … 71 65 123 72 66 1 2 3 73 123 67 123 74 68 1 2 3 75 69 76 1 2 3 4 5 6" "77 1, 2, 3 4, 5, 6 ""78 1, 2, 3 4, 5, 670 1 2 3 3 4 5 " " 71 1, 2, 3 3, 4, 5 ", " 72 1, 2, 3 3, 4, 5 79 73 80 74 3, 4, a, 7.2 81 75 3, 4, a, 7.2 82 76 3 4 a 7.2 83 3 4 a 7.234a7.23 4 a 7.277 3 4 a 7.234a7.23 4 a 7.2 84 78 3-4-a-7.2^3^4^3-4-a-7.2 -
src/tests/Makefile.am
r3d4b23fa r55a68c3 29 29 30 30 # applies to both programs 31 DEBUG_FLAGS = 32 33 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ 34 if !BUILD_DEBUG 35 BUILD_FLAGS += -nodebug 36 else 37 if !BUILD_RELEASE 38 BUILD_FLAGS += -debug 39 else 40 BUILD_FLAGS += ${DEBUG_FLAGS} 41 endif 42 endif 43 31 EXTRA_FLAGS = 32 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ ${EXTRA_FLAGS} 44 33 TEST_FLAGS = $(if $(test), 2> .err/${@}.log, ) 45 34 AM_CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS} -
src/tests/Makefile.in
r3d4b23fa r55a68c3 92 92 host_triplet = @host@ 93 93 @BUILD_CONCURRENCY_TRUE@am__append_1 = coroutine thread monitor 94 @BUILD_DEBUG_FALSE@am__append_2 = -nodebug95 @BUILD_DEBUG_TRUE@@BUILD_RELEASE_FALSE@am__append_3 = -debug96 @BUILD_DEBUG_TRUE@@BUILD_RELEASE_TRUE@am__append_4 = ${DEBUG_FLAGS}97 94 EXTRA_PROGRAMS = fstream_test$(EXEEXT) vector_test$(EXEEXT) \ 98 95 avl_test$(EXEEXT) … … 323 320 324 321 # applies to both programs 325 DEBUG_FLAGS = 326 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ \ 327 $(am__append_2) $(am__append_3) $(am__append_4) 322 EXTRA_FLAGS = 323 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ ${EXTRA_FLAGS} 328 324 TEST_FLAGS = $(if $(test), 2> .err/${@}.log, ) 329 325 AM_CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS} … … 347 343 esac; \ 348 344 done; \ 349 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- foreignsrc/tests/Makefile'; \345 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tests/Makefile'; \ 350 346 $(am__cd) $(top_srcdir) && \ 351 $(AUTOMAKE) -- foreignsrc/tests/Makefile347 $(AUTOMAKE) --gnu src/tests/Makefile 352 348 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 353 349 @case '$?' in \ -
src/tests/io.c
r3d4b23fa r55a68c3 10 10 // Created On : Wed Mar 2 16:56:02 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 6 23:26:12201713 // Update Count : 7812 // Last Modified On : Sun Jul 2 09:40:58 2017 13 // Update Count : 68 14 14 // 15 15 … … 104 104 105 105 sout | "tuples" | endl; 106 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6] ];106 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ]; 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 | endl // complex without separator 113 | fc | sepOn | dc | ldc | endl // local separator add 114 | sepEnable | fc | dc | ldc | endl // complex with separator 115 | fc | sepOff | dc | ldc | endl // local separator removal 116 | s1 | sepOff | s2 | endl // local separator removal 117 | s1 | "" | s2 | endl; // local separator removal 112 | sepDisable | fc | dc | ldc | sepEnable | endl // complex without separator 113 | sepOn | s1 | sepOff | s2 | endl // local separator removal 114 | s1 | "" | s2 | endl; // C string without separator 118 115 sout | endl; 119 116 120 117 sout | "change separator" | endl; 121 sout | "from \" " | sep| "\"";118 sout | "from \" " | sepGet( sout ) | "\""; 122 119 sepSet( sout, ", $" ); // change separator, maximum of 15 characters 123 sout | " to \"" | sep| "\"" | endl;120 sout | "to \" " | sepGet( sout ) | "\"" | endl; 124 121 sout | f | d | ld | endl 125 122 | fc | dc | ldc | endl … … 127 124 | t1 | t2 | endl; // print tuple 128 125 sout | endl; 129 sout | "from \"" | sep | "\"";126 sout | "from \"" | sepGet( sout ) | "\""; 130 127 sepSet( sout, " " ); // restore separator 131 sout | "to \"" | sep | "\"" | endl;128 sout | "to \"" | sepGet( sout ) | "\"" | endl; 132 129 sout | f | d | ld | endl 133 130 | fc | dc | ldc | endl … … 136 133 sout | endl; 137 134 138 sout | "check sepOn/sepOff" | endl; 139 sout | sepOn | 1 | 2 | 3 | sepOn | endl; // no separator at start/end of line 135 sout | sepOn | 1 | 2 | 3 | sepOn | endl; // separator at start/end of line 140 136 sout | 1 | sepOff | 2 | 3 | endl; // locally turn off implicit separator 141 sout | sepOn | sepOn | 1 | 2 | 3 | sepOn | sepOff | sepOn | '\n'; // no separator at start/endof line142 sout | 1 | 2 | 3 | "\n\n" | sepOn; // noseparator at start of next line137 sout | sepOn | 1 | 2 | 3 | sepOn | sepOff | endl; // separator at start of line 138 sout | 1 | 2 | 3 | endl | sepOn; // separator at start of next line 143 139 sout | 1 | 2 | 3 | endl; 144 140 sout | endl; 145 141 146 sout | "check enable/disable" | endl;147 142 sout | sepDisable | 1 | 2 | 3 | endl; // globally turn off implicit separation 148 143 sout | 1 | sepOn | 2 | 3 | endl; // locally turn on implicit separator … … 154 149 sout | endl; 155 150 156 // sout | fmt( d, "%8.3f" ) || endl;157 // sout | endl;158 159 151 sepSetTuple( sout, " " ); // set tuple separator from ", " to " " 160 sout | t1 | t2 | " \"" | sep | "\"" | endl;152 sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl; 161 153 sepSetTuple( sout, ", " ); // reset tuple separator to ", " 162 sout | t1 | t2 | " \"" | sep | "\"" | endl;154 sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl; 163 155 sout | t1 | t2 | endl; // print tuple 164 156 sout | endl; -
src/tests/preempt_longrun/Makefile.am
r3d4b23fa r55a68c3 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= 60019 preempt=1 _000ul18 max_time=30 19 preempt=10_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 enter enter3processor stack wait yield27 TESTS = barge block create disjoint processor stack wait yield 28 28 29 29 .INTERMEDIATE: ${TESTS} -
src/tests/preempt_longrun/Makefile.in
r3d4b23fa r55a68c3 449 449 top_srcdir = @top_srcdir@ 450 450 repeats = 10 451 max_time = 600452 preempt = 1 _000ul451 max_time = 30 452 preempt = 10_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 enter enter3processor stack wait yield455 TESTS = barge block create disjoint processor stack wait yield 456 456 all: all-am 457 457 … … 467 467 esac; \ 468 468 done; \ 469 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- foreignsrc/tests/preempt_longrun/Makefile'; \469 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tests/preempt_longrun/Makefile'; \ 470 470 $(am__cd) $(top_srcdir) && \ 471 $(AUTOMAKE) -- foreignsrc/tests/preempt_longrun/Makefile471 $(AUTOMAKE) --gnu 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: enter666 @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: enter3673 @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)679 665 processor.log: processor 680 666 @p='processor'; \ -
src/tests/preempt_longrun/create.c
r3d4b23fa r55a68c3 10 10 } 11 11 12 thread worker_t{};12 thread Worker {}; 13 13 14 void main( worker_t* this) {}14 void main(Worker * this) {} 15 15 16 16 int main(int argc, char* argv[]) { 17 processor p; 18 for(int i = 0; i < 10_000ul; i++) { 19 worker_t w[7]; 17 for(int i = 0; i < 100_000ul; i++) { 18 Worker w; 20 19 } 21 20 } -
src/tests/preempt_longrun/processor.c
r3d4b23fa r55a68c3 10 10 } 11 11 12 thread worker_t{};12 thread Worker {}; 13 13 14 void main( worker_t* this) {}14 void main(Worker * this) {} 15 15 16 16 int main(int argc, char* argv[]) { 17 for(int i = 0; i < 10 _000ul; i++) {17 for(int i = 0; i < 100_000ul; i++) { 18 18 processor p; 19 19 } -
src/tests/preempt_longrun/stack.c
r3d4b23fa r55a68c3 12 12 } 13 13 14 thread worker_t{};14 thread Worker {}; 15 15 16 void main( worker_t* this) {16 void main(Worker * 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 34 30 int main(int argc, char* argv[]) { 35 31 processor p; 36 32 { 37 worker_t w[7]; 38 workers = w; 33 Worker w[7]; 39 34 } 40 35 } -
src/tests/preempt_longrun/yield.c
r3d4b23fa r55a68c3 10 10 } 11 11 12 thread worker_t{};12 thread Worker {}; 13 13 14 void main( worker_t* this) {15 for(int i = 0; i < 325_000ul; i++) {14 void main(Worker * this) { 15 for(int i = 0; i < 100_000ul; i++) { 16 16 yield(); 17 17 } 18 }19 20 extern "C" {21 static worker_t * workers;22 18 } 23 19 … … 25 21 processor p; 26 22 { 27 worker_t w[7]; 28 workers = w; 23 Worker w[7]; 29 24 } 30 25 } -
src/tests/sched-int-block.c
r3d4b23fa r55a68c3 6 6 7 7 #ifndef N 8 #define N 10 _0008 #define N 100_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
r3d4b23fa r55a68c3 5 5 6 6 #ifndef N 7 #define N 10 _0007 #define N 100_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
r3d4b23fa r55a68c3 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
r3d4b23fa r55a68c3 166 166 167 167 # build, skipping to next test on error 168 make_ret, _ = sh("""%s test=yes DEBUG_FLAGS="%s" %s 2> %s 1> /dev/null""" % (make_cmd, options, test.name, out_file), dry_run)168 make_ret, _ = sh("""%s test=yes EXTRA_FLAGS="%s" %s 2> %s 1> /dev/null""" % (make_cmd, options, test.name, out_file), dry_run) 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
r3d4b23fa r55a68c3 4 4 #include <thread> 5 5 6 thread First { semaphore* lock; };7 thread Second { semaphore* lock; };6 // thread First; 7 // void main(First* this); 8 8 9 void ?{}( First * this, semaphore* lock ) { this->lock = lock; } 10 void ?{}( Second * this, semaphore* lock ) { this->lock = lock; } 9 // thread Second; 10 // void main(Second* this); 11 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; } 11 17 12 18 void main(First* this) { … … 15 21 yield(); 16 22 } 17 V(this->lock);23 signal(this->lock); 18 24 } 19 25 20 26 void main(Second* this) { 21 P(this->lock);27 wait(this->lock); 22 28 for(int i = 0; i < 10; i++) { 23 29 sout | "Second : Suspend No." | i + 1 | endl; … … 28 34 29 35 int main(int argc, char* argv[]) { 30 s emaphore lock = { 0 };36 signal_once lock; 31 37 sout | "User main begin" | endl; 32 38 { -
tools/prettyprinter/Makefile.in
r3d4b23fa r55a68c3 350 350 esac; \ 351 351 done; \ 352 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- foreigntools/prettyprinter/Makefile'; \352 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/prettyprinter/Makefile'; \ 353 353 $(am__cd) $(top_srcdir) && \ 354 $(AUTOMAKE) -- foreigntools/prettyprinter/Makefile354 $(AUTOMAKE) --gnu 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.