Changeset e2e7330
- Timestamp:
- Jan 31, 2018, 5:50:34 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 295e5071
- Parents:
- bc6f918 (diff), 281806b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 4 added
- 3 deleted
- 50 edited
- 5 moved
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
rbc6f918 re2e7330 9 9 config.log 10 10 stamp-h1 11 Makefile 12 driver/Makefile 13 libcfa/Makefile 14 src/Makefile 11 /Makefile 12 src/**/Makefile 13 tools/**/Makefile 15 14 /version 16 15 -
Jenkinsfile
rbc6f918 re2e7330 174 174 175 175 def notify_server(int wait) { 176 sh """curl -- silent --data "wait=${wait}" -X POST http://plg2:8082/jenkins/notify > /dev/null || true"""176 sh """curl --data "wait=${wait}" -X POST http://plg2:8082/jenkins/notify > /dev/null || true""" 177 177 return 178 178 } … … 324 324 325 325 //Then publish the results 326 sh 'curl -H "Content-Type: application/json" --silent--data @bench.json http://plg2:8082/jenkins/publish > /dev/null || true'326 sh 'curl -H \'Content-Type: application/json\' --data @bench.json http://plg2:8082/jenkins/publish > /dev/null || true' 327 327 } 328 328 } -
doc/bibliography/pl.bib
rbc6f918 re2e7330 882 882 address = {\href{https://www.iso.org/standard/64031.html}{https://\-www.iso.org/\-standard/\-64031.html}}, 883 883 year = 2015 884 } 885 886 @misc{Cforall, 887 key = {Cforall}, 888 title = {C$\forall$ Features}, 889 howpublished= {\url{https://plg.uwaterloo.ca/~cforall/features}}, 890 note = {Accessed: 2018-01-01}, 884 891 } 885 892 … … 3685 3692 contributer = {pabuhr@plg}, 3686 3693 author = {James Gosling and Bill Joy and Guy Steele and Gilad Bracha and Alex Buckley}, 3687 title = {{Java} Language Spec .},3694 title = {{Java} Language Specification}, 3688 3695 publisher = {Oracle}, 3689 3696 year = 2015, -
doc/papers/OOPSLA17/.gitignore
rbc6f918 re2e7330 1 1 # generated by latex 2 *.aux 3 *.bbl 4 *.blg 5 *.brf 6 *.dvi 7 *.idx 8 *.ilg 9 *.ind 10 *.log 11 *.out 2 build/* 12 3 *.pdf 13 4 *.ps 14 *.toc15 *.lof16 *.lot17 *.synctex.gz18 comment.cut19 timing.tex -
doc/papers/OOPSLA17/Makefile
rbc6f918 re2e7330 1 ## Define the appropriateconfiguration variables.1 ## Define the configuration variables. 2 2 3 TeXLIB = .:../LaTeXmacros:../LaTeXmacros/listings:../LaTeXmacros/enumitem:../bibliography/: 4 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error 3 Build = build 4 Figures = figures 5 Macros = ../../LaTeXmacros 6 TeXLIB = .:${Macros}:${Build}:../../bibliography: 7 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build} 5 8 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex 9 10 MAKEFLAGS = --no-print-directory --silent # 11 VPATH = ${Figures} evaluation 6 12 7 13 ## Define the text source files. … … 33 39 34 40 clean : 35 rm -f *.bbl *.aux *.dvi *.idx *.ilg *.ind *.brf *.out *.log *.toc *.blg *.pstex_t *.cf \ 36 ${FIGURES} ${PICTURES} ${PROGRAMS} ${GRAPHS} ${basename ${DOCUMENT}}.ps ${DOCUMENT} 41 @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build} 37 42 38 43 # File Dependencies # … … 42 47 43 48 ${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi 44 dvips $ < -o $@49 dvips ${Build}/$< -o $@ 45 50 46 #${DOCUMENT} : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \ 47 48 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ../bibliography/cfa.bib 49 # Conditionally create an empty *.idx (index) file for inclusion until makeindex is run. 50 if [ ! -r ${basename $@}.idx ] ; then touch ${basename $@}.idx ; fi 51 ${basename ${DOCUMENT}}.dvi : Makefile ${Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ../../bibliography/pl.bib 51 52 # Must have *.aux file containing citations for bibtex 52 53 if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi 53 -${BibTeX} ${ basename $@}54 # Some citations reference others so run stepsagain to resolve these citations54 -${BibTeX} ${Build}/${basename $@} 55 # Some citations reference others so run again to resolve these citations 55 56 ${LaTeX} ${basename $@}.tex 56 -${BibTeX} ${basename $@} 57 # Make index from *.aux entries and input index at end of document 58 makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx 57 -${BibTeX} ${Build}/${basename $@} 58 # Run again to finish citations 59 59 ${LaTeX} ${basename $@}.tex 60 # Run again to get index title into table of contents61 ${LaTeX} ${basename $@}.tex62 63 predefined :64 sed -f predefined.sed ${basename ${DOCUMENT}}.tex > ${basename $@}.cf65 60 66 61 ## Define the default recipes. 67 62 68 ${GRAPHS} : evaluation/timing.gp evaluation/timing.dat 69 gnuplot evaluation/timing.gp 63 ${Build}: 64 mkdir -p ${Build} 65 66 ${GRAPHS} : timing.gp timing.dat 67 gnuplot -e Build="'${Build}/'" evaluation/timing.gp 70 68 71 69 %.tex : %.fig 72 fig2dev -L eepic $< > $ @70 fig2dev -L eepic $< > ${Build}/$@ 73 71 74 72 %.ps : %.fig 75 fig2dev -L ps $< > $ @73 fig2dev -L ps $< > ${Build}/$@ 76 74 77 75 %.pstex : %.fig 78 fig2dev -L pstex $< > $ @79 fig2dev -L pstex_t -p $ @ $< >$@_t76 fig2dev -L pstex $< > ${Build}/$@ 77 fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t 80 78 81 79 # Local Variables: # -
doc/papers/OOPSLA17/evaluation/timing.gp
rbc6f918 re2e7330 2 2 # set output "timing.pdf" 3 3 set terminal pslatex size 6.25,2.125 color solid 4 set output "timing.tex"4 set output Build."timing.tex" 5 5 6 6 set pointsize 2.0 -
doc/papers/OOPSLA17/generic_types.tex
rbc6f918 re2e7330 1109 1109 1110 1110 \bibliographystyle{ACM-Reference-Format} 1111 \bibliography{ cfa}1111 \bibliography{pl} 1112 1112 1113 1113 -
doc/papers/concurrency/.gitignore
rbc6f918 re2e7330 1 build/*.aux 2 build/*.acn 3 build/*.acr 4 build/*.alg 5 build/*.bbl 6 build/*.blg 7 build/*.brf 8 build/*.dvi 9 build/*.glg 10 build/*.glo 11 build/*.gls 12 build/*.idx 13 build/*.ind 14 build/*.ist 15 build/*.lof 16 build/*.log 17 build/*.lol 18 build/*.lot 19 build/*.out 20 build/*.ps 21 build/*.pstex 22 build/*.pstex_t 23 build/*.tex 24 build/*.toc 1 # generated by latex 2 build/* 25 3 *.pdf 26 *.png 27 figures/*.tex 28 29 examples 4 *.ps -
doc/papers/concurrency/Paper.tex
rbc6f918 re2e7330 1 % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended 2 3 % inline code �...� (copyright symbol) emacs: C-q M-) 4 % red highlighting �...� (registered trademark symbol) emacs: C-q M-. 5 % blue highlighting �...� (sharp s symbol) emacs: C-q M-_ 6 % green highlighting �...� (cent symbol) emacs: C-q M-" 7 % LaTex escape �...� (section symbol) emacs: C-q M-' 8 % keyword escape �...� (pilcrow symbol) emacs: C-q M-^ 1 % inline code ©...© (copyright symbol) emacs: C-q M-) 2 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. 3 % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_ 4 % green highlighting ¢...¢ (cent symbol) emacs: C-q M-" 5 % LaTex escape §...§ (section symbol) emacs: C-q M-' 6 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^ 9 7 % math escape $...$ (dollar symbol) 10 8 … … 20 18 \usepackage{epic,eepic} 21 19 \usepackage{upquote} % switch curled `'" to straight 22 \usepackage{dirtytalk}23 20 \usepackage{calc} 24 21 \usepackage{xspace} … … 46 43 \urlstyle{rm} 47 44 48 \usepackage{tikz}49 \def\checkmark{\tikz\fill[scale=0.4](0,.35) -- (.25,0) -- (1,.7) -- (.25,.15) -- cycle;}50 51 45 \setlength{\topmargin}{-0.45in} % move running title into header 52 46 \setlength{\headsep}{0.25in} … … 78 72 79 73 \title{Concurrency in \CFA} 80 \author{Thierry Delisle , Waterloo, Ontario, Canada, 2018}74 \author{Thierry Delisle and Peter A. Buhr, Waterloo, Ontario, Canada} 81 75 82 76 … … 85 79 86 80 \begin{abstract} 87 \CFA is a modern, non-object-oriented extension of the C programming language. This thesis serves as a definition and an implementation for the concurrency and parallelism \CFA offers. These features are created from scratch due to the lack of concurrency in ISO C. Lightweight threads are introduced into the language. In addition, monitors are introduced as a high-level tool for control-flow based synchronization and mutual-exclusion. The main contributions of this thesis are two-fold: it extends the existing semantics of monitors introduce by~\cite{Hoare74} to handle monitors in groups and also details the engineering effort needed to introduce these features as core language features. Indeed, these features are added with respect to expectations of C programmers, and integrate with the \CFA type-system and other language features. 81 \CFA is a modern, \emph{non-object-oriented} extension of the C programming language. 82 This paper serves as a definition and an implementation for the concurrency and parallelism \CFA offers. These features are created from scratch due to the lack of concurrency in ISO C. Lightweight threads are introduced into the language. In addition, monitors are introduced as a high-level tool for control-flow based synchronization and mutual-exclusion. The main contributions of this paper are two-fold: it extends the existing semantics of monitors introduce by~\cite{Hoare74} to handle monitors in groups and also details the engineering effort needed to introduce these features as core language features. Indeed, these features are added with respect to expectations of C programmers, and integrate with the \CFA type-system and other language features. 88 83 \end{abstract} 89 84 … … 95 90 \section{Introduction} 96 91 % ====================================================================== 97 This thesis provides a minimal concurrency \textbf{api} that is simple, efficient and can be reused to build higher-level features. The simplest possible concurrency system is a thread and a lock but this low-level approach is hard to master. An easier approach for users is to support higher-level constructs as the basis of concurrency. Indeed, for highly productive concurrent programming, high-level approaches are much more popular~\cite{HPP:Study}. Examples are task based, message passing and implicit threading. The high-level approach and its minimal \textbf{api} are tested in a dialect of C, called \CFA. Furthermore, the proposed \textbf{api} doubles as an early definition of the \CFA language and library. This thesis also provides an implementation of the concurrency library for \CFA as well as all the required language features added to the source-to-source translator. 92 93 This paper provides a minimal concurrency \textbf{api} that is simple, efficient and can be reused to build higher-level features. The simplest possible concurrency system is a thread and a lock but this low-level approach is hard to master. An easier approach for users is to support higher-level constructs as the basis of concurrency. Indeed, for highly productive concurrent programming, high-level approaches are much more popular~\cite{HPP:Study}. Examples are task based, message passing and implicit threading. The high-level approach and its minimal \textbf{api} are tested in a dialect of C, called \CFA. Furthermore, the proposed \textbf{api} doubles as an early definition of the \CFA language and library. This paper also provides an implementation of the concurrency library for \CFA as well as all the required language features added to the source-to-source translator. 98 94 99 95 There are actually two problems that need to be solved in the design of concurrency for a programming language: which concurrency and which parallelism tools are available to the programmer. While these two concepts are often combined, they are in fact distinct, requiring different tools~\cite{Buhr05a}. Concurrency tools need to handle mutual exclusion and synchronization, while parallelism tools are about performance, cost and resource utilization. 100 96 101 In the context of this thesis, a \textbf{thread} is a fundamental unit of execution that runs a sequence of code, generally on a program stack. Having multiple simultaneous threads gives rise to concurrency and generally requires some kind of locking mechanism to ensure proper execution. Correspondingly, \textbf{concurrency} is defined as the concepts and challenges that occur when multiple independent (sharing memory, timing dependencies, etc.) concurrent threads are introduced. Accordingly, \textbf{locking} (and by extension locks) are defined as a mechanism that prevents the progress of certain threads in order to avoid problems due to concurrency. Finally, in this thesis\textbf{parallelism} is distinct from concurrency and is defined as running multiple threads simultaneously. More precisely, parallelism implies \emph{actual} simultaneous execution as opposed to concurrency which only requires \emph{apparent} simultaneous execution. As such, parallelism is only observable in the differences in performance or, more generally, differences in timing.97 In the context of this paper, a \textbf{thread} is a fundamental unit of execution that runs a sequence of code, generally on a program stack. Having multiple simultaneous threads gives rise to concurrency and generally requires some kind of locking mechanism to ensure proper execution. Correspondingly, \textbf{concurrency} is defined as the concepts and challenges that occur when multiple independent (sharing memory, timing dependencies, etc.) concurrent threads are introduced. Accordingly, \textbf{locking} (and by extension locks) are defined as a mechanism that prevents the progress of certain threads in order to avoid problems due to concurrency. Finally, in this paper \textbf{parallelism} is distinct from concurrency and is defined as running multiple threads simultaneously. More precisely, parallelism implies \emph{actual} simultaneous execution as opposed to concurrency which only requires \emph{apparent} simultaneous execution. As such, parallelism is only observable in the differences in performance or, more generally, differences in timing. 102 98 103 99 % ====================================================================== … … 113 109 114 110 % ====================================================================== 115 \s ection{References}111 \subsection{References} 116 112 117 113 Like \CC, \CFA introduces rebind-able references providing multiple dereferencing as an alternative to pointers. In regards to concurrency, the semantic difference between pointers and references are not particularly relevant, but since this document uses mostly references, here is a quick overview of the semantics: … … 132 128 133 129 % ====================================================================== 134 \s ection{Overloading}130 \subsection{Overloading} 135 131 136 132 Another important feature of \CFA is function overloading as in Java and \CC, where routines with the same name are selected based on the number and type of the arguments. As well, \CFA uses the return type as part of the selection criteria, as in Ada~\cite{Ada}. For routines with multiple parameters and returns, the selection is complex. … … 153 149 154 150 % ====================================================================== 155 \s ection{Operators}151 \subsection{Operators} 156 152 Overloading also extends to operators. The syntax for denoting operator-overloading is to name a routine with the symbol of the operator and question marks where the arguments of the operation appear, e.g.: 157 153 \begin{cfacode} … … 173 169 174 170 % ====================================================================== 175 \s ection{Constructors/Destructors}171 \subsection{Constructors/Destructors} 176 172 Object lifetime is often a challenge in concurrency. \CFA uses the approach of giving concurrent meaning to object lifetime as a means of synchronization and/or mutual exclusion. Since \CFA relies heavily on the lifetime of objects, constructors and destructors is a core feature required for concurrency and parallelism. \CFA uses the following syntax for constructors and destructors: 177 173 \begin{cfacode} … … 208 204 209 205 % ====================================================================== 210 \s ection{Parametric Polymorphism}206 \subsection{Parametric Polymorphism} 211 207 \label{s:ParametricPolymorphism} 212 208 Routines in \CFA can also be reused for multiple types. This capability is done using the \code{forall} clauses, which allow separately compiled routines to support generic usage over multiple types. For example, the following sum function works for any type that supports construction from 0 and addition: … … 241 237 242 238 % ====================================================================== 243 \s ection{with Clause/Statement}239 \subsection{with Clause/Statement} 244 240 Since \CFA lacks the concept of a receiver, certain functions end up needing to repeat variable names often. To remove this inconvenience, \CFA provides the \code{with} statement, which opens an aggregate scope making its fields directly accessible (like Pascal). 245 241 \begin{cfacode} … … 286 282 287 283 \section{\protect\CFA's Thread Building Blocks} 288 One of the important features that are missing in C is threading\footnote{While the C11 standard defines a ``threads.h'' header, it is minimal and defined as optional. As such, library support for threading is far from widespread. At the time of writing the thesis, neither \texttt{gcc} nor \texttt{clang} support ``threads.h'' in their respective standard libraries.}. On modern architectures, a lack of threading is unacceptable~\cite{Sutter05, Sutter05b}, and therefore modern programming languages must have the proper tools to allow users to write efficient concurrent programs to take advantage of parallelism. As an extension of C, \CFA needs to express these concepts in a way that is as natural as possible to programmers familiar with imperative languages. And being a system-level language means programmers expect to choose precisely which features they need and which cost they are willing to pay.284 One of the important features that are missing in C is threading\footnote{While the C11 standard defines a ``threads.h'' header, it is minimal and defined as optional. As such, library support for threading is far from widespread. At the time of writing the paper, neither \texttt{gcc} nor \texttt{clang} support ``threads.h'' in their respective standard libraries.}. On modern architectures, a lack of threading is unacceptable~\cite{Sutter05, Sutter05b}, and therefore modern programming languages must have the proper tools to allow users to write efficient concurrent programs to take advantage of parallelism. As an extension of C, \CFA needs to express these concepts in a way that is as natural as possible to programmers familiar with imperative languages. And being a system-level language means programmers expect to choose precisely which features they need and which cost they are willing to pay. 289 285 290 286 \section{Coroutines: A Stepping Stone}\label{coroutine} … … 664 660 \end{cfacode} 665 661 666 In this example, threads of type \code{foo} start execution in the \code{void main(foo &)} routine, which prints \code{"Hello World!".} While this thesisencourages this approach to enforce strongly typed programming, users may prefer to use the routine-based thread semantics for the sake of simplicity. With the static semantics it is trivial to write a thread type that takes a function pointer as a parameter and executes it on its stack asynchronously.662 In this example, threads of type \code{foo} start execution in the \code{void main(foo &)} routine, which prints \code{"Hello World!".} While this paper encourages this approach to enforce strongly typed programming, users may prefer to use the routine-based thread semantics for the sake of simplicity. With the static semantics it is trivial to write a thread type that takes a function pointer as a parameter and executes it on its stack asynchronously. 667 663 \begin{cfacode} 668 664 typedef void (*voidFunc)(int); … … 999 995 % ====================================================================== 1000 996 % ====================================================================== 1001 In addition to mutual exclusion, the monitors at the core of \CFA's concurrency can also be used to achieve synchronization. With monitors, this capability is generally achieved with internal or external scheduling as in~\cite{Hoare74}. With \textbf{scheduling} loosely defined as deciding which thread acquires the critical section next, \textbf{internal scheduling} means making the decision from inside the critical section (i.e., with access to the shared state), while \textbf{external scheduling} means making the decision when entering the critical section (i.e., without access to the shared state). Since internal scheduling within a single monitor is mostly a solved problem, this thesisconcentrates on extending internal scheduling to multiple monitors. Indeed, like the \textbf{bulk-acq} semantics, internal scheduling extends to multiple monitors in a way that is natural to the user but requires additional complexity on the implementation side.997 In addition to mutual exclusion, the monitors at the core of \CFA's concurrency can also be used to achieve synchronization. With monitors, this capability is generally achieved with internal or external scheduling as in~\cite{Hoare74}. With \textbf{scheduling} loosely defined as deciding which thread acquires the critical section next, \textbf{internal scheduling} means making the decision from inside the critical section (i.e., with access to the shared state), while \textbf{external scheduling} means making the decision when entering the critical section (i.e., without access to the shared state). Since internal scheduling within a single monitor is mostly a solved problem, this paper concentrates on extending internal scheduling to multiple monitors. Indeed, like the \textbf{bulk-acq} semantics, internal scheduling extends to multiple monitors in a way that is natural to the user but requires additional complexity on the implementation side. 1002 998 1003 999 First, here is a simple example of internal scheduling: … … 1800 1796 A \textbf{cfacluster} is a group of \textbf{kthread} executed in isolation. \textbf{uthread} are scheduled on the \textbf{kthread} of a given \textbf{cfacluster}, allowing organization between \textbf{uthread} and \textbf{kthread}. It is important that \textbf{kthread} belonging to a same \textbf{cfacluster} have homogeneous settings, otherwise migrating a \textbf{uthread} from one \textbf{kthread} to the other can cause issues. A \textbf{cfacluster} also offers a pluggable scheduler that can optimize the workload generated by the \textbf{uthread}. 1801 1797 1802 \textbf{cfacluster} have not been fully implemented in the context of this thesis. Currently \CFA only supports one \textbf{cfacluster}, the initial one.1798 \textbf{cfacluster} have not been fully implemented in the context of this paper. Currently \CFA only supports one \textbf{cfacluster}, the initial one. 1803 1799 1804 1800 \subsection{Future Work: Machine Setup}\label{machine} 1805 While this was not done in the context of this thesis, another important aspect of clusters is affinity. While many common desktop and laptop PCs have homogeneous CPUs, other devices often have more heterogeneous setups. For example, a system using \textbf{numa} configurations may benefit from users being able to tie clusters and/or kernel threads to certain CPU cores. OS support for CPU affinity is now common~\cite{affinityLinux, affinityWindows, affinityFreebsd, affinityNetbsd, affinityMacosx}, which means it is both possible and desirable for \CFA to offer an abstraction mechanism for portable CPU affinity.1801 While this was not done in the context of this paper, another important aspect of clusters is affinity. While many common desktop and laptop PCs have homogeneous CPUs, other devices often have more heterogeneous setups. For example, a system using \textbf{numa} configurations may benefit from users being able to tie clusters and/or kernel threads to certain CPU cores. OS support for CPU affinity is now common~\cite{affinityLinux, affinityWindows, affinityFreebsd, affinityNetbsd, affinityMacosx}, which means it is both possible and desirable for \CFA to offer an abstraction mechanism for portable CPU affinity. 1806 1802 1807 1803 \subsection{Paradigms}\label{cfaparadigms} … … 1815 1811 The main memory concern for concurrency is queues. All blocking operations are made by parking threads onto queues and all queues are designed with intrusive nodes, where each node has pre-allocated link fields for chaining, to avoid the need for memory allocation. Since several concurrency operations can use an unbound amount of memory (depending on \textbf{bulk-acq}), statically defining information in the intrusive fields of threads is insufficient.The only way to use a variable amount of memory without requiring memory allocation is to pre-allocate large buffers of memory eagerly and store the information in these buffers. Conveniently, the call stack fits that description and is easy to use, which is why it is used heavily in the implementation of internal scheduling, particularly variable-length arrays. Since stack allocation is based on scopes, the first step of the implementation is to identify the scopes that are available to store the information, and which of these can have a variable-length array. The threads and the condition both have a fixed amount of memory, while \code{mutex} routines and blocking calls allow for an unbound amount, within the stack size. 1816 1812 1817 Note that since the major contributions of this thesisare extending monitor semantics to \textbf{bulk-acq} and loose object definitions, any challenges that are not resulting of these characteristics of \CFA are considered as solved problems and therefore not discussed.1813 Note that since the major contributions of this paper are extending monitor semantics to \textbf{bulk-acq} and loose object definitions, any challenges that are not resulting of these characteristics of \CFA are considered as solved problems and therefore not discussed. 1818 1814 1819 1815 % ====================================================================== … … 2615 2611 2616 2612 \section{Conclusion} 2617 This thesis has achieved a minimal concurrency \textbf{api} that is simple, efficient and usable as the basis for higher-level features. The approach presented is based on a lightweight thread-system for parallelism, which sits on top of clusters of processors. This M:N model is judged to be both more efficient and allow more flexibility for users. Furthermore, this document introduces monitors as the main concurrency tool for users. This thesisalso offers a novel approach allowing multiple monitors to be accessed simultaneously without running into the Nested Monitor Problem~\cite{Lister77}. It also offers a full implementation of the concurrency runtime written entirely in \CFA, effectively the largest \CFA code base to date.2613 This paper has achieved a minimal concurrency \textbf{api} that is simple, efficient and usable as the basis for higher-level features. The approach presented is based on a lightweight thread-system for parallelism, which sits on top of clusters of processors. This M:N model is judged to be both more efficient and allow more flexibility for users. Furthermore, this document introduces monitors as the main concurrency tool for users. This paper also offers a novel approach allowing multiple monitors to be accessed simultaneously without running into the Nested Monitor Problem~\cite{Lister77}. It also offers a full implementation of the concurrency runtime written entirely in \CFA, effectively the largest \CFA code base to date. 2618 2614 2619 2615 … … 2625 2621 2626 2622 \subsection{Performance} \label{futur:perf} 2627 This thesispresents a first implementation of the \CFA concurrency runtime. Therefore, there is still significant work to improve performance. Many of the data structures and algorithms may change in the future to more efficient versions. For example, the number of monitors in a single \textbf{bulk-acq} is only bound by the stack size, this is probably unnecessarily generous. It may be possible that limiting the number helps increase performance. However, it is not obvious that the benefit would be significant.2623 This paper presents a first implementation of the \CFA concurrency runtime. Therefore, there is still significant work to improve performance. Many of the data structures and algorithms may change in the future to more efficient versions. For example, the number of monitors in a single \textbf{bulk-acq} is only bound by the stack size, this is probably unnecessarily generous. It may be possible that limiting the number helps increase performance. However, it is not obvious that the benefit would be significant. 2628 2624 2629 2625 \subsection{Flexible Scheduling} \label{futur:sched} … … 2729 2725 \section{Acknowledgements} 2730 2726 2731 I would like to thank my supervisor, Professor Peter Buhr, for his guidance through my degree as well as the editing of this document. 2732 2733 I would like to thank Professors Martin Karsten and Gregor Richards, for reading my thesis and providing helpful feedback. 2734 2735 Thanks to Aaron Moss, Rob Schluntz and Andrew Beach for their work on the \CFA project as well as all the discussions which have helped me concretize the ideas in this thesis. 2736 2737 Finally, I acknowledge that this has been possible thanks to the financial help offered by the David R. Cheriton School of Computer Science and the corporate partnership with Huawei Ltd. 2727 Thanks to Aaron Moss, Rob Schluntz and Andrew Beach for their work on the \CFA project as well as all the discussions which helped concretize the ideas in this paper. 2728 Partial funding was supplied by the Natural Sciences and Engineering Research Council of Canada and a corporate partnership with Huawei Ltd. 2738 2729 2739 2730 … … 2744 2735 2745 2736 \end{document} 2737 2738 % Local Variables: % 2739 % tab-width: 4 % 2740 % fill-column: 120 % 2741 % compile-command: "make" % 2742 % End: % -
doc/papers/general/.gitignore
rbc6f918 re2e7330 1 1 # generated by latex 2 *.aux 3 *.bbl 4 *.blg 5 *.brf 6 *.dvi 7 *.idx 8 *.ilg 9 *.ind 10 *.log 11 *.out 2 build/* 12 3 *.pdf 13 4 *.ps 14 *.toc15 *.lof16 *.lot17 *.synctex.gz18 comment.cut19 timing.tex -
doc/papers/general/Paper.tex
rbc6f918 re2e7330 1095 1095 1096 1096 \bibliographystyle{plain} 1097 \bibliography{ cfa}1097 \bibliography{pl} 1098 1098 1099 1099 -
doc/papers/general/evaluation/timing.gp
rbc6f918 re2e7330 2 2 # set output "timing.pdf" 3 3 set terminal pslatex size 6.25,2.125 color solid 4 set output "timing.tex"4 set output Build."timing.tex" 5 5 6 6 set pointsize 2.0 -
doc/proposals/tuples/tuples.tex
rbc6f918 re2e7330 322 322 \addcontentsline{toc}{section}{\refname} 323 323 \bibliographystyle{plain} 324 \bibliography{ cfa}324 \bibliography{pl} 325 325 326 326 %\addcontentsline{toc}{section}{\indexname} % add index name to table of contents -
doc/refrat/.gitignore
rbc6f918 re2e7330 1 1 # generated by latex 2 *.aux 3 *.bbl 4 *.blg 5 *.brf 6 *.dvi 7 *.idx 8 *.ilg 9 *.ind 10 *.log 11 *.out 2 build/* 12 3 *.pdf 13 4 *.ps 14 *.toc -
doc/refrat/Makefile
rbc6f918 re2e7330 1 ## Define the appropriateconfiguration variables.1 ## Define the configuration variables. 2 2 3 TeXLIB = .:../LaTeXmacros:../LaTeXmacros/listings:../LaTeXmacros/enumitem:../bibliography/: 4 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error 3 Build = build 4 Figures = figures 5 Macros = ../LaTeXmacros 6 TeXLIB = .:${Macros}:${Build}:../bibliography: 7 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build} 5 8 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex 9 10 MAKEFLAGS = --no-print-directory --silent # 11 VPATH = ${Figures} 6 12 7 13 ## Define the text source files. … … 31 37 # Directives # 32 38 39 .PHONY : all clean # not file names 40 33 41 all : ${DOCUMENT} 34 42 35 43 clean : 36 rm -f *.bbl *.aux *.dvi *.idx *.ilg *.ind *.brf *.out *.log *.toc *.blg *.pstex_t *.cf \ 37 ${FIGURES} ${PICTURES} ${PROGRAMS} ${GRAPHS} ${basename ${DOCUMENT}}.ps ${DOCUMENT} 44 @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build} 38 45 39 46 # File Dependencies # … … 43 50 44 51 ${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi 45 dvips $ < -o $@52 dvips ${Build}/$< -o $@ 46 53 47 ${basename ${DOCUMENT}}.dvi : Makefile ${ GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \48 ../LaTeXmacros/common.tex ../LaTeXmacros/lstlang.sty ../LaTeXmacros/indexstyle ../bibliography/cfa.bib54 ${basename ${DOCUMENT}}.dvi : Makefile ${Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \ 55 ${Macros}/common.tex ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib 49 56 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 50 if [ ! -r ${basename $@}.ind ] ; then touch ${ basename $@}.ind ; fi57 if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi 51 58 # Must have *.aux file containing citations for bibtex 52 59 if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi 53 -${BibTeX} ${ basename $@}54 # Some citations reference others so run stepsagain to resolve these citations60 -${BibTeX} ${Build}/${basename $@} 61 # Some citations reference others so run again to resolve these citations 55 62 ${LaTeX} ${basename $@}.tex 56 -${BibTeX} ${ basename $@}63 -${BibTeX} ${Build}/${basename $@} 57 64 # Make index from *.aux entries and input index at end of document 58 makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx 65 makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx 66 # Run again to finish citations 59 67 ${LaTeX} ${basename $@}.tex 60 68 # Run again to get index title into table of contents … … 66 74 ## Define the default recipes. 67 75 76 ${Build}: 77 mkdir -p ${Build} 78 68 79 %.tex : %.fig 69 fig2dev -L eepic $< > $ @80 fig2dev -L eepic $< > ${Build}/$@ 70 81 71 82 %.ps : %.fig 72 fig2dev -L ps $< > $ @83 fig2dev -L ps $< > ${Build}/$@ 73 84 74 85 %.pstex : %.fig 75 fig2dev -L pstex $< > $ @76 fig2dev -L pstex_t -p $ @ $< >$@_t86 fig2dev -L pstex $< > ${Build}/$@ 87 fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t 77 88 78 89 # Local Variables: # -
doc/refrat/refrat.tex
rbc6f918 re2e7330 11 11 %% Created On : Wed Apr 6 14:52:25 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Tue Aug 15 18:46:31 201714 %% Update Count : 10 613 %% Last Modified On : Wed Jan 31 17:30:23 2018 14 %% Update Count : 108 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 141 141 The manual deliberately imitates the ordering of the \Celeven standard (although the section numbering differs). 142 142 Unfortunately, this means the manual contains more ``forward references'' than usual, making it harder to follow if the reader does not have a copy of the \Celeven standard. 143 For a simple introduction to \CFA, see the companion document ``An Overview of \CFA'' 144 \cite{Ditchfield96:Overview}. 143 For a simple introduction to \CFA, see~\cite{Cforall}. 145 144 146 145 \begin{rationale} … … 596 595 \begin{rationale} 597 596 Since each subsection describes the interpretations of an expression in terms of the interpretations of its subexpressions, this chapter can be taken as describing an overload resolution algorithm that uses one bottom-up pass over an expression tree. 598 Such an algorithm was first described (for Ada) by Baker~\cite{Bak :overload}.597 Such an algorithm was first described (for Ada) by Baker~\cite{Baker82}. 599 598 It is extended here to handle polymorphic functions and arithmetic conversions. 600 599 The overload resolution rules and the predefined functions have been chosen so that, in programs that do not introduce overloaded declarations, expressions will have the same meaning in C and in \CFA. … … 3775 3774 3776 3775 \bibliographystyle{plain} 3777 \bibliography{ cfa}3776 \bibliography{pl} 3778 3777 3779 3778 -
doc/user/.gitignore
rbc6f918 re2e7330 1 1 # generated by latex 2 *.aux 3 *.bbl 4 *.blg 5 *.brf 6 *.dvi 7 *.idx 8 *.ilg 9 *.ind 10 *.log 11 *.out 2 build/* 12 3 *.pdf 13 4 *.ps 14 *.toc -
doc/user/Makefile
rbc6f918 re2e7330 1 ## Define the appropriateconfiguration variables.1 ## Define the configuration variables. 2 2 3 TeXLIB = .:../LaTeXmacros:../bibliography/: 4 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error 3 Build = build 4 Figures = figures 5 Macros = ../LaTeXmacros 6 TeXLIB = .:${Macros}:${Build}:../bibliography: 7 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build} 5 8 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex 9 10 MAKEFLAGS = --no-print-directory --silent # 11 VPATH = ${Figures} 6 12 7 13 ## Define the text source files. … … 35 41 # Directives # 36 42 43 .PHONY : all clean # not file names 44 37 45 all : ${DOCUMENT} 38 46 39 47 clean : 40 rm -f *.bbl *.aux *.dvi *.idx *.ilg *.ind *.brf *.out *.log *.toc *.blg *.pstex_t *.cf \ 41 ${FIGURES} ${PICTURES} ${PROGRAMS} ${GRAPHS} ${basename ${DOCUMENT}}.ps ${DOCUMENT} 48 @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build} 42 49 43 50 # File Dependencies # … … 47 54 48 55 ${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi 49 dvips $ < -o $@56 dvips ${Build}/$< -o $@ 50 57 51 ${basename ${DOCUMENT}}.dvi : Makefile ${ GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \52 ../LaTeXmacros/common.tex ../LaTeXmacros/lstlang.sty ../LaTeXmacros/indexstyle ../bibliography/cfa.bib58 ${basename ${DOCUMENT}}.dvi : Makefile ${Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \ 59 ${Macros}/common.tex ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib 53 60 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 54 if [ ! -r ${basename $@}.ind ] ; then touch ${ basename $@}.ind ; fi61 if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi 55 62 # Must have *.aux file containing citations for bibtex 56 63 if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi 57 -${BibTeX} ${ basename $@}58 # Some citations reference others so run stepsagain to resolve these citations64 -${BibTeX} ${Build}/${basename $@} 65 # Some citations reference others so run again to resolve these citations 59 66 ${LaTeX} ${basename $@}.tex 60 -${BibTeX} ${ basename $@}67 -${BibTeX} ${Build}/${basename $@} 61 68 # Make index from *.aux entries and input index at end of document 62 makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx 69 makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx 70 # Run again to finish citations 63 71 ${LaTeX} ${basename $@}.tex 64 72 # Run again to get index title into table of contents 65 73 ${LaTeX} ${basename $@}.tex 66 74 67 predefined :68 sed -f predefined.sed ${basename ${DOCUMENT}}.tex > ${basename $@}.cf69 70 75 ## Define the default recipes. 71 76 77 ${Build}: 78 mkdir -p ${Build} 79 72 80 %.tex : %.fig 73 fig2dev -L eepic $< > $ @81 fig2dev -L eepic $< > ${Build}/$@ 74 82 75 83 %.ps : %.fig 76 fig2dev -L ps $< > $ @84 fig2dev -L ps $< > ${Build}/$@ 77 85 78 86 %.pstex : %.fig 79 fig2dev -L pstex $< > $ @80 fig2dev -L pstex_t -p $ @ $< >$@_t87 fig2dev -L pstex $< > ${Build}/$@ 88 fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t 81 89 82 90 # Local Variables: # -
doc/user/user.tex
rbc6f918 re2e7330 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Mon Nov 27 18:09:59 201714 %% Update Count : 314 313 %% Last Modified On : Wed Jan 31 07:59:24 2018 14 %% Update Count : 3146 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 40 40 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref} 41 41 \usepackage{breakurl} 42 \renewcommand{\UrlFont}{\small\sf}43 42 44 43 \usepackage[pagewise]{lineno} … … 6661 6660 6662 6661 \bibliographystyle{plain} 6663 \bibliography{ cfa}6662 \bibliography{pl} 6664 6663 6665 6664 -
src/benchmark/Makefile.am
rbc6f918 re2e7330 59 59 @echo -e '\t"githash": "'${githash}'",' 60 60 @echo -e '\t"arch": "' ${arch} '",' 61 @echo -e '\t"compile": {' 62 @+make compile TIME_FORMAT='%e,' PRINT_FORMAT='\t\t\"%s\" :' 63 @echo -e '\t\t"dummy" : {}' 64 @echo -e '\t},' 61 65 @echo -e '\t"ctxswitch": {' 62 66 @echo -en '\t\t"coroutine":' -
src/benchmark/Makefile.in
rbc6f918 re2e7330 473 473 @echo -e '\t"githash": "'${githash}'",' 474 474 @echo -e '\t"arch": "' ${arch} '",' 475 @echo -e '\t"compile": {' 476 @+make compile TIME_FORMAT='%e,' PRINT_FORMAT='\t\t\"%s\" :' 477 @echo -e '\t\t"dummy" : {}' 478 @echo -e '\t},' 475 479 @echo -e '\t"ctxswitch": {' 476 480 @echo -en '\t\t"coroutine":' -
src/driver/cfa.cc
rbc6f918 re2e7330 10 10 // Created On : Tue Aug 20 13:44:49 2002 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Oct 31 11:40:44 201713 // Update Count : 16 012 // Last Modified On : Tue Jan 30 15:46:15 2018 13 // Update Count : 161 14 14 // 15 15 … … 277 277 args[nargs] = "--undefined=__cfaabi_dbg_bits_write"; 278 278 nargs += 1; 279 args[nargs] = "-Xlinker"; 280 nargs += 1; 281 args[nargs] = "--undefined=__cfaabi_interpose_startup"; 282 nargs += 1; 279 283 280 284 } // if … … 353 357 nargs += 1; 354 358 args[nargs] = "-D__int8_t_defined"; // prevent gcc type-size attributes 359 nargs += 1; 360 args[nargs] = "-D__NO_STRING_INLINES"; // prevent gcc strcmp unrolling 355 361 nargs += 1; 356 362 args[nargs] = ( *new string( string("-B") + Bprefix + "/" ) ).c_str(); -
src/libcfa/bits/containers.h
rbc6f918 re2e7330 140 140 141 141 #ifdef __cforall 142 142 143 forall(dtype T | is_node(T)) 143 static inline void ?{}( __queue(T) & this ) {144 (this.head){ NULL };145 (this.tail){ &this.head };144 static inline void ?{}( __queue(T) & this ) with( this ) { 145 head{ NULL }; 146 tail{ &head }; 146 147 } 147 148 148 149 forall(dtype T | is_node(T) | sized(T)) 149 static inline void append( __queue(T) & this, T * val ) {150 verify(t his.tail != NULL);151 *t his.tail = val;152 t his.tail = &get_next( *val );150 static inline void append( __queue(T) & this, T * val ) with( this ) { 151 verify(tail != NULL); 152 *tail = val; 153 tail = &get_next( *val ); 153 154 } 154 155 … … 167 168 168 169 forall(dtype T | is_node(T) | sized(T)) 169 static inline T * remove( __queue(T) & this, T ** it ) {170 static inline T * remove( __queue(T) & this, T ** it ) with( this ) { 170 171 T * val = *it; 171 172 verify( val ); … … 173 174 (*it) = get_next( *val ); 174 175 175 if( t his.tail == &get_next( *val ) ) {176 t his.tail = it;176 if( tail == &get_next( *val ) ) { 177 tail = it; 177 178 } 178 179 179 180 get_next( *val ) = NULL; 180 181 181 verify( ( this.head == NULL) == (&this.head == this.tail) );182 verify( *t his.tail == NULL );182 verify( (head == NULL) == (&head == tail) ); 183 verify( *tail == NULL ); 183 184 return val; 184 185 } 185 186 #endif 187 188 //----------------------------------------------------------------------------- 189 // Tools 190 //----------------------------------------------------------------------------- 191 #ifdef __cforall 192 193 #endif -
src/libcfa/bits/locks.h
rbc6f918 re2e7330 58 58 59 59 #ifdef __cforall 60 extern "C" { 61 extern void disable_interrupts(); 62 extern void enable_interrupts_noPoll(); 63 } 64 60 65 extern void yield( unsigned int ); 61 66 extern thread_local struct thread_desc * volatile this_thread; 67 extern thread_local struct processor * volatile this_processor; 62 68 63 69 static inline void ?{}( __spinlock_t & this ) { … … 68 74 static inline _Bool try_lock ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) { 69 75 _Bool result = __lock_test_and_test_and_set( this.lock ); 70 __cfaabi_dbg_debug_do( 71 if( result ) { 76 if( result ) { 77 disable_interrupts(); 78 __cfaabi_dbg_debug_do( 72 79 this.prev_name = caller; 73 80 this.prev_thrd = this_thread; 74 }75 )81 ) 82 } 76 83 return result; 77 84 } … … 99 106 #endif 100 107 } 108 disable_interrupts(); 101 109 __cfaabi_dbg_debug_do( 102 110 this.prev_name = caller; … … 105 113 } 106 114 107 // Lock the spinlock, spin if already acquired 108 static inline void lock_yield( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) { 109 for ( unsigned int i = 1;; i += 1 ) { 110 if ( __lock_test_and_test_and_set( this.lock ) ) break; 111 yield( i ); 112 } 113 __cfaabi_dbg_debug_do( 114 this.prev_name = caller; 115 this.prev_thrd = this_thread; 116 ) 117 } 115 // // Lock the spinlock, yield if already acquired 116 // static inline void lock_yield( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) { 117 // for ( unsigned int i = 1;; i += 1 ) { 118 // if ( __lock_test_and_test_and_set( this.lock ) ) break; 119 // yield( i ); 120 // } 121 // disable_interrupts(); 122 // __cfaabi_dbg_debug_do( 123 // this.prev_name = caller; 124 // this.prev_thrd = this_thread; 125 // ) 126 // } 118 127 119 128 static inline void unlock( __spinlock_t & this ) { 129 enable_interrupts_noPoll(); 120 130 __lock_release( this.lock ); 121 131 } -
src/libcfa/concurrency/coroutine.c
rbc6f918 re2e7330 118 118 } //ctxSwitchDirect 119 119 120 void create_stack( coStack_t* this, unsigned int storageSize ) {120 void create_stack( coStack_t* this, unsigned int storageSize ) with( *this ) { 121 121 //TEMP HACK do this on proper kernel startup 122 122 if(pageSize == 0ul) pageSize = sysconf( _SC_PAGESIZE ); … … 124 124 size_t cxtSize = libCeiling( sizeof(machine_context_t), 8 ); // minimum alignment 125 125 126 if ( (intptr_t) this->storage == 0 ) {127 this->userStack = false;128 this->size = libCeiling( storageSize, 16 );126 if ( (intptr_t)storage == 0 ) { 127 userStack = false; 128 size = libCeiling( storageSize, 16 ); 129 129 // use malloc/memalign because "new" raises an exception for out-of-memory 130 130 131 131 // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment 132 __cfaabi_dbg_debug_do( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) );133 __cfaabi_dbg_no_debug_do( this->storage = malloc( cxtSize + this->size + 8 ) );132 __cfaabi_dbg_debug_do( storage = memalign( pageSize, cxtSize + size + pageSize ) ); 133 __cfaabi_dbg_no_debug_do( storage = malloc( cxtSize + size + 8 ) ); 134 134 135 135 __cfaabi_dbg_debug_do( 136 if ( mprotect( this->storage, pageSize, PROT_NONE ) == -1 ) {136 if ( mprotect( storage, pageSize, PROT_NONE ) == -1 ) { 137 137 abortf( "(uMachContext &)%p.createContext() : internal error, mprotect failure, error(%d) %s.", this, (int)errno, strerror( (int)errno ) ); 138 138 } // if 139 139 ); 140 140 141 if ( (intptr_t) this->storage == 0 ) {142 abortf( "Attempt to allocate %d bytes of storage for coroutine or task execution-state but insufficient memory available.", this->size );141 if ( (intptr_t)storage == 0 ) { 142 abortf( "Attempt to allocate %d bytes of storage for coroutine or task execution-state but insufficient memory available.", size ); 143 143 } // if 144 144 145 __cfaabi_dbg_debug_do( this->limit = (char *)this->storage + pageSize );146 __cfaabi_dbg_no_debug_do( this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ) ); // minimum alignment145 __cfaabi_dbg_debug_do( limit = (char *)storage + pageSize ); 146 __cfaabi_dbg_no_debug_do( limit = (char *)libCeiling( (unsigned long)storage, 16 ) ); // minimum alignment 147 147 148 148 } else { 149 assertf( ((size_t) this->storage & (libAlign() - 1)) != 0ul, "Stack storage %p for task/coroutine must be aligned on %d byte boundary.", this->storage, (int)libAlign() );150 this->userStack = true;151 this->size = storageSize - cxtSize;149 assertf( ((size_t)storage & (libAlign() - 1)) != 0ul, "Stack storage %p for task/coroutine must be aligned on %d byte boundary.", storage, (int)libAlign() ); 150 userStack = true; 151 size = storageSize - cxtSize; 152 152 153 if ( this->size % 16 != 0u ) this->size -= 8;153 if ( size % 16 != 0u ) size -= 8; 154 154 155 this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ); // minimum alignment155 limit = (char *)libCeiling( (unsigned long)storage, 16 ); // minimum alignment 156 156 } // if 157 assertf( this->size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", this->size, MinStackSize );157 assertf( size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", size, MinStackSize ); 158 158 159 this->base = (char *)this->limit + this->size;160 this->context = this->base;161 t his->top = (char *)this->context + cxtSize;159 base = (char *)limit + size; 160 context = base; 161 top = (char *)context + cxtSize; 162 162 } 163 163 -
src/libcfa/concurrency/invoke.h
rbc6f918 re2e7330 134 134 // instrusive link field for threads 135 135 struct thread_desc * next; 136 137 __cfaabi_dbg_debug_do( 138 // instrusive link field for debugging 139 struct thread_desc * dbg_next; 140 struct thread_desc * dbg_prev; 141 ) 136 142 }; 137 143 -
src/libcfa/concurrency/kernel.c
rbc6f918 re2e7330 87 87 } 88 88 89 void ?{}( coStack_t & this, current_stack_info_t * info) {90 this.size= info->size;91 this.storage= info->storage;92 this.limit= info->limit;93 this.base= info->base;94 this.context= info->context;95 t his.top= info->top;96 this.userStack = true;97 } 98 99 void ?{}( coroutine_desc & this, current_stack_info_t * info) {100 (this.stack){ info };101 this.name = "Main Thread";102 this.errno_ = 0;103 this.state = Start;104 this.starter = NULL;105 } 106 107 void ?{}( thread_desc & this, current_stack_info_t * info) {108 (this.self_cor){ info };89 void ?{}( coStack_t & this, current_stack_info_t * info) with( this ) { 90 size = info->size; 91 storage = info->storage; 92 limit = info->limit; 93 base = info->base; 94 context = info->context; 95 top = info->top; 96 userStack = true; 97 } 98 99 void ?{}( coroutine_desc & this, current_stack_info_t * info) with( this ) { 100 stack{ info }; 101 name = "Main Thread"; 102 errno_ = 0; 103 state = Start; 104 starter = NULL; 105 } 106 107 void ?{}( thread_desc & this, current_stack_info_t * info) with( this ) { 108 self_cor{ info }; 109 109 } 110 110 … … 133 133 void ?{}(processor & this, cluster * cltr) { 134 134 this.cltr = cltr; 135 (this.terminated){ 0 };135 this.terminated{ 0 }; 136 136 this.do_terminate = false; 137 137 this.preemption_alarm = NULL; … … 143 143 void ?{}(processor & this, cluster * cltr, processorCtx_t & runner) { 144 144 this.cltr = cltr; 145 (this.terminated){ 0 };145 this.terminated{ 0 }; 146 146 this.do_terminate = false; 147 147 this.preemption_alarm = NULL; … … 154 154 } 155 155 156 void ^?{}(processor & this) {157 if( ! this.do_terminate ) {156 void ^?{}(processor & this) with( this ){ 157 if( ! do_terminate ) { 158 158 __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this); 159 this.do_terminate = true;160 P( t his.terminated );161 pthread_join( this.kernel_thread, NULL );162 } 163 } 164 165 void ?{}(cluster & this) {166 (this.ready_queue){};167 ( this.ready_queue_lock ){};168 169 this.preemption = default_preemption();159 do_terminate = true; 160 P( terminated ); 161 pthread_join( kernel_thread, NULL ); 162 } 163 } 164 165 void ?{}(cluster & this) with( this ) { 166 ready_queue{}; 167 ready_queue_lock{}; 168 169 preemption = default_preemption(); 170 170 } 171 171 … … 240 240 // Once a thread has finished running, some of 241 241 // its final actions must be executed from the kernel 242 void finishRunning(processor * this) { 243 if( this->finish.action_code == Release ) { 244 unlock( *this->finish.lock ); 245 } 246 else if( this->finish.action_code == Schedule ) { 247 ScheduleThread( this->finish.thrd ); 248 } 249 else if( this->finish.action_code == Release_Schedule ) { 250 unlock( *this->finish.lock ); 251 ScheduleThread( this->finish.thrd ); 252 } 253 else if( this->finish.action_code == Release_Multi ) { 254 for(int i = 0; i < this->finish.lock_count; i++) { 255 unlock( *this->finish.locks[i] ); 242 void finishRunning(processor * this) with( this->finish ) { 243 if( action_code == Release ) { 244 verify( disable_preempt_count > 1 ); 245 unlock( *lock ); 246 } 247 else if( action_code == Schedule ) { 248 ScheduleThread( thrd ); 249 } 250 else if( action_code == Release_Schedule ) { 251 verify( disable_preempt_count > 1 ); 252 unlock( *lock ); 253 ScheduleThread( thrd ); 254 } 255 else if( action_code == Release_Multi ) { 256 verify( disable_preempt_count > lock_count ); 257 for(int i = 0; i < lock_count; i++) { 258 unlock( *locks[i] ); 256 259 } 257 260 } 258 else if( this->finish.action_code == Release_Multi_Schedule ) {259 for(int i = 0; i < this->finish.lock_count; i++) {260 unlock( * this->finish.locks[i] );261 else if( action_code == Release_Multi_Schedule ) { 262 for(int i = 0; i < lock_count; i++) { 263 unlock( *locks[i] ); 261 264 } 262 for(int i = 0; i < th is->finish.thrd_count; i++) {263 ScheduleThread( th is->finish.thrds[i] );265 for(int i = 0; i < thrd_count; i++) { 266 ScheduleThread( thrds[i] ); 264 267 } 265 268 } 266 269 else { 267 assert( this->finish.action_code == No_Action);270 assert(action_code == No_Action); 268 271 } 269 272 } … … 334 337 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 335 338 336 lock( this_processor->cltr->ready_queue_lock __cfaabi_dbg_ctx2 ); 337 append( this_processor->cltr->ready_queue, thrd ); 338 unlock( this_processor->cltr->ready_queue_lock ); 339 340 verify( disable_preempt_count > 0 ); 341 } 342 343 thread_desc * nextThread(cluster * this) { 344 verify( disable_preempt_count > 0 ); 345 lock( this->ready_queue_lock __cfaabi_dbg_ctx2 ); 346 thread_desc * head = pop_head( this->ready_queue ); 347 unlock( this->ready_queue_lock ); 339 with( *this_processor->cltr ) { 340 lock ( ready_queue_lock __cfaabi_dbg_ctx2 ); 341 append( ready_queue, thrd ); 342 unlock( ready_queue_lock ); 343 } 344 345 verify( disable_preempt_count > 0 ); 346 } 347 348 thread_desc * nextThread(cluster * this) with( *this ) { 349 verify( disable_preempt_count > 0 ); 350 lock( ready_queue_lock __cfaabi_dbg_ctx2 ); 351 thread_desc * head = pop_head( ready_queue ); 352 unlock( ready_queue_lock ); 348 353 verify( disable_preempt_count > 0 ); 349 354 return head; … … 361 366 disable_interrupts(); 362 367 this_processor->finish.action_code = Release; 363 this_processor->finish.lock = lock;364 365 verify( disable_preempt_count > 0);368 this_processor->finish.lock = lock; 369 370 verify( disable_preempt_count > 1 ); 366 371 suspend(); 367 372 verify( disable_preempt_count > 0 ); … … 371 376 372 377 void BlockInternal( thread_desc * thrd ) { 373 assert(thrd);374 378 disable_interrupts(); 375 assert( thrd->self_cor.state != Halted );376 379 this_processor->finish.action_code = Schedule; 377 this_processor->finish.thrd = thrd;380 this_processor->finish.thrd = thrd; 378 381 379 382 verify( disable_preempt_count > 0 ); … … 388 391 disable_interrupts(); 389 392 this_processor->finish.action_code = Release_Schedule; 390 this_processor->finish.lock = lock;391 this_processor->finish.thrd = thrd;392 393 verify( disable_preempt_count > 0);393 this_processor->finish.lock = lock; 394 this_processor->finish.thrd = thrd; 395 396 verify( disable_preempt_count > 1 ); 394 397 suspend(); 395 398 verify( disable_preempt_count > 0 ); … … 401 404 disable_interrupts(); 402 405 this_processor->finish.action_code = Release_Multi; 403 this_processor->finish.locks = locks;404 this_processor->finish.lock_count = count;406 this_processor->finish.locks = locks; 407 this_processor->finish.lock_count = count; 405 408 406 409 verify( disable_preempt_count > 0 ); … … 414 417 disable_interrupts(); 415 418 this_processor->finish.action_code = Release_Multi_Schedule; 416 this_processor->finish.locks = locks;417 this_processor->finish.lock_count = lock_count;418 this_processor->finish.thrds = thrds;419 this_processor->finish.thrd_count = thrd_count;419 this_processor->finish.locks = locks; 420 this_processor->finish.lock_count = lock_count; 421 this_processor->finish.thrds = thrds; 422 this_processor->finish.thrd_count = thrd_count; 420 423 421 424 verify( disable_preempt_count > 0 ); … … 429 432 verify( disable_preempt_count > 0 ); 430 433 this_processor->finish.action_code = thrd ? Release_Schedule : Release; 431 this_processor->finish.lock = lock;432 this_processor->finish.thrd = thrd;434 this_processor->finish.lock = lock; 435 this_processor->finish.thrd = thrd; 433 436 434 437 suspend(); … … 516 519 } 517 520 521 //============================================================================================= 522 // Unexpected Terminating logic 523 //============================================================================================= 524 525 518 526 static __spinlock_t kernel_abort_lock; 519 527 static __spinlock_t kernel_debug_lock; … … 581 589 void ^?{}(semaphore & this) {} 582 590 583 void P(semaphore & this) {584 lock( this.lock __cfaabi_dbg_ctx2 );585 this.count -= 1;586 if ( this.count < 0 ) {591 void P(semaphore & this) with( this ){ 592 lock( lock __cfaabi_dbg_ctx2 ); 593 count -= 1; 594 if ( count < 0 ) { 587 595 // queue current task 588 append( this.waiting, (thread_desc *)this_thread );596 append( waiting, (thread_desc *)this_thread ); 589 597 590 598 // atomically release spin lock and block 591 BlockInternal( & this.lock );599 BlockInternal( &lock ); 592 600 } 593 601 else { 594 unlock( this.lock );595 } 596 } 597 598 void V(semaphore & this) {602 unlock( lock ); 603 } 604 } 605 606 void V(semaphore & this) with( this ) { 599 607 thread_desc * thrd = NULL; 600 lock( this.lock __cfaabi_dbg_ctx2 );601 this.count += 1;602 if ( this.count <= 0 ) {608 lock( lock __cfaabi_dbg_ctx2 ); 609 count += 1; 610 if ( count <= 0 ) { 603 611 // remove task at head of waiting list 604 thrd = pop_head( this.waiting );605 } 606 607 unlock( this.lock );612 thrd = pop_head( waiting ); 613 } 614 615 unlock( lock ); 608 616 609 617 // make new owner … … 611 619 } 612 620 621 //----------------------------------------------------------------------------- 622 // Debug 623 __cfaabi_dbg_debug_do( 624 struct { 625 thread_desc * tail; 626 } __cfaabi_dbg_thread_list = { NULL }; 627 628 void __cfaabi_dbg_thread_register( thread_desc * thrd ) { 629 if( !__cfaabi_dbg_thread_list.tail ) { 630 __cfaabi_dbg_thread_list.tail = thrd; 631 return; 632 } 633 __cfaabi_dbg_thread_list.tail->dbg_next = thrd; 634 thrd->dbg_prev = __cfaabi_dbg_thread_list.tail; 635 __cfaabi_dbg_thread_list.tail = thrd; 636 } 637 638 void __cfaabi_dbg_thread_unregister( thread_desc * thrd ) { 639 thread_desc * prev = thrd->dbg_prev; 640 thread_desc * next = thrd->dbg_next; 641 642 if( next ) { next->dbg_prev = prev; } 643 else { 644 assert( __cfaabi_dbg_thread_list.tail == thrd ); 645 __cfaabi_dbg_thread_list.tail = prev; 646 } 647 648 if( prev ) { prev->dbg_next = next; } 649 650 thrd->dbg_prev = NULL; 651 thrd->dbg_next = NULL; 652 } 653 ) 613 654 // Local Variables: // 614 655 // mode: c // -
src/libcfa/concurrency/kernel_private.h
rbc6f918 re2e7330 85 85 extern void ThreadCtxSwitch(coroutine_desc * src, coroutine_desc * dst); 86 86 87 __cfaabi_dbg_debug_do( 88 extern void __cfaabi_dbg_thread_register ( thread_desc * thrd ); 89 extern void __cfaabi_dbg_thread_unregister( thread_desc * thrd ); 90 ) 91 87 92 //----------------------------------------------------------------------------- 88 93 // Utils -
src/libcfa/concurrency/monitor.c
rbc6f918 re2e7330 53 53 static inline __lock_size_t aggregate ( monitor_desc * storage [], const __waitfor_mask_t & mask ); 54 54 55 #ifndef __CFA_LOCK_NO_YIELD56 #define DO_LOCK lock_yield57 #else58 #define DO_LOCK lock59 #endif60 61 55 //----------------------------------------------------------------------------- 62 56 // Useful defines … … 90 84 static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) { 91 85 // Lock the monitor spinlock 92 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );86 lock( this->lock __cfaabi_dbg_ctx2 ); 93 87 thread_desc * thrd = this_thread; 88 89 verify( disable_preempt_count > 0 ); 94 90 95 91 __cfaabi_dbg_print_safe("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner); … … 121 117 // Some one else has the monitor, wait in line for it 122 118 append( this->entry_queue, thrd ); 119 120 verify( disable_preempt_count > 0 ); 121 123 122 BlockInternal( &this->lock ); 124 123 … … 138 137 static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) { 139 138 // Lock the monitor spinlock 140 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );139 lock( this->lock __cfaabi_dbg_ctx2 ); 141 140 thread_desc * thrd = this_thread; 142 141 … … 201 200 // Leave single monitor 202 201 void __leave_monitor_desc( monitor_desc * this ) { 203 // Lock the monitor spinlock , DO_LOCK to reduce contention204 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );202 // Lock the monitor spinlock 203 lock( this->lock __cfaabi_dbg_ctx2 ); 205 204 206 205 __cfaabi_dbg_print_safe("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner); … … 248 247 249 248 // Lock the monitor now 250 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );249 lock( this->lock __cfaabi_dbg_ctx2 ); 251 250 252 251 disable_interrupts(); … … 397 396 append( this.blocked, &waiter ); 398 397 398 verify( disable_preempt_count == 0 ); 399 399 400 // Lock all monitors (aggregates the locks as well) 400 401 lock_all( monitors, locks, count ); 402 403 // verifyf( disable_preempt_count == count, "Got %d, expected %d\n", disable_preempt_count, count ); 404 if(disable_preempt_count != count) { __cfaabi_dbg_print_buffer_decl("----------Gonna crash\n"); } 401 405 402 406 // Find the next thread(s) to run … … 473 477 monitor_ctx( this.monitors, this.monitor_count ); 474 478 479 verify( disable_preempt_count == 0 ); 480 475 481 // Lock all monitors (aggregates the locks them as well) 476 482 lock_all( monitors, locks, count ); 483 484 // verify( disable_preempt_count == count ); 485 if(disable_preempt_count != count) { __cfaabi_dbg_print_buffer_decl("----------Gonna crash\n"); } 486 477 487 478 488 // Create the node specific to this wait operation … … 737 747 static inline void lock_all( __spinlock_t * locks [], __lock_size_t count ) { 738 748 for( __lock_size_t i = 0; i < count; i++ ) { 739 DO_LOCK( *locks[i] __cfaabi_dbg_ctx2 );749 lock( *locks[i] __cfaabi_dbg_ctx2 ); 740 750 } 741 751 } … … 744 754 for( __lock_size_t i = 0; i < count; i++ ) { 745 755 __spinlock_t * l = &source[i]->lock; 746 DO_LOCK( *l __cfaabi_dbg_ctx2 );756 lock( *l __cfaabi_dbg_ctx2 ); 747 757 if(locks) locks[i] = l; 748 758 } -
src/libcfa/concurrency/preemption.c
rbc6f918 re2e7330 19 19 extern "C" { 20 20 #include <errno.h> 21 #include <execinfo.h>22 #define __USE_GNU23 #include <signal.h>24 #undef __USE_GNU25 21 #include <stdio.h> 26 22 #include <string.h> … … 29 25 #undef ftype 30 26 31 #ifdef __USE_STREAM__ 32 #include "fstream" 33 #endif 27 #include "bits/signal.h" 34 28 35 29 //TODO move to defaults … … 40 34 return __CFA_DEFAULT_PREEMPTION__; 41 35 } 42 43 // Short hands for signal context information44 #define __CFA_SIGCXT__ ucontext_t *45 #define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt46 36 47 37 // FwdDeclarations : timeout handlers … … 53 43 void sigHandler_segv ( __CFA_SIGPARMS__ ); 54 44 void sigHandler_abort ( __CFA_SIGPARMS__ ); 55 56 // FwdDeclarations : sigaction wrapper57 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );58 45 59 46 // FwdDeclarations : alarm thread main … … 73 60 static pthread_t alarm_thread; // pthread handle to alarm thread 74 61 75 void ?{}(event_kernel_t & this) {76 (this.alarms){};77 (this.lock){};62 void ?{}(event_kernel_t & this) with( this ) { 63 alarms{}; 64 lock{}; 78 65 } 79 66 … … 162 149 // If counter reaches 0, execute any pending CtxSwitch 163 150 void enable_interrupts( __cfaabi_dbg_ctx_param ) { 164 processor * proc= this_processor; // Cache the processor now since interrupts can start happening after the atomic add151 processor * proc = this_processor; // Cache the processor now since interrupts can start happening after the atomic add 165 152 thread_desc * thrd = this_thread; // Cache the thread now since interrupts can start happening after the atomic add 166 153 … … 182 169 void enable_interrupts_noPoll() { 183 170 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 184 verify ( prev != 0u); // If this triggers someone is enabled already enabled interrupts171 verifyf( prev != 0u, "Incremented from %u\n", prev ); // If this triggers someone is enabled already enabled interrupts 185 172 } 186 173 } … … 246 233 // Setup proper signal handlers 247 234 __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART ); // CtxSwitch handler 248 // __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); // Failure handler249 // __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); // Failure handler250 235 251 236 signal_block( SIGALRM ); … … 308 293 if( !preemption_ready() ) { return; } 309 294 310 //__cfaabi_dbg_print_buffer_decl(" KERNEL: preempting core %p (%p).\n", this_processor, this_thread);295 __cfaabi_dbg_print_buffer_decl(" KERNEL: preempting core %p (%p).\n", this_processor, this_thread); 311 296 312 297 preemption_in_progress = true; // Sync flag : prevent recursive calls to the signal handler … … 380 365 } 381 366 382 // Sigaction wrapper : register an signal handler383 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) {384 struct sigaction act;385 386 act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;387 act.sa_flags = flags;388 389 if ( sigaction( sig, &act, NULL ) == -1 ) {390 __cfaabi_dbg_print_buffer_decl(391 " __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",392 sig, handler, flags, errno, strerror( errno )393 );394 _exit( EXIT_FAILURE );395 }396 }397 398 // Sigaction wrapper : restore default handler399 static void __kernel_sigdefault( int sig ) {400 struct sigaction act;401 402 act.sa_handler = SIG_DFL;403 act.sa_flags = 0;404 sigemptyset( &act.sa_mask );405 406 if ( sigaction( sig, &act, NULL ) == -1 ) {407 __cfaabi_dbg_print_buffer_decl(408 " __kernel_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n",409 sig, errno, strerror( errno )410 );411 _exit( EXIT_FAILURE );412 }413 }414 415 //=============================================================================================416 // Terminating Signals logic417 //=============================================================================================418 419 __cfaabi_dbg_debug_do(420 static void __kernel_backtrace( int start ) {421 // skip first N stack frames422 423 enum { Frames = 50 };424 void * array[Frames];425 int size = backtrace( array, Frames );426 char ** messages = backtrace_symbols( array, size );427 428 // find executable name429 *index( messages[0], '(' ) = '\0';430 #ifdef __USE_STREAM__431 serr | "Stack back trace for:" | messages[0] | endl;432 #else433 fprintf( stderr, "Stack back trace for: %s\n", messages[0]);434 #endif435 436 // skip last 2 stack frames after main437 for ( int i = start; i < size && messages != NULL; i += 1 ) {438 char * name = NULL;439 char * offset_begin = NULL;440 char * offset_end = NULL;441 442 for ( char *p = messages[i]; *p; ++p ) {443 // find parantheses and +offset444 if ( *p == '(' ) {445 name = p;446 }447 else if ( *p == '+' ) {448 offset_begin = p;449 }450 else if ( *p == ')' ) {451 offset_end = p;452 break;453 }454 }455 456 // if line contains symbol print it457 int frameNo = i - start;458 if ( name && offset_begin && offset_end && name < offset_begin ) {459 // delimit strings460 *name++ = '\0';461 *offset_begin++ = '\0';462 *offset_end++ = '\0';463 464 #ifdef __USE_STREAM__465 serr | "(" | frameNo | ")" | messages[i] | ":"466 | name | "+" | offset_begin | offset_end | endl;467 #else468 fprintf( stderr, "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end);469 #endif470 }471 // otherwise, print the whole line472 else {473 #ifdef __USE_STREAM__474 serr | "(" | frameNo | ")" | messages[i] | endl;475 #else476 fprintf( stderr, "(%i) %s\n", frameNo, messages[i] );477 #endif478 }479 }480 481 free( messages );482 }483 )484 485 // void sigHandler_segv( __CFA_SIGPARMS__ ) {486 // __cfaabi_dbg_debug_do(487 // #ifdef __USE_STREAM__488 // serr | "*CFA runtime error* program cfa-cpp terminated with"489 // | (sig == SIGSEGV ? "segment fault." : "bus error.")490 // | endl;491 // #else492 // fprintf( stderr, "*CFA runtime error* program cfa-cpp terminated with %s\n", sig == SIGSEGV ? "segment fault." : "bus error." );493 // #endif494 495 // // skip first 2 stack frames496 // __kernel_backtrace( 1 );497 // )498 // exit( EXIT_FAILURE );499 // }500 501 // void sigHandler_abort( __CFA_SIGPARMS__ ) {502 // // skip first 6 stack frames503 // __cfaabi_dbg_debug_do( __kernel_backtrace( 6 ); )504 505 // // reset default signal handler506 // __kernel_sigdefault( SIGABRT );507 508 // raise( SIGABRT );509 // }510 511 367 // Local Variables: // 512 368 // mode: c // -
src/libcfa/concurrency/thread.c
rbc6f918 re2e7330 31 31 // Thread ctors and dtors 32 32 33 void ?{}(thread_desc& this) { 34 (this.self_cor){}; 35 this.self_cor.name = "Anonymous Coroutine"; 36 this.self_mon.owner = &this; 37 this.self_mon.recursion = 1; 38 this.self_mon_p = &this.self_mon; 39 this.next = NULL; 33 void ?{}(thread_desc& this) with( this ) { 34 self_cor{}; 35 self_cor.name = "Anonymous Coroutine"; 36 self_mon.owner = &this; 37 self_mon.recursion = 1; 38 self_mon_p = &self_mon; 39 next = NULL; 40 __cfaabi_dbg_debug_do( 41 dbg_next = NULL; 42 dbg_prev = NULL; 43 __cfaabi_dbg_thread_register(&this); 44 ) 40 45 41 (this.monitors){ &this.self_mon_p, 1, (fptr_t)0 };46 monitors{ &self_mon_p, 1, (fptr_t)0 }; 42 47 } 43 48 44 void ^?{}(thread_desc& this) {45 ^ (this.self_cor){};49 void ^?{}(thread_desc& this) with( this ) { 50 ^self_cor{}; 46 51 } 47 52 48 53 forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } ) 49 void ?{}( scoped(T)& this ) {50 (this.handle){};51 __thrd_start( this.handle);54 void ?{}( scoped(T)& this ) with( this ) { 55 handle{}; 56 __thrd_start(handle); 52 57 } 53 58 54 59 forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T&, P); } ) 55 void ?{}( scoped(T)& this, P params ) {56 (this.handle){ params };57 __thrd_start( this.handle);60 void ?{}( scoped(T)& this, P params ) with( this ) { 61 handle{ params }; 62 __thrd_start(handle); 58 63 } 59 64 60 65 forall( dtype T | sized(T) | is_thread(T) ) 61 void ^?{}( scoped(T)& this ) {62 ^ (this.handle){};66 void ^?{}( scoped(T)& this ) with( this ) { 67 ^handle{}; 63 68 } 64 69 … … 68 73 void __thrd_start( T& this ) { 69 74 coroutine_desc* thrd_c = get_coroutine(this); 70 thread_desc *thrd_h = get_thread (this);75 thread_desc * thrd_h = get_thread (this); 71 76 thrd_c->last = this_coroutine; 72 77 -
src/libcfa/interpose.c
rbc6f918 re2e7330 22 22 #include <dlfcn.h> 23 23 #include <unistd.h> 24 #define __USE_GNU 25 #include <signal.h> 26 #undef __USE_GNU 27 #include <execinfo.h> 24 28 } 25 29 26 30 #include "bits/debug.h" 27 31 #include "bits/defs.h" 32 #include "bits/signal.h" 28 33 #include "startup.h" 29 34 30 void interpose_startup(void) __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));35 void __cfaabi_interpose_startup(void) __attribute__(( constructor( STARTUP_PRIORITY_CORE ) )); 31 36 32 37 typedef void (*generic_fptr_t)(void); … … 84 89 #define INIT_REALRTN( x, ver ) assign_ptr( (void**)&libc_##x, #x, ver) 85 90 86 void interpose_startup() { 91 void sigHandler_segv ( __CFA_SIGPARMS__ ); 92 void sigHandler_abort( __CFA_SIGPARMS__ ); 93 94 void __cfaabi_interpose_startup() { 87 95 const char *version = NULL; 88 96 89 97 INIT_REALRTN( abort, version ); 90 98 INIT_REALRTN( exit, version ); 91 } 99 100 __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); // Failure handler 101 __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); // Failure handler 102 __kernel_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO ); // Failure handler 103 } 104 105 //============================================================================================= 106 // Terminating Signals logic 107 //============================================================================================= 92 108 93 109 extern "C" { … … 137 153 libc_abort(); 138 154 } 155 } 156 157 // skip first 6 stack frames by default 158 static void __kernel_backtrace() { 159 // skip first N stack frames 160 int start = 6; 161 162 enum { Frames = 50 }; 163 void * array[Frames]; 164 int size = backtrace( array, Frames ); 165 char ** messages = backtrace_symbols( array, size ); 166 167 // find executable name 168 *index( messages[0], '(' ) = '\0'; 169 __cfaabi_dbg_bits_print_nolock( "Stack back trace for: %s\n", messages[0]); 170 171 // skip last 2 stack frames after main 172 for ( int i = start; i < size && messages != NULL; i += 1 ) { 173 char * name = NULL; 174 char * offset_begin = NULL; 175 char * offset_end = NULL; 176 177 for ( char *p = messages[i]; *p; ++p ) { 178 // find parantheses and +offset 179 if ( *p == '(' ) { 180 name = p; 181 } 182 else if ( *p == '+' ) { 183 offset_begin = p; 184 } 185 else if ( *p == ')' ) { 186 offset_end = p; 187 break; 188 } 189 } 190 191 // if line contains symbol print it 192 int frameNo = i - start; 193 if ( name && offset_begin && offset_end && name < offset_begin ) { 194 // delimit strings 195 *name++ = '\0'; 196 *offset_begin++ = '\0'; 197 *offset_end++ = '\0'; 198 199 __cfaabi_dbg_bits_print_nolock( "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end); 200 } 201 // otherwise, print the whole line 202 else { 203 __cfaabi_dbg_bits_print_nolock( "(%i) %s\n", frameNo, messages[i] ); 204 } 205 } 206 207 free( messages ); 208 } 209 210 void sigHandler_segv( __CFA_SIGPARMS__ ) { 211 // skip first only 1 stack frames in case of segfault. 212 abortf( "*CFA runtime error* program cfa-cpp terminated with %s\n", sig == SIGSEGV ? "segment fault." : "bus error." ); 213 } 214 215 void sigHandler_abort( __CFA_SIGPARMS__ ) { 216 __kernel_backtrace(); 217 218 // reset default signal handler 219 __kernel_sigdefault( SIGABRT ); 220 221 raise( SIGABRT ); 139 222 } 140 223 -
src/libcfa/interpose.h
rbc6f918 re2e7330 16 16 #pragma once 17 17 18 void * interpose_symbol( const char* symbol, ,const char *version );18 void * interpose_symbol( const char* symbol, const char *version ); 19 19 20 20 extern __typeof__( abort ) libc_abort __attribute__(( noreturn )); -
src/prelude/prelude.cf
rbc6f918 re2e7330 39 39 // ------------------------------------------------------------ 40 40 41 _Bool ?++( _Bool & ), ?++( volatile _Bool & );42 _Bool ?--( _Bool & ), ?--( volatile _Bool & );43 41 signed short ?++( signed short & ), ?++( volatile signed short & ); 44 42 signed short ?--( signed short & ), ?--( volatile signed short & ); … … 94 92 // ------------------------------------------------------------ 95 93 96 _Bool ++?( _Bool & ), --?( _Bool & );97 94 signed short ++?( signed short & ), --?( signed short & ); 98 95 signed int ++?( signed int & ), --?( signed int & ); … … 125 122 forall( ftype FT ) FT & *?( FT * ); 126 123 127 _Bool +?( _Bool ), -?( _Bool ) , ~?( _Bool );124 _Bool +?( _Bool ), -?( _Bool ); 128 125 signed int +?( signed int ), -?( signed int ), ~?( signed int ); 129 126 unsigned int +?( unsigned int ), -?( unsigned int ), ~?( unsigned int ); … … 157 154 // ------------------------------------------------------------ 158 155 159 _Bool ?*?( _Bool, _Bool ), ?/?( _Bool, _Bool ), ?%?( _Bool, _Bool );160 156 signed int ?*?( signed int, signed int ), ?/?( signed int, signed int ), ?%?( signed int, signed int ); 161 157 unsigned int ?*?( unsigned int, unsigned int ), ?/?( unsigned int, unsigned int ), ?%?( unsigned int, unsigned int ); … … 215 211 // ------------------------------------------------------------ 216 212 217 _Bool ?<<?( _Bool, _Bool ), ?>>?( _Bool, _Bool );218 213 signed int ?<<?( signed int, signed int ), ?>>?( signed int, signed int ); 219 214 unsigned int ?<<?( unsigned int, unsigned int ), ?>>?( unsigned int, unsigned int ); … … 467 462 468 463 469 _Bool ?*=?( _Bool &, _Bool ), ?*=?( volatile _Bool &, _Bool );470 464 char ?*=?( char &, char ), ?*=?( volatile char &, char ); 471 465 char signed ?*=?( char signed &, char signed ), ?*=?( volatile char signed &, char signed ); … … 534 528 unsigned long long int ?-=?( unsigned long long int &, unsigned long long int ), ?-=?( volatile unsigned long long int &, unsigned long long int ); 535 529 536 _Bool ?<<=?( _Bool &, _Bool ), ?<<=?( volatile _Bool &, _Bool );537 530 char ?<<=?( char &, char ), ?<<=?( volatile char &, char ); 538 531 char signed ?<<=?( char signed &, char signed ), ?<<=?( volatile char signed &, char signed ); … … 547 540 unsigned long long int ?<<=?( unsigned long long int &, unsigned long long int ), ?<<=?( volatile unsigned long long int &, unsigned long long int ); 548 541 549 _Bool ?>>=?( _Bool &, _Bool ), ?>>=?( volatile _Bool &, _Bool );550 542 char ?>>=?( char &, char ), ?>>=?( volatile char &, char ); 551 543 char signed ?>>=?( char signed &, char signed ), ?>>=?( volatile char signed &, char signed ); -
src/tests/Makefile.am
rbc6f918 re2e7330 65 65 66 66 concurrency : 67 @+python test.py --debug=${debug} ${concurrent} ${concurrent_test}67 @+python test.py --debug=${debug} -Iconcurrent 68 68 69 69 .dummy : .dummy.c @CFA_BINDIR@/@CFA_NAME@ -
src/tests/Makefile.in
rbc6f918 re2e7330 743 743 744 744 concurrency : 745 @+python test.py --debug=${debug} ${concurrent} ${concurrent_test}745 @+python test.py --debug=${debug} -Iconcurrent 746 746 747 747 .dummy : .dummy.c @CFA_BINDIR@/@CFA_NAME@ -
src/tests/concurrent/examples/quickSort.c
rbc6f918 re2e7330 9 9 // Created On : Wed Dec 6 12:15:52 2017 10 10 // Last Modified By : Peter A. Buhr 11 // Last Modified On : Mon Jan 29 08:41:37201812 // Update Count : 1 5511 // Last Modified On : Tue Jan 30 15:58:58 2018 12 // Update Count : 162 13 13 // 14 14 … … 100 100 if ( argc != 1 ) { // do not use defaults 101 101 if ( argc < 2 || argc > 4 ) usage( argv ); // wrong number of options 102 // if ( strcmp( argv[1], "-t" ) == 0 ) { // timing ? 103 if ( argv[1][0] == '-' && argv[1][1] == 't' ) { // timing ? 102 if ( strcmp( argv[1], "-t" ) == 0 ) { // timing ? 104 103 &unsortedfile = (ifstream *)0; // no input 105 104 choose ( argc ) { -
src/tests/functions.c
rbc6f918 re2e7330 10 10 // Created On : Wed Aug 17 08:39:58 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Nov 27 18:08:54 201713 // Update Count : 1 112 // Last Modified On : Wed Jan 17 22:44:12 2018 13 // Update Count : 12 14 14 // 15 15 … … 25 25 void g(void) 26 26 ) { 27 (* g)();27 (* g)(); 28 28 g(); 29 29 g = h; … … 32 32 int f1() {} 33 33 int (f2()) {} 34 int (* f3())() {}35 int * ((f4())) {}36 int ((* f5()))() {}37 int * f6() {}38 int * (f7)() {}39 int ** f8() {}40 int * const * (f9)() {}41 int (* f10())[] {}42 int (* f11())[][3] {}43 int ((* f12())[])[3] {}34 int (* f3())() {} 35 int * ((f4())) {} 36 int ((* f5()))() {} 37 int * f6() {} 38 int * (f7)() {} 39 int ** f8() {} 40 int * const * (f9)() {} 41 int (* f10())[] {} 42 int (* f11())[][3] {} 43 int ((* f12())[])[3] {} 44 44 45 45 // "implicit int" otype specifier (not ANSI) … … 50 50 extern const fII4( int i ) {} 51 51 52 * fII5() {}53 const * fII6() {}54 const long * fII7() {}55 static const long * fII8() {}56 const static long * fII9() {}52 * fII5() {} 53 const * fII6() {} 54 const long * fII7() {} 55 static const long * fII8() {} 56 const static long * fII9() {} 57 57 58 58 // K&R function definitions … … 117 117 [int](int) 118 118 ) { 119 int (* (*pc)[][10])[][3];119 int (* (* pc)[][10])[][3]; 120 120 * [][10] * [][3] int p; 121 121 * [] * [int](int) p; 122 122 } 123 123 124 static const int * f1() {}124 static const int * f1() {} 125 125 static [ const int ] f2() {} 126 126 static inline [ const * int ] f3() {} … … 133 133 int (), 134 134 135 int * (),136 int ** (),137 int * const * (),135 int * (), 136 int ** (), 137 int * const * (), 138 138 int * const * const (), 139 139 … … 141 141 int ([10]), 142 142 143 int * ([]),144 int * ([10]),145 int ** ([]),146 int ** ([10]),147 int * const * ([]),148 int * const * ([10]),143 int * ([]), 144 int * ([10]), 145 int ** ([]), 146 int ** ([10]), 147 int * const * ([]), 148 int * const * ([10]), 149 149 int * const * const ([]), 150 150 int * const * const ([10]) … … 154 154 int (), 155 155 156 int * (),157 int ** (),158 int * const * (),156 int * (), 157 int ** (), 158 int * const * (), 159 159 int * const * const (), 160 160 … … 162 162 int ([10]), 163 163 164 int * ([]),165 int * ([10]),166 int ** ([]),167 int ** ([10]),168 int * const * ([]),169 int * const * ([10]),164 int * ([]), 165 int * ([10]), 166 int ** ([]), 167 int ** ([10]), 168 int * const * ([]), 169 int * const * ([10]), 170 170 int * const * const ([]), 171 171 int * const * const ([10]) … … 175 175 typedef int T; 176 176 177 int f( T (* f), T t ) {177 int f( T (* f), T t ) { 178 178 T (T); 179 179 } … … 184 184 //int (f[])() {} 185 185 //int f[]() {} 186 //int ((* f15())())[] {}186 //int ((* f15())())[] {} 187 187 188 188 // Local Variables: // -
src/tests/identFuncDeclarator.c
rbc6f918 re2e7330 10 10 // Created On : Wed Aug 17 08:36:34 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Aug 17 08:37:06 201613 // Update Count : 112 // Last Modified On : Wed Jan 17 22:39:13 2018 13 // Update Count : 2 14 14 // 15 15 … … 18 18 int (f2); 19 19 20 int * f3;21 int ** f4;22 int * const * f5;20 int * f3; 21 int ** f4; 22 int * const * f5; 23 23 int * const * const f6; 24 24 25 int * (f7);26 int ** (f8);27 int * const * (f9);25 int * (f7); 26 int ** (f8); 27 int * const * (f9); 28 28 int * const * const (f10); 29 29 30 int (* f11);31 int (** f12);32 int (* const * f13);30 int (* f11); 31 int (** f12); 32 int (* const * f13); 33 33 int (* const * const f14); 34 34 … … 38 38 int (f18[10]); 39 39 40 int * f19[2];41 int * f20[10];42 int ** f21[2];43 int ** f22[10];44 int * const * f23[2];45 int * const * f24[10];40 int * f19[2]; 41 int * f20[10]; 42 int ** f21[2]; 43 int ** f22[10]; 44 int * const * f23[2]; 45 int * const * f24[10]; 46 46 int * const * const f25[2]; 47 47 int * const * const f26[10]; 48 48 49 int * (f27[2]);50 int * (f28[10]);51 int ** (f29[2]);52 int ** (f30[10]);53 int * const * (f31[2]);54 int * const * (f32[10]);49 int * (f27[2]); 50 int * (f28[10]); 51 int ** (f29[2]); 52 int ** (f30[10]); 53 int * const * (f31[2]); 54 int * const * (f32[10]); 55 55 int * const * const (f33[2]); 56 56 int * const * const (f34[10]); 57 57 58 int (* f35[2]);59 int (* f36[10]);60 int (** f37[2]);61 int (** f38[10]);62 int (* const * f39[2]);63 int (* const * f40[10]);58 int (* f35[2]); 59 int (* f36[10]); 60 int (** f37[2]); 61 int (** f38[10]); 62 int (* const * f39[2]); 63 int (* const * f40[10]); 64 64 int (* const * const f41[2]); 65 65 int (* const * const f42[10]); … … 72 72 int ((f48[3]))[3]; 73 73 74 int * f49[2][3];75 int * f50[3][3];76 int ** f51[2][3];77 int ** f52[3][3];78 int * const * f53[2][3];79 int * const * f54[3][3];74 int * f49[2][3]; 75 int * f50[3][3]; 76 int ** f51[2][3]; 77 int ** f52[3][3]; 78 int * const * f53[2][3]; 79 int * const * f54[3][3]; 80 80 int * const * const f55[2][3]; 81 81 int * const * const f56[3][3]; 82 82 83 int (* f57[2][3]);84 int (* f58[3][3]);85 int (** f59[2][3]);86 int (** f60[3][3]);87 int (* const * f61[2][3]);88 int (* const * f62[3][3]);83 int (* f57[2][3]); 84 int (* f58[3][3]); 85 int (** f59[2][3]); 86 int (** f60[3][3]); 87 int (* const * f61[2][3]); 88 int (* const * f62[3][3]); 89 89 int (* const * const f63[2][3]); 90 90 int (* const * const f64[3][3]); … … 93 93 int (f66)(int); 94 94 95 int * f67(int);96 int ** f68(int);97 int * const * f69(int);95 int * f67(int); 96 int ** f68(int); 97 int * const * f69(int); 98 98 int * const * const f70(int); 99 99 100 int * (f71)(int);101 int ** (f72)(int);102 int * const * (f73)(int);100 int * (f71)(int); 101 int ** (f72)(int); 102 int * const * (f73)(int); 103 103 int * const * const (f74)(int); 104 104 105 int (* f75)(int);106 int (** f76)(int);107 int (* const * f77)(int);105 int (* f75)(int); 106 int (** f76)(int); 107 int (* const * f77)(int); 108 108 int (* const * const f78)(int); 109 109 110 int (* (*f79)(int))();111 int (* (* const f80)(int))();110 int (* (* f79)(int))(); 111 int (* (* const f80)(int))(); 112 112 int (* const(* const f81)(int))(); 113 113 } -
src/tests/identParamDeclarator.c
rbc6f918 re2e7330 10 10 // Created On : Wed Aug 17 08:37:56 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Aug 17 08:38:42 201613 // Update Count : 112 // Last Modified On : Wed Jan 17 22:36:11 2018 13 // Update Count : 2 14 14 // 15 15 16 int fred (16 int fred ( 17 17 int f1, 18 18 int (f2), … … 157 157 ); 158 158 159 //Dummy main 160 int main(int argc, char const *argv[]) 161 { 159 int main( int argc, char const *argv[] ) { // dummy main 162 160 return 0; 163 161 } -
src/tests/preempt_longrun/Makefile.am
rbc6f918 re2e7330 19 19 preempt=1_000ul 20 20 21 REPEAT = ${abs_top_srcdir}/tools/repeat -s 21 REPEAT = ${abs_top_srcdir}/tools/repeat 22 TIME = /usr/bin/time -f "%E" 22 23 23 24 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -debug -O2 -DPREEMPTION_RATE=${preempt} … … 37 38 ${AM_V_GEN}${CC} ${CFLAGS} ${<} -o ${@} 38 39 39 %.run : % 40 @ time ${REPEAT} $(repeats) timeout ${max_time} ./${<}40 %.run : % ${REPEAT} 41 @ time ${REPEAT} -r out.log -i -s $(repeats) timeout ${max_time} ./${<} 41 42 @ rm ${<} 42 43 @ echo -e "${<}: SUCCESS\n" 44 45 %.time : % ${REPEAT} 46 @ ${REPEAT} -i -s -- $(repeats) $(TIME) -a -o times.log ./${<} 47 @ rm ${<} 48 @ echo -e "${<}: SUCCESS\n" 49 50 ${REPEAT}: 51 @+make -C ${abs_top_srcdir}/tools/ -
src/tests/preempt_longrun/Makefile.in
rbc6f918 re2e7330 451 451 max_time = 600 452 452 preempt = 1_000ul 453 REPEAT = ${abs_top_srcdir}/tools/repeat -s 453 REPEAT = ${abs_top_srcdir}/tools/repeat 454 TIME = /usr/bin/time -f "%E" 454 455 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -debug -O2 -DPREEMPTION_RATE=${preempt} 455 456 TESTS = block create disjoint enter enter3 processor stack wait yield … … 874 875 ${AM_V_GEN}${CC} ${CFLAGS} ${<} -o ${@} 875 876 876 %.run : % 877 @ time ${REPEAT} $(repeats) timeout ${max_time} ./${<}877 %.run : % ${REPEAT} 878 @ time ${REPEAT} -r out.log -i -s $(repeats) timeout ${max_time} ./${<} 878 879 @ rm ${<} 879 880 @ echo -e "${<}: SUCCESS\n" 881 882 %.time : % ${REPEAT} 883 @ ${REPEAT} -i -s -- $(repeats) $(TIME) -a -o times.log ./${<} 884 @ rm ${<} 885 @ echo -e "${<}: SUCCESS\n" 886 887 ${REPEAT}: 888 @+make -C ${abs_top_srcdir}/tools/ 880 889 881 890 # Tell versions [3.59,3.63) of GNU make to not export all variables. -
src/tests/preempt_longrun/block.c
rbc6f918 re2e7330 1 ../ sched-int-block.c1 ../concurrent/signal/block.c -
src/tests/preempt_longrun/create.c
rbc6f918 re2e7330 14 14 thread worker_t {}; 15 15 16 void main(worker_t *this) {}16 void main(worker_t & this) {} 17 17 18 18 int main(int argc, char* argv[]) { -
src/tests/preempt_longrun/disjoint.c
rbc6f918 re2e7330 1 ../ sched-int-disjoint.c1 ../concurrent/signal/disjoint.c -
src/tests/preempt_longrun/enter.c
rbc6f918 re2e7330 17 17 mon_t mon; 18 18 19 void foo( mon_t *mutex this ) {}19 void foo( mon_t & mutex this ) {} 20 20 21 21 thread worker_t {}; 22 22 23 void main( worker_t *this ) {23 void main( worker_t & this ) { 24 24 for( unsigned long i = 0; i < N; i++ ) { 25 foo( &mon );25 foo( mon ); 26 26 } 27 27 } -
src/tests/preempt_longrun/enter3.c
rbc6f918 re2e7330 17 17 mon_t mon1, mon2, mon3; 18 18 19 void foo( mon_t * mutex a, mon_t * mutex b, mon_t *mutex c ) {}19 void foo( mon_t & mutex a, mon_t & mutex b, mon_t & mutex c ) {} 20 20 21 21 thread worker_t {}; 22 22 23 void main( worker_t *this ) {23 void main( worker_t & this ) { 24 24 for( unsigned long i = 0; i < N; i++ ) { 25 foo( &mon1, &mon2, &mon3 );25 foo( mon1, mon2, mon3 ); 26 26 } 27 27 } -
src/tests/preempt_longrun/processor.c
rbc6f918 re2e7330 14 14 thread worker_t {}; 15 15 16 void main(worker_t *this) {}16 void main(worker_t & this) {} 17 17 18 18 int main(int argc, char* argv[]) { -
src/tests/preempt_longrun/stack.c
rbc6f918 re2e7330 14 14 thread worker_t {}; 15 15 16 void main(worker_t *this) {16 void main(worker_t & this) { 17 17 volatile long long p = 5_021_609ul; 18 18 volatile long long a = 326_417ul; -
src/tests/preempt_longrun/wait.c
rbc6f918 re2e7330 1 ../ sched-int-wait.c1 ../concurrent/signal/wait.c -
src/tests/preempt_longrun/yield.c
rbc6f918 re2e7330 14 14 thread worker_t {}; 15 15 16 void main(worker_t *this) {16 void main(worker_t & this) { 17 17 for(int i = 0; i < N; i++) { 18 18 yield();
Note: See TracChangeset
for help on using the changeset viewer.