Changes in / [e2e7330:bc6f918]


Ignore:
Files:
8 added
9 deleted
50 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    re2e7330 rbc6f918  
    99config.log
    1010stamp-h1
    11 /Makefile
    12 src/**/Makefile
    13 tools/**/Makefile
     11Makefile
     12driver/Makefile
     13libcfa/Makefile
     14src/Makefile
    1415/version
    1516
  • Jenkinsfile

    re2e7330 rbc6f918  
    174174
    175175def notify_server(int wait) {
    176         sh """curl --data "wait=${wait}" -X POST http://plg2:8082/jenkins/notify > /dev/null || true"""
     176        sh """curl --silent --data "wait=${wait}" -X POST http://plg2:8082/jenkins/notify > /dev/null || true"""
    177177        return
    178178}
     
    324324
    325325                //Then publish the results
    326                 sh 'curl -H \'Content-Type: application/json\' --data @bench.json http://plg2:8082/jenkins/publish > /dev/null || true'
     326                sh 'curl -H "Content-Type: application/json" --silent --data @bench.json http://plg2:8082/jenkins/publish > /dev/null || true'
    327327        }
    328328}
  • doc/papers/OOPSLA17/.gitignore

    re2e7330 rbc6f918  
    11# generated by latex
    2 build/*
     2*.aux
     3*.bbl
     4*.blg
     5*.brf
     6*.dvi
     7*.idx
     8*.ilg
     9*.ind
     10*.log
     11*.out
    312*.pdf
    413*.ps
     14*.toc
     15*.lof
     16*.lot
     17*.synctex.gz
     18comment.cut
     19timing.tex
  • doc/papers/OOPSLA17/Makefile

    re2e7330 rbc6f918  
    1 ## Define the configuration variables.
     1## Define the appropriate configuration variables.
    22
    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}
     3TeXLIB = .:../LaTeXmacros:../LaTeXmacros/listings:../LaTeXmacros/enumitem:../bibliography/:
     4LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error
    85BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
    9 
    10 MAKEFLAGS = --no-print-directory --silent #
    11 VPATH = ${Figures} evaluation
    126
    137## Define the text source files.
     
    3933
    4034clean :
    41         @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build}
     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}
    4237
    4338# File Dependencies #
     
    4742
    4843${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
    49         dvips ${Build}/$< -o $@
     44        dvips $< -o $@
    5045
    51 ${basename ${DOCUMENT}}.dvi : Makefile ${Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ../../bibliography/pl.bib
     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
    5251        # Must have *.aux file containing citations for bibtex
    5352        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
    54         -${BibTeX} ${Build}/${basename $@}
    55         # Some citations reference others so run again to resolve these citations
     53        -${BibTeX} ${basename $@}
     54        # Some citations reference others so run steps again to resolve these citations
    5655        ${LaTeX} ${basename $@}.tex
    57         -${BibTeX} ${Build}/${basename $@}
    58         # Run again to finish citations
     56        -${BibTeX} ${basename $@}
     57        # Make index from *.aux entries and input index at end of document
     58        makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx
    5959        ${LaTeX} ${basename $@}.tex
     60        # Run again to get index title into table of contents
     61        ${LaTeX} ${basename $@}.tex
     62
     63predefined :
     64        sed -f predefined.sed ${basename ${DOCUMENT}}.tex > ${basename $@}.cf
    6065
    6166## Define the default recipes.
    6267
    63 ${Build}:
    64         mkdir -p ${Build}
    65 
    66 ${GRAPHS} : timing.gp timing.dat
    67         gnuplot -e Build="'${Build}/'" evaluation/timing.gp
     68${GRAPHS} : evaluation/timing.gp evaluation/timing.dat
     69        gnuplot evaluation/timing.gp
    6870
    6971%.tex : %.fig
    70         fig2dev -L eepic $< > ${Build}/$@
     72        fig2dev -L eepic $< > $@
    7173
    7274%.ps : %.fig
    73         fig2dev -L ps $< > ${Build}/$@
     75        fig2dev -L ps $< > $@
    7476
    7577%.pstex : %.fig
    76         fig2dev -L pstex $< > ${Build}/$@
    77         fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
     78        fig2dev -L pstex $< > $@
     79        fig2dev -L pstex_t -p $@ $< > $@_t
    7880
    7981# Local Variables: #
  • doc/papers/OOPSLA17/evaluation/timing.gp

    re2e7330 rbc6f918  
    22# set output "timing.pdf"
    33set terminal pslatex size 6.25,2.125 color solid
    4 set output Build."timing.tex"
     4set output "timing.tex"
    55
    66set pointsize 2.0
  • doc/papers/OOPSLA17/generic_types.tex

    re2e7330 rbc6f918  
    11091109
    11101110\bibliographystyle{ACM-Reference-Format}
    1111 \bibliography{pl}
     1111\bibliography{cfa}
    11121112
    11131113
  • doc/papers/concurrency/.gitignore

    re2e7330 rbc6f918  
    1 # generated by latex
    2 build/*
     1build/*.aux
     2build/*.acn
     3build/*.acr
     4build/*.alg
     5build/*.bbl
     6build/*.blg
     7build/*.brf
     8build/*.dvi
     9build/*.glg
     10build/*.glo
     11build/*.gls
     12build/*.idx
     13build/*.ind
     14build/*.ist
     15build/*.lof
     16build/*.log
     17build/*.lol
     18build/*.lot
     19build/*.out
     20build/*.ps
     21build/*.pstex
     22build/*.pstex_t
     23build/*.tex
     24build/*.toc
    325*.pdf
    4 *.ps
     26*.png
     27figures/*.tex
     28
     29examples
  • doc/papers/concurrency/Paper.tex

    re2e7330 rbc6f918  
    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-^
     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-^
    79% math escape $...$ (dollar symbol)
    810
     
    1820\usepackage{epic,eepic}
    1921\usepackage{upquote}                                            % switch curled `'" to straight
     22\usepackage{dirtytalk}
    2023\usepackage{calc}
    2124\usepackage{xspace}
     
    4346\urlstyle{rm}
    4447
     48\usepackage{tikz}
     49\def\checkmark{\tikz\fill[scale=0.4](0,.35) -- (.25,0) -- (1,.7) -- (.25,.15) -- cycle;}
     50
    4551\setlength{\topmargin}{-0.45in}                         % move running title into header
    4652\setlength{\headsep}{0.25in}
     
    7278
    7379\title{Concurrency in \CFA}
    74 \author{Thierry Delisle and Peter A. Buhr, Waterloo, Ontario, Canada}
     80\author{Thierry Delisle, Waterloo, Ontario, Canada, 2018}
    7581
    7682
     
    7985
    8086\begin{abstract}
    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.
     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.
    8388\end{abstract}
    8489
     
    9095\section{Introduction}
    9196% ======================================================================
    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.
     97This 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.
    9498
    9599There 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.
    96100
    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.
     101In 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.
    98102
    99103% ======================================================================
     
    109113
    110114% ======================================================================
    111 \subsection{References}
     115\section{References}
    112116
    113117Like \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:
     
    128132
    129133% ======================================================================
    130 \subsection{Overloading}
     134\section{Overloading}
    131135
    132136Another 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.
     
    149153
    150154% ======================================================================
    151 \subsection{Operators}
     155\section{Operators}
    152156Overloading 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.:
    153157\begin{cfacode}
     
    169173
    170174% ======================================================================
    171 \subsection{Constructors/Destructors}
     175\section{Constructors/Destructors}
    172176Object 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:
    173177\begin{cfacode}
     
    204208
    205209% ======================================================================
    206 \subsection{Parametric Polymorphism}
     210\section{Parametric Polymorphism}
    207211\label{s:ParametricPolymorphism}
    208212Routines 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:
     
    237241
    238242% ======================================================================
    239 \subsection{with Clause/Statement}
     243\section{with Clause/Statement}
    240244Since \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).
    241245\begin{cfacode}
     
    282286
    283287\section{\protect\CFA's Thread Building Blocks}
    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.
     288One 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.
    285289
    286290\section{Coroutines: A Stepping Stone}\label{coroutine}
     
    660664\end{cfacode}
    661665
    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.
     666In this example, threads of type \code{foo} start execution in the \code{void main(foo &)} routine, which prints \code{"Hello World!".} While this thesis 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.
    663667\begin{cfacode}
    664668typedef void (*voidFunc)(int);
     
    995999% ======================================================================
    9961000% ======================================================================
    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.
     1001In 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 thesis 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.
    9981002
    9991003First, here is a simple example of internal scheduling:
     
    17961800A \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}.
    17971801
    1798 \textbf{cfacluster} have not been fully implemented in the context of this paper. Currently \CFA only supports one \textbf{cfacluster}, the initial one.
     1802\textbf{cfacluster} have not been fully implemented in the context of this thesis. Currently \CFA only supports one \textbf{cfacluster}, the initial one.
    17991803
    18001804\subsection{Future Work: Machine Setup}\label{machine}
    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.
     1805While 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.
    18021806
    18031807\subsection{Paradigms}\label{cfaparadigms}
     
    18111815The 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.
    18121816
    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.
     1817Note that since the major contributions of this thesis 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.
    18141818
    18151819% ======================================================================
     
    26112615
    26122616\section{Conclusion}
    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.
     2617This 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 thesis 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.
    26142618
    26152619
     
    26212625
    26222626\subsection{Performance} \label{futur:perf}
    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.
     2627This thesis 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.
    26242628
    26252629\subsection{Flexible Scheduling} \label{futur:sched}
     
    27252729\section{Acknowledgements}
    27262730
    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.
     2731I would like to thank my supervisor, Professor Peter Buhr, for his guidance through my degree as well as the editing of this document.
     2732
     2733I would like to thank Professors Martin Karsten and Gregor Richards, for reading my thesis and providing helpful feedback.
     2734
     2735Thanks 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
     2737Finally, 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.
    27292738
    27302739
     
    27352744
    27362745\end{document}
    2737 
    2738 % Local Variables: %
    2739 % tab-width: 4 %
    2740 % fill-column: 120 %
    2741 % compile-command: "make" %
    2742 % End: %
  • doc/papers/general/.gitignore

    re2e7330 rbc6f918  
    11# generated by latex
    2 build/*
     2*.aux
     3*.bbl
     4*.blg
     5*.brf
     6*.dvi
     7*.idx
     8*.ilg
     9*.ind
     10*.log
     11*.out
    312*.pdf
    413*.ps
     14*.toc
     15*.lof
     16*.lot
     17*.synctex.gz
     18comment.cut
     19timing.tex
  • doc/papers/general/Paper.tex

    re2e7330 rbc6f918  
    10951095
    10961096\bibliographystyle{plain}
    1097 \bibliography{pl}
     1097\bibliography{cfa}
    10981098
    10991099
  • doc/papers/general/evaluation/timing.gp

    re2e7330 rbc6f918  
    22# set output "timing.pdf"
    33set terminal pslatex size 6.25,2.125 color solid
    4 set output Build."timing.tex"
     4set output "timing.tex"
    55
    66set pointsize 2.0
  • doc/proposals/tuples/tuples.tex

    re2e7330 rbc6f918  
    322322\addcontentsline{toc}{section}{\refname}
    323323\bibliographystyle{plain}
    324 \bibliography{pl}
     324\bibliography{cfa}
    325325
    326326%\addcontentsline{toc}{section}{\indexname} % add index name to table of contents
  • doc/refrat/.gitignore

    re2e7330 rbc6f918  
    11# generated by latex
    2 build/*
     2*.aux
     3*.bbl
     4*.blg
     5*.brf
     6*.dvi
     7*.idx
     8*.ilg
     9*.ind
     10*.log
     11*.out
    312*.pdf
    413*.ps
     14*.toc
  • doc/refrat/Makefile

    re2e7330 rbc6f918  
    1 ## Define the configuration variables.
     1## Define the appropriate configuration variables.
    22
    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}
     3TeXLIB = .:../LaTeXmacros:../LaTeXmacros/listings:../LaTeXmacros/enumitem:../bibliography/:
     4LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error
    85BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
    9 
    10 MAKEFLAGS = --no-print-directory --silent #
    11 VPATH = ${Figures}
    126
    137## Define the text source files.
     
    3731# Directives #
    3832
    39 .PHONY : all clean                                      # not file names
    40 
    4133all : ${DOCUMENT}
    4234
    4335clean :
    44         @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build}
     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}
    4538
    4639# File Dependencies #
     
    5043
    5144${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
    52         dvips ${Build}/$< -o $@
     45        dvips $< -o $@
    5346
    54 ${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
     47${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \
     48                ../LaTeXmacros/common.tex ../LaTeXmacros/lstlang.sty ../LaTeXmacros/indexstyle ../bibliography/cfa.bib
    5649        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    57         if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi
     50        if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi
    5851        # Must have *.aux file containing citations for bibtex
    5952        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
    60         -${BibTeX} ${Build}/${basename $@}
    61         # Some citations reference others so run again to resolve these citations
     53        -${BibTeX} ${basename $@}
     54        # Some citations reference others so run steps again to resolve these citations
    6255        ${LaTeX} ${basename $@}.tex
    63         -${BibTeX} ${Build}/${basename $@}
     56        -${BibTeX} ${basename $@}
    6457        # Make index from *.aux entries and input index at end of document
    65         makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx
    66         # Run again to finish citations
     58        makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx
    6759        ${LaTeX} ${basename $@}.tex
    6860        # Run again to get index title into table of contents
     
    7466## Define the default recipes.
    7567
    76 ${Build}:
    77         mkdir -p ${Build}
    78 
    7968%.tex : %.fig
    80         fig2dev -L eepic $< > ${Build}/$@
     69        fig2dev -L eepic $< > $@
    8170
    8271%.ps : %.fig
    83         fig2dev -L ps $< > ${Build}/$@
     72        fig2dev -L ps $< > $@
    8473
    8574%.pstex : %.fig
    86         fig2dev -L pstex $< > ${Build}/$@
    87         fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
     75        fig2dev -L pstex $< > $@
     76        fig2dev -L pstex_t -p $@ $< > $@_t
    8877
    8978# Local Variables: #
  • doc/refrat/refrat.tex

    re2e7330 rbc6f918  
    1111%% Created On       : Wed Apr  6 14:52:25 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Wed Jan 31 17:30:23 2018
    14 %% Update Count     : 108
     13%% Last Modified On : Tue Aug 15 18:46:31 2017
     14%% Update Count     : 106
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    141141The manual deliberately imitates the ordering of the \Celeven standard (although the section numbering differs).
    142142Unfortunately, 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~\cite{Cforall}.
     143For a simple introduction to \CFA, see the companion document ``An Overview of \CFA''
     144\cite{Ditchfield96:Overview}.
    144145
    145146\begin{rationale}
     
    595596\begin{rationale}
    596597Since 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.
    597 Such an algorithm was first described (for Ada) by Baker~\cite{Baker82}.
     598Such an algorithm was first described (for Ada) by Baker~\cite{Bak:overload}.
    598599It is extended here to handle polymorphic functions and arithmetic conversions.
    599600The 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.
     
    37743775
    37753776\bibliographystyle{plain}
    3776 \bibliography{pl}
     3777\bibliography{cfa}
    37773778
    37783779
  • doc/user/.gitignore

    re2e7330 rbc6f918  
    11# generated by latex
    2 build/*
     2*.aux
     3*.bbl
     4*.blg
     5*.brf
     6*.dvi
     7*.idx
     8*.ilg
     9*.ind
     10*.log
     11*.out
    312*.pdf
    413*.ps
     14*.toc
  • doc/user/Makefile

    re2e7330 rbc6f918  
    1 ## Define the configuration variables.
     1## Define the appropriate configuration variables.
    22
    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}
     3TeXLIB = .:../LaTeXmacros:../bibliography/:
     4LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error
    85BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
    9 
    10 MAKEFLAGS = --no-print-directory --silent #
    11 VPATH = ${Figures}
    126
    137## Define the text source files.
     
    4135# Directives #
    4236
    43 .PHONY : all clean                                      # not file names
    44 
    4537all : ${DOCUMENT}
    4638
    4739clean :
    48         @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build}
     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}
    4942
    5043# File Dependencies #
     
    5447
    5548${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
    56         dvips ${Build}/$< -o $@
     49        dvips $< -o $@
    5750
    58 ${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
     51${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \
     52                ../LaTeXmacros/common.tex ../LaTeXmacros/lstlang.sty ../LaTeXmacros/indexstyle ../bibliography/cfa.bib
    6053        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    61         if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi
     54        if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi
    6255        # Must have *.aux file containing citations for bibtex
    6356        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
    64         -${BibTeX} ${Build}/${basename $@}
    65         # Some citations reference others so run again to resolve these citations
     57        -${BibTeX} ${basename $@}
     58        # Some citations reference others so run steps again to resolve these citations
    6659        ${LaTeX} ${basename $@}.tex
    67         -${BibTeX} ${Build}/${basename $@}
     60        -${BibTeX} ${basename $@}
    6861        # Make index from *.aux entries and input index at end of document
    69         makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx
    70         # Run again to finish citations
     62        makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx
    7163        ${LaTeX} ${basename $@}.tex
    7264        # Run again to get index title into table of contents
    7365        ${LaTeX} ${basename $@}.tex
    7466
     67predefined :
     68        sed -f predefined.sed ${basename ${DOCUMENT}}.tex > ${basename $@}.cf
     69
    7570## Define the default recipes.
    7671
    77 ${Build}:
    78         mkdir -p ${Build}
    79 
    8072%.tex : %.fig
    81         fig2dev -L eepic $< > ${Build}/$@
     73        fig2dev -L eepic $< > $@
    8274
    8375%.ps : %.fig
    84         fig2dev -L ps $< > ${Build}/$@
     76        fig2dev -L ps $< > $@
    8577
    8678%.pstex : %.fig
    87         fig2dev -L pstex $< > ${Build}/$@
    88         fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
     79        fig2dev -L pstex $< > $@
     80        fig2dev -L pstex_t -p $@ $< > $@_t
    8981
    9082# Local Variables: #
  • doc/user/user.tex

    re2e7330 rbc6f918  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Wed Jan 31 07:59:24 2018
    14 %% Update Count     : 3146
     13%% Last Modified On : Mon Nov 27 18:09:59 2017
     14%% Update Count     : 3143
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    4040\usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}
    4141\usepackage{breakurl}
     42\renewcommand{\UrlFont}{\small\sf}
    4243
    4344\usepackage[pagewise]{lineno}
     
    66606661
    66616662\bibliographystyle{plain}
    6662 \bibliography{pl}
     6663\bibliography{cfa}
    66636664
    66646665
  • src/benchmark/Makefile.am

    re2e7330 rbc6f918  
    5959        @echo -e '\t"githash": "'${githash}'",'
    6060        @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},'
    6561        @echo -e '\t"ctxswitch": {'
    6662        @echo -en '\t\t"coroutine":'
  • src/benchmark/Makefile.in

    re2e7330 rbc6f918  
    473473        @echo -e '\t"githash": "'${githash}'",'
    474474        @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},'
    479475        @echo -e '\t"ctxswitch": {'
    480476        @echo -en '\t\t"coroutine":'
  • src/driver/cfa.cc

    re2e7330 rbc6f918  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jan 30 15:46:15 2018
    13 // Update Count     : 161
     12// Last Modified On : Tue Oct 31 11:40:44 2017
     13// Update Count     : 160
    1414//
    1515
     
    277277                args[nargs] = "--undefined=__cfaabi_dbg_bits_write";
    278278                nargs += 1;
    279                 args[nargs] = "-Xlinker";
    280                 nargs += 1;
    281                 args[nargs] = "--undefined=__cfaabi_interpose_startup";
    282                 nargs += 1;
    283279
    284280        } // if
     
    357353                nargs += 1;
    358354                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
    361355                nargs += 1;
    362356                args[nargs] = ( *new string( string("-B") + Bprefix + "/" ) ).c_str();
  • src/libcfa/bits/containers.h

    re2e7330 rbc6f918  
    140140
    141141#ifdef __cforall
    142 
    143142        forall(dtype T | is_node(T))
    144         static inline void ?{}( __queue(T) & this ) with( this ) {
    145                 head{ NULL };
    146                 tail{ &head };
     143        static inline void ?{}( __queue(T) & this ) {
     144                (this.head){ NULL };
     145                (this.tail){ &this.head };
    147146        }
    148147
    149148        forall(dtype T | is_node(T) | sized(T))
    150         static inline void append( __queue(T) & this, T * val ) with( this ) {
    151                 verify(tail != NULL);
    152                 *tail = val;
    153                 tail = &get_next( *val );
     149        static inline void append( __queue(T) & this, T * val ) {
     150                verify(this.tail != NULL);
     151                *this.tail = val;
     152                this.tail = &get_next( *val );
    154153        }
    155154
     
    168167
    169168        forall(dtype T | is_node(T) | sized(T))
    170         static inline T * remove( __queue(T) & this, T ** it ) with( this ) {
     169        static inline T * remove( __queue(T) & this, T ** it ) {
    171170                T * val = *it;
    172171                verify( val );
     
    174173                (*it) = get_next( *val );
    175174
    176                 if( tail == &get_next( *val ) ) {
    177                         tail = it;
     175                if( this.tail == &get_next( *val ) ) {
     176                        this.tail = it;
    178177                }
    179178
    180179                get_next( *val ) = NULL;
    181180
    182                 verify( (head == NULL) == (&head == tail) );
    183                 verify( *tail == NULL );
     181                verify( (this.head == NULL) == (&this.head == this.tail) );
     182                verify( *this.tail == NULL );
    184183                return val;
    185184        }
    186185#endif
    187 
    188 //-----------------------------------------------------------------------------
    189 // Tools
    190 //-----------------------------------------------------------------------------
    191 #ifdef __cforall
    192 
    193 #endif
  • src/libcfa/bits/locks.h

    re2e7330 rbc6f918  
    5858
    5959#ifdef __cforall
    60         extern "C" {
    61                 extern void disable_interrupts();
    62                 extern void enable_interrupts_noPoll();
    63         }
    64 
    6560        extern void yield( unsigned int );
    6661        extern thread_local struct thread_desc *    volatile this_thread;
    67         extern thread_local struct processor *      volatile this_processor;
    6862
    6963        static inline void ?{}( __spinlock_t & this ) {
     
    7468        static inline _Bool try_lock  ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
    7569                _Bool result = __lock_test_and_test_and_set( this.lock );
    76                 if( result ) {
    77                         disable_interrupts();
    78                         __cfaabi_dbg_debug_do(
     70                __cfaabi_dbg_debug_do(
     71                        if( result ) {
    7972                                this.prev_name = caller;
    8073                                this.prev_thrd = this_thread;
    81                         )
    82                 }
     74                        }
     75                )
    8376                return result;
    8477        }
     
    10699                        #endif
    107100                }
    108                 disable_interrupts();
    109101                __cfaabi_dbg_debug_do(
    110102                        this.prev_name = caller;
     
    113105        }
    114106
    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         // }
     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        }
    127118
    128119        static inline void unlock( __spinlock_t & this ) {
    129                 enable_interrupts_noPoll();
    130120                __lock_release( this.lock );
    131121        }
  • src/libcfa/concurrency/coroutine.c

    re2e7330 rbc6f918  
    118118} //ctxSwitchDirect
    119119
    120 void create_stack( coStack_t* this, unsigned int storageSize ) with( *this ) {
     120void create_stack( coStack_t* this, unsigned int storageSize ) {
    121121        //TEMP HACK do this on proper kernel startup
    122122        if(pageSize == 0ul) pageSize = sysconf( _SC_PAGESIZE );
     
    124124        size_t cxtSize = libCeiling( sizeof(machine_context_t), 8 ); // minimum alignment
    125125
    126         if ( (intptr_t)storage == 0 ) {
    127                 userStack = false;
    128                 size = libCeiling( storageSize, 16 );
     126        if ( (intptr_t)this->storage == 0 ) {
     127                this->userStack = false;
     128                this->size = libCeiling( storageSize, 16 );
    129129                // use malloc/memalign because "new" raises an exception for out-of-memory
    130130
    131131                // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment
    132                 __cfaabi_dbg_debug_do( storage = memalign( pageSize, cxtSize + size + pageSize ) );
    133                 __cfaabi_dbg_no_debug_do( storage = malloc( cxtSize + size + 8 ) );
     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 ) );
    134134
    135135                __cfaabi_dbg_debug_do(
    136                         if ( mprotect( storage, pageSize, PROT_NONE ) == -1 ) {
     136                        if ( mprotect( this->storage, pageSize, PROT_NONE ) == -1 ) {
    137137                                abortf( "(uMachContext &)%p.createContext() : internal error, mprotect failure, error(%d) %s.", this, (int)errno, strerror( (int)errno ) );
    138138                        } // if
    139139                );
    140140
    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 );
     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 );
    143143                } // if
    144144
    145                 __cfaabi_dbg_debug_do( limit = (char *)storage + pageSize );
    146                 __cfaabi_dbg_no_debug_do( limit = (char *)libCeiling( (unsigned long)storage, 16 ) ); // minimum alignment
     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 alignment
    147147
    148148        } else {
    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;
     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;
    152152
    153                 if ( size % 16 != 0u ) size -= 8;
     153                if ( this->size % 16 != 0u ) this->size -= 8;
    154154
    155                 limit = (char *)libCeiling( (unsigned long)storage, 16 ); // minimum alignment
     155                this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ); // minimum alignment
    156156        } // if
    157         assertf( size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", size, MinStackSize );
     157        assertf( this->size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", this->size, MinStackSize );
    158158
    159         base = (char *)limit + size;
    160         context = base;
    161         top = (char *)context + cxtSize;
     159        this->base = (char *)this->limit + this->size;
     160        this->context = this->base;
     161        this->top = (char *)this->context + cxtSize;
    162162}
    163163
  • src/libcfa/concurrency/invoke.h

    re2e7330 rbc6f918  
    134134                // instrusive link field for threads
    135135                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                 )
    142136     };
    143137
  • src/libcfa/concurrency/kernel.c

    re2e7330 rbc6f918  
    8787}
    8888
    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 };
     89void ?{}( 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        this.top = info->top;
     96        this.userStack = true;
     97}
     98
     99void ?{}( 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
     107void ?{}( thread_desc & this, current_stack_info_t * info) {
     108        (this.self_cor){ info };
    109109}
    110110
     
    133133void ?{}(processor & this, cluster * cltr) {
    134134        this.cltr = cltr;
    135         this.terminated{ 0 };
     135        (this.terminated){ 0 };
    136136        this.do_terminate = false;
    137137        this.preemption_alarm = NULL;
     
    143143void ?{}(processor & this, cluster * cltr, processorCtx_t & runner) {
    144144        this.cltr = cltr;
    145         this.terminated{ 0 };
     145        (this.terminated){ 0 };
    146146        this.do_terminate = false;
    147147        this.preemption_alarm = NULL;
     
    154154}
    155155
    156 void ^?{}(processor & this) with( this ){
    157         if( ! do_terminate ) {
     156void ^?{}(processor & this) {
     157        if( ! this.do_terminate ) {
    158158                __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this);
    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();
     159                this.do_terminate = true;
     160                P( this.terminated );
     161                pthread_join( this.kernel_thread, NULL );
     162        }
     163}
     164
     165void ?{}(cluster & this) {
     166        (this.ready_queue){};
     167        ( this.ready_queue_lock ){};
     168
     169        this.preemption = default_preemption();
    170170}
    171171
     
    240240// Once a thread has finished running, some of
    241241// its final actions must be executed from the kernel
    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] );
     242void 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] );
    259256                }
    260257        }
    261         else if( action_code == Release_Multi_Schedule ) {
    262                 for(int i = 0; i < lock_count; i++) {
    263                         unlock( *locks[i] );
     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] );
    264261                }
    265                 for(int i = 0; i < thrd_count; i++) {
    266                         ScheduleThread( thrds[i] );
     262                for(int i = 0; i < this->finish.thrd_count; i++) {
     263                        ScheduleThread( this->finish.thrds[i] );
    267264                }
    268265        }
    269266        else {
    270                 assert(action_code == No_Action);
     267                assert(this->finish.action_code == No_Action);
    271268        }
    272269}
     
    337334        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    338335
    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 );
     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
     343thread_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 );
    353348        verify( disable_preempt_count > 0 );
    354349        return head;
     
    366361        disable_interrupts();
    367362        this_processor->finish.action_code = Release;
    368         this_processor->finish.lock        = lock;
    369 
    370         verify( disable_preempt_count > 1 );
     363        this_processor->finish.lock = lock;
     364
     365        verify( disable_preempt_count > 0 );
    371366        suspend();
    372367        verify( disable_preempt_count > 0 );
     
    376371
    377372void BlockInternal( thread_desc * thrd ) {
     373        assert(thrd);
    378374        disable_interrupts();
     375        assert( thrd->self_cor.state != Halted );
    379376        this_processor->finish.action_code = Schedule;
    380         this_processor->finish.thrd        = thrd;
     377        this_processor->finish.thrd = thrd;
    381378
    382379        verify( disable_preempt_count > 0 );
     
    391388        disable_interrupts();
    392389        this_processor->finish.action_code = Release_Schedule;
    393         this_processor->finish.lock        = lock;
    394         this_processor->finish.thrd        = thrd;
    395 
    396         verify( disable_preempt_count > 1 );
     390        this_processor->finish.lock = lock;
     391        this_processor->finish.thrd = thrd;
     392
     393        verify( disable_preempt_count > 0 );
    397394        suspend();
    398395        verify( disable_preempt_count > 0 );
     
    404401        disable_interrupts();
    405402        this_processor->finish.action_code = Release_Multi;
    406         this_processor->finish.locks       = locks;
    407         this_processor->finish.lock_count  = count;
     403        this_processor->finish.locks = locks;
     404        this_processor->finish.lock_count = count;
    408405
    409406        verify( disable_preempt_count > 0 );
     
    417414        disable_interrupts();
    418415        this_processor->finish.action_code = Release_Multi_Schedule;
    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;
     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;
    423420
    424421        verify( disable_preempt_count > 0 );
     
    432429        verify( disable_preempt_count > 0 );
    433430        this_processor->finish.action_code = thrd ? Release_Schedule : Release;
    434         this_processor->finish.lock        = lock;
    435         this_processor->finish.thrd        = thrd;
     431        this_processor->finish.lock = lock;
     432        this_processor->finish.thrd = thrd;
    436433
    437434        suspend();
     
    518515        __cfaabi_dbg_print_safe("Kernel : Shutdown complete\n");
    519516}
    520 
    521 //=============================================================================================
    522 // Unexpected Terminating logic
    523 //=============================================================================================
    524 
    525517
    526518static __spinlock_t kernel_abort_lock;
     
    589581void ^?{}(semaphore & this) {}
    590582
    591 void P(semaphore & this) with( this ){
    592         lock( lock __cfaabi_dbg_ctx2 );
    593         count -= 1;
    594         if ( count < 0 ) {
     583void P(semaphore & this) {
     584        lock( this.lock __cfaabi_dbg_ctx2 );
     585        this.count -= 1;
     586        if ( this.count < 0 ) {
    595587                // queue current task
    596                 append( waiting, (thread_desc *)this_thread );
     588                append( this.waiting, (thread_desc *)this_thread );
    597589
    598590                // atomically release spin lock and block
    599                 BlockInternal( &lock );
     591                BlockInternal( &this.lock );
    600592        }
    601593        else {
    602             unlock( lock );
    603         }
    604 }
    605 
    606 void V(semaphore & this) with( this ) {
     594            unlock( this.lock );
     595        }
     596}
     597
     598void V(semaphore & this) {
    607599        thread_desc * thrd = NULL;
    608         lock( lock __cfaabi_dbg_ctx2 );
    609         count += 1;
    610         if ( count <= 0 ) {
     600        lock( this.lock __cfaabi_dbg_ctx2 );
     601        this.count += 1;
     602        if ( this.count <= 0 ) {
    611603                // remove task at head of waiting list
    612                 thrd = pop_head( waiting );
    613         }
    614 
    615         unlock( lock );
     604                thrd = pop_head( this.waiting );
     605        }
     606
     607        unlock( this.lock );
    616608
    617609        // make new owner
     
    619611}
    620612
    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 )
    654613// Local Variables: //
    655614// mode: c //
  • src/libcfa/concurrency/kernel_private.h

    re2e7330 rbc6f918  
    8585extern void ThreadCtxSwitch(coroutine_desc * src, coroutine_desc * dst);
    8686
    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 
    9287//-----------------------------------------------------------------------------
    9388// Utils
  • src/libcfa/concurrency/monitor.c

    re2e7330 rbc6f918  
    5353static inline __lock_size_t aggregate    ( monitor_desc * storage [], const __waitfor_mask_t & mask );
    5454
     55#ifndef __CFA_LOCK_NO_YIELD
     56#define DO_LOCK lock_yield
     57#else
     58#define DO_LOCK lock
     59#endif
     60
    5561//-----------------------------------------------------------------------------
    5662// Useful defines
     
    8490        static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) {
    8591                // Lock the monitor spinlock
    86                 lock( this->lock __cfaabi_dbg_ctx2 );
     92                DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
    8793                thread_desc * thrd = this_thread;
    88 
    89                 verify( disable_preempt_count > 0 );
    9094
    9195                __cfaabi_dbg_print_safe("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
     
    117121                        // Some one else has the monitor, wait in line for it
    118122                        append( this->entry_queue, thrd );
    119 
    120                         verify( disable_preempt_count > 0 );
    121 
    122123                        BlockInternal( &this->lock );
    123124
     
    137138        static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) {
    138139                // Lock the monitor spinlock
    139                 lock( this->lock __cfaabi_dbg_ctx2 );
     140                DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
    140141                thread_desc * thrd = this_thread;
    141142
     
    200201        // Leave single monitor
    201202        void __leave_monitor_desc( monitor_desc * this ) {
    202                 // Lock the monitor spinlock
    203                 lock( this->lock __cfaabi_dbg_ctx2 );
     203                // Lock the monitor spinlock, DO_LOCK to reduce contention
     204                DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
    204205
    205206                __cfaabi_dbg_print_safe("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner);
     
    247248
    248249                // Lock the monitor now
    249                 lock( this->lock __cfaabi_dbg_ctx2 );
     250                DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
    250251
    251252                disable_interrupts();
     
    396397        append( this.blocked, &waiter );
    397398
    398         verify( disable_preempt_count == 0 );
    399 
    400399        // Lock all monitors (aggregates the locks as well)
    401400        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"); }
    405401
    406402        // Find the next thread(s) to run
     
    477473        monitor_ctx( this.monitors, this.monitor_count );
    478474
    479         verify( disable_preempt_count == 0 );
    480 
    481475        // Lock all monitors (aggregates the locks them as well)
    482476        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 
    487477
    488478        // Create the node specific to this wait operation
     
    747737static inline void lock_all( __spinlock_t * locks [], __lock_size_t count ) {
    748738        for( __lock_size_t i = 0; i < count; i++ ) {
    749                 lock( *locks[i] __cfaabi_dbg_ctx2 );
     739                DO_LOCK( *locks[i] __cfaabi_dbg_ctx2 );
    750740        }
    751741}
     
    754744        for( __lock_size_t i = 0; i < count; i++ ) {
    755745                __spinlock_t * l = &source[i]->lock;
    756                 lock( *l __cfaabi_dbg_ctx2 );
     746                DO_LOCK( *l __cfaabi_dbg_ctx2 );
    757747                if(locks) locks[i] = l;
    758748        }
  • src/libcfa/concurrency/preemption.c

    re2e7330 rbc6f918  
    1919extern "C" {
    2020#include <errno.h>
     21#include <execinfo.h>
     22#define __USE_GNU
     23#include <signal.h>
     24#undef __USE_GNU
    2125#include <stdio.h>
    2226#include <string.h>
     
    2529#undef ftype
    2630
    27 #include "bits/signal.h"
     31#ifdef __USE_STREAM__
     32#include "fstream"
     33#endif
    2834
    2935//TODO move to defaults
     
    3440        return __CFA_DEFAULT_PREEMPTION__;
    3541}
     42
     43// Short hands for signal context information
     44#define __CFA_SIGCXT__ ucontext_t *
     45#define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt
    3646
    3747// FwdDeclarations : timeout handlers
     
    4353void sigHandler_segv     ( __CFA_SIGPARMS__ );
    4454void sigHandler_abort    ( __CFA_SIGPARMS__ );
     55
     56// FwdDeclarations : sigaction wrapper
     57static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
    4558
    4659// FwdDeclarations : alarm thread main
     
    6073static pthread_t alarm_thread;                        // pthread handle to alarm thread
    6174
    62 void ?{}(event_kernel_t & this) with( this ) {
    63         alarms{};
    64         lock{};
     75void ?{}(event_kernel_t & this) {
     76        (this.alarms){};
     77        (this.lock){};
    6578}
    6679
     
    149162        // If counter reaches 0, execute any pending CtxSwitch
    150163        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    151                 processor   * proc = this_processor;      // Cache the processor now since interrupts can start happening after the atomic add
     164                processor * proc  = this_processor;      // Cache the processor now since interrupts can start happening after the atomic add
    152165                thread_desc * thrd = this_thread;         // Cache the thread now since interrupts can start happening after the atomic add
    153166
     
    169182        void enable_interrupts_noPoll() {
    170183                __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    171                 verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
     184                verify( prev != 0u );                     // If this triggers someone is enabled already enabled interrupts
    172185        }
    173186}
     
    233246        // Setup proper signal handlers
    234247        __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART );         // CtxSwitch handler
     248        // __kernel_sigaction( SIGSEGV, sigHandler_segv     , SA_SIGINFO );      // Failure handler
     249        // __kernel_sigaction( SIGBUS , sigHandler_segv     , SA_SIGINFO );      // Failure handler
    235250
    236251        signal_block( SIGALRM );
     
    293308        if( !preemption_ready() ) { return; }
    294309
    295         __cfaabi_dbg_print_buffer_decl(" KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
     310        // __cfaabi_dbg_print_buffer_decl(" KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
    296311
    297312        preemption_in_progress = true;                      // Sync flag : prevent recursive calls to the signal handler
     
    365380}
    366381
     382// Sigaction wrapper : register an signal handler
     383static 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 handler
     399static 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 logic
     417//=============================================================================================
     418
     419__cfaabi_dbg_debug_do(
     420        static void __kernel_backtrace( int start ) {
     421                // skip first N stack frames
     422
     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 name
     429                *index( messages[0], '(' ) = '\0';
     430                #ifdef __USE_STREAM__
     431                serr | "Stack back trace for:" | messages[0] | endl;
     432                #else
     433                fprintf( stderr, "Stack back trace for: %s\n", messages[0]);
     434                #endif
     435
     436                // skip last 2 stack frames after main
     437                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 +offset
     444                                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 it
     457                        int frameNo = i - start;
     458                        if ( name && offset_begin && offset_end && name < offset_begin ) {
     459                                // delimit strings
     460                                *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                                #else
     468                                fprintf( stderr, "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end);
     469                                #endif
     470                        }
     471                        // otherwise, print the whole line
     472                        else {
     473                                #ifdef __USE_STREAM__
     474                                serr | "(" | frameNo | ")" | messages[i] | endl;
     475                                #else
     476                                fprintf( stderr, "(%i) %s\n", frameNo, messages[i] );
     477                                #endif
     478                        }
     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//              #else
     492//              fprintf( stderr, "*CFA runtime error* program cfa-cpp terminated with %s\n", sig == SIGSEGV ? "segment fault." : "bus error." );
     493//              #endif
     494
     495//              // skip first 2 stack frames
     496//              __kernel_backtrace( 1 );
     497//      )
     498//      exit( EXIT_FAILURE );
     499// }
     500
     501// void sigHandler_abort( __CFA_SIGPARMS__ ) {
     502//      // skip first 6 stack frames
     503//      __cfaabi_dbg_debug_do( __kernel_backtrace( 6 ); )
     504
     505//      // reset default signal handler
     506//      __kernel_sigdefault( SIGABRT );
     507
     508//      raise( SIGABRT );
     509// }
     510
    367511// Local Variables: //
    368512// mode: c //
  • src/libcfa/concurrency/thread.c

    re2e7330 rbc6f918  
    3131// Thread ctors and dtors
    3232
    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         )
     33void ?{}(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;
    4540
    46         monitors{ &self_mon_p, 1, (fptr_t)0 };
     41        (this.monitors){ &this.self_mon_p, 1, (fptr_t)0 };
    4742}
    4843
    49 void ^?{}(thread_desc& this) with( this ) {
    50         ^self_cor{};
     44void ^?{}(thread_desc& this) {
     45        ^(this.self_cor){};
    5146}
    5247
    5348forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } )
    54 void ?{}( scoped(T)& this ) with( this ) {
    55         handle{};
    56         __thrd_start(handle);
     49void ?{}( scoped(T)& this ) {
     50        (this.handle){};
     51        __thrd_start(this.handle);
    5752}
    5853
    5954forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T&, P); } )
    60 void ?{}( scoped(T)& this, P params ) with( this ) {
    61         handle{ params };
    62         __thrd_start(handle);
     55void ?{}( scoped(T)& this, P params ) {
     56        (this.handle){ params };
     57        __thrd_start(this.handle);
    6358}
    6459
    6560forall( dtype T | sized(T) | is_thread(T) )
    66 void ^?{}( scoped(T)& this ) with( this ) {
    67         ^handle{};
     61void ^?{}( scoped(T)& this ) {
     62        ^(this.handle){};
    6863}
    6964
     
    7368void __thrd_start( T& this ) {
    7469        coroutine_desc* thrd_c = get_coroutine(this);
    75         thread_desc   * thrd_h = get_thread   (this);
     70        thread_desc* thrd_h = get_thread   (this);
    7671        thrd_c->last = this_coroutine;
    7772
  • src/libcfa/interpose.c

    re2e7330 rbc6f918  
    2222#include <dlfcn.h>
    2323#include <unistd.h>
    24 #define __USE_GNU
    25 #include <signal.h>
    26 #undef __USE_GNU
    27 #include <execinfo.h>
    2824}
    2925
    3026#include "bits/debug.h"
    3127#include "bits/defs.h"
    32 #include "bits/signal.h"
    3328#include "startup.h"
    3429
    35 void __cfaabi_interpose_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
     30void interpose_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
    3631
    3732typedef void (*generic_fptr_t)(void);
     
    8984#define INIT_REALRTN( x, ver ) assign_ptr( (void**)&libc_##x, #x, ver)
    9085
    91 void sigHandler_segv ( __CFA_SIGPARMS__ );
    92 void sigHandler_abort( __CFA_SIGPARMS__ );
    93 
    94 void __cfaabi_interpose_startup() {
     86void interpose_startup() {
    9587        const char *version = NULL;
    9688
    9789        INIT_REALRTN( abort, version );
    9890        INIT_REALRTN( exit, version );
    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
    10391}
    104 
    105 //=============================================================================================
    106 // Terminating Signals logic
    107 //=============================================================================================
    10892
    10993extern "C" {
     
    155139}
    156140
    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 );
    222 }
    223 
    224141// Local Variables: //
    225142// mode: c //
  • src/libcfa/interpose.h

    re2e7330 rbc6f918  
    1616#pragma once
    1717
    18 void * interpose_symbol( const char* symbol, const char *version );
     18void * interpose_symbol( const char* symbol, , const char *version );
    1919
    2020extern __typeof__( abort ) libc_abort __attribute__(( noreturn ));
  • src/prelude/prelude.cf

    re2e7330 rbc6f918  
    3939// ------------------------------------------------------------
    4040
     41_Bool                   ?++( _Bool & ),                         ?++( volatile _Bool & );
     42_Bool                   ?--( _Bool & ),                         ?--( volatile _Bool & );
    4143signed short            ?++( signed short & ),                  ?++( volatile signed short & );
    4244signed short            ?--( signed short & ),                  ?--( volatile signed short & );
     
    9294// ------------------------------------------------------------
    9395
     96_Bool                   ++?( _Bool & ),                         --?( _Bool & );
    9497signed short    ++?( signed short & ),                  --?( signed short & );
    9598signed int              ++?( signed int & ),                    --?( signed int & );
     
    122125forall( ftype FT ) FT &          *?( FT * );
    123126
    124 _Bool                   +?( _Bool ),                    -?( _Bool );
     127_Bool                   +?( _Bool ),                    -?( _Bool ),                    ~?( _Bool );
    125128signed int              +?( signed int ),               -?( signed int ),               ~?( signed int );
    126129unsigned int            +?( unsigned int ),             -?( unsigned int ),             ~?( unsigned int );
     
    154157// ------------------------------------------------------------
    155158
     159_Bool                   ?*?( _Bool, _Bool ),                                    ?/?( _Bool, _Bool ),                            ?%?( _Bool, _Bool );
    156160signed int              ?*?( signed int, signed int ),                          ?/?( signed int, signed int ),                  ?%?( signed int, signed int );
    157161unsigned int            ?*?( unsigned int, unsigned int ),                      ?/?( unsigned int, unsigned int ),              ?%?( unsigned int, unsigned int );
     
    211215// ------------------------------------------------------------
    212216
     217_Bool                   ?<<?( _Bool, _Bool ),                                   ?>>?( _Bool, _Bool );
    213218signed int              ?<<?( signed int, signed int ),                         ?>>?( signed int, signed int );
    214219unsigned int            ?<<?( unsigned int, unsigned int ),                     ?>>?( unsigned int, unsigned int );
     
    462467
    463468
     469_Bool                   ?*=?( _Bool &, _Bool ),                                 ?*=?( volatile _Bool &, _Bool );
    464470char                    ?*=?( char &, char ),                                   ?*=?( volatile char &, char );
    465471char signed             ?*=?( char signed &, char signed ),                     ?*=?( volatile char signed &, char signed );
     
    528534unsigned long long int  ?-=?( unsigned long long int &, unsigned long long int ), ?-=?( volatile unsigned long long int &, unsigned long long int );
    529535
     536_Bool                   ?<<=?( _Bool &, _Bool ),                                ?<<=?( volatile _Bool &, _Bool );
    530537char                    ?<<=?( char &, char ),                                  ?<<=?( volatile char &, char );
    531538char signed             ?<<=?( char signed &, char signed ),                    ?<<=?( volatile char signed &, char signed );
     
    540547unsigned long long int  ?<<=?( unsigned long long int &, unsigned long long int ), ?<<=?( volatile unsigned long long int &, unsigned long long int );
    541548
     549_Bool                   ?>>=?( _Bool &, _Bool ),                                ?>>=?( volatile _Bool &, _Bool );
    542550char                    ?>>=?( char &, char ),                                  ?>>=?( volatile char &, char );
    543551char signed             ?>>=?( char signed &, char signed ),                    ?>>=?( volatile char signed &, char signed );
  • src/tests/Makefile.am

    re2e7330 rbc6f918  
    6565
    6666concurrency :
    67         @+python test.py --debug=${debug} -Iconcurrent
     67        @+python test.py --debug=${debug} ${concurrent} ${concurrent_test}
    6868
    6969.dummy : .dummy.c @CFA_BINDIR@/@CFA_NAME@
  • src/tests/Makefile.in

    re2e7330 rbc6f918  
    743743
    744744concurrency :
    745         @+python test.py --debug=${debug} -Iconcurrent
     745        @+python test.py --debug=${debug} ${concurrent} ${concurrent_test}
    746746
    747747.dummy : .dummy.c @CFA_BINDIR@/@CFA_NAME@
  • src/tests/concurrent/examples/quickSort.c

    re2e7330 rbc6f918  
    99// Created On       : Wed Dec  6 12:15:52 2017
    1010// Last Modified By : Peter A. Buhr
    11 // Last Modified On : Tue Jan 30 15:58:58 2018
    12 // Update Count     : 162
     11// Last Modified On : Mon Jan 29 08:41:37 2018
     12// Update Count     : 155
    1313//
    1414
     
    100100        if ( argc != 1 ) {                                                                      // do not use defaults
    101101                if ( argc < 2 || argc > 4 ) usage( argv );              // wrong number of options
    102                 if ( strcmp( argv[1], "-t" ) == 0 ) {                   // timing ?
     102//              if ( strcmp( argv[1], "-t" ) == 0 ) {                   // timing ?
     103                if ( argv[1][0] == '-' && argv[1][1] == 't' ) { // timing ?
    103104                        &unsortedfile = (ifstream *)0;                          // no input
    104105                        choose ( argc ) {
  • src/tests/functions.c

    re2e7330 rbc6f918  
    1010// Created On       : Wed Aug 17 08:39:58 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jan 17 22:44:12 2018
    13 // Update Count     : 12
     12// Last Modified On : Mon Nov 27 18:08:54 2017
     13// Update Count     : 11
    1414//
    1515
     
    2525        void g(void)
    2626        ) {
    27         (* g)();
     27        (*g)();
    2828        g();
    2929        g = h;
     
    3232int f1() {}
    3333int (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] {}
     34int (*f3())() {}
     35int *((f4())) {}
     36int ((*f5()))() {}
     37int *f6() {}
     38int *(f7)() {}
     39int **f8() {}
     40int * const *(f9)() {}
     41int (*f10())[] {}
     42int (*f11())[][3] {}
     43int ((*f12())[])[3] {}
    4444
    4545// "implicit int" otype specifier (not ANSI)
     
    5050extern const fII4( int i ) {}
    5151
    52 * fII5() {}
    53 const * fII6() {}
    54 const long * fII7() {}
    55 static const long * fII8() {}
    56 const static long * fII9() {}
     52*fII5() {}
     53const *fII6() {}
     54const long *fII7() {}
     55static const long *fII8() {}
     56const static long *fII9() {}
    5757
    5858// K&R function definitions
     
    117117        [int](int)
    118118        ) {
    119         int (* (* pc)[][10])[][3];
     119        int (*(*pc)[][10])[][3];
    120120        * [][10] * [][3] int p;
    121121        * [] * [int](int) p;
    122122}
    123123
    124 static const int * f1() {}
     124static const int *f1() {}
    125125static [ const int ] f2() {}
    126126static inline [ const * int ] f3() {}
     
    133133        int (),
    134134
    135         int * (),
    136         int ** (),
    137         int * const * (),
     135        int *(),
     136        int **(),
     137        int * const *(),
    138138        int * const * const (),
    139139
     
    141141        int ([10]),
    142142
    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]),
    149149        int * const * const ([]),
    150150        int * const * const ([10])
     
    154154        int (),
    155155
    156         int * (),
    157         int ** (),
    158         int * const * (),
     156        int *(),
     157        int **(),
     158        int * const *(),
    159159        int * const * const (),
    160160
     
    162162        int ([10]),
    163163
    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]),
    170170        int * const * const ([]),
    171171        int * const * const ([10])
     
    175175typedef int T;
    176176
    177 int f( T (* f), T t ) {
     177int f( T (*f), T t ) {
    178178        T (T);
    179179}
     
    184184//int (f[])() {}
    185185//int f[]() {}
    186 //int ((* f15())())[] {}
     186//int ((*f15())())[] {}
    187187
    188188// Local Variables: //
  • src/tests/identFuncDeclarator.c

    re2e7330 rbc6f918  
    1010// Created On       : Wed Aug 17 08:36:34 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jan 17 22:39:13 2018
    13 // Update Count     : 2
     12// Last Modified On : Wed Aug 17 08:37:06 2016
     13// Update Count     : 1
    1414//
    1515
     
    1818        int (f2);
    1919
    20         int * f3;
    21         int ** f4;
    22         int * const * f5;
     20        int *f3;
     21        int **f4;
     22        int * const *f5;
    2323        int * const * const f6;
    2424
    25         int * (f7);
    26         int ** (f8);
    27         int * const * (f9);
     25        int *(f7);
     26        int **(f8);
     27        int * const *(f9);
    2828        int * const * const (f10);
    2929
    30         int (* f11);
    31         int (** f12);
    32         int (* const * f13);
     30        int (*f11);
     31        int (**f12);
     32        int (* const *f13);
    3333        int (* const * const f14);
    3434
     
    3838        int (f18[10]);
    3939
    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];
    4646        int * const * const f25[2];
    4747        int * const * const f26[10];
    4848
    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]);
    5555        int * const * const (f33[2]);
    5656        int * const * const (f34[10]);
    5757
    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]);
    6464        int (* const * const f41[2]);
    6565        int (* const * const f42[10]);
     
    7272        int ((f48[3]))[3];
    7373
    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];
    8080        int * const * const f55[2][3];
    8181        int * const * const f56[3][3];
    8282
    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]);
    8989        int (* const * const f63[2][3]);
    9090        int (* const * const f64[3][3]);
     
    9393        int (f66)(int);
    9494
    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);
    9898        int * const * const f70(int);
    9999
    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);
    103103        int * const * const (f74)(int);
    104104
    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);
    108108        int (* const * const f78)(int);
    109109
    110         int (* (* f79)(int))();
    111         int (* (* const f80)(int))();
     110        int (*(*f79)(int))();
     111        int (*(* const f80)(int))();
    112112        int (* const(* const f81)(int))();
    113113}
  • src/tests/identParamDeclarator.c

    re2e7330 rbc6f918  
    1010// Created On       : Wed Aug 17 08:37:56 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jan 17 22:36:11 2018
    13 // Update Count     : 2
     12// Last Modified On : Wed Aug 17 08:38:42 2016
     13// Update Count     : 1
    1414//
    1515
    16 int fred (
     16int fred(
    1717        int f1,
    1818        int (f2),
     
    157157    );
    158158
    159 int main( int argc, char const *argv[] ) {                              // dummy main
     159//Dummy main
     160int main(int argc, char const *argv[])
     161{
    160162        return 0;
    161163}
  • src/tests/preempt_longrun/Makefile.am

    re2e7330 rbc6f918  
    1919preempt=1_000ul
    2020
    21 REPEAT = ${abs_top_srcdir}/tools/repeat
    22 TIME = /usr/bin/time -f "%E"
     21REPEAT = ${abs_top_srcdir}/tools/repeat -s
    2322
    2423BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -debug -O2 -DPREEMPTION_RATE=${preempt}
     
    3837        ${AM_V_GEN}${CC} ${CFLAGS} ${<} -o ${@}
    3938
    40 %.run : % ${REPEAT}
    41         @ time ${REPEAT} -r out.log -i -s $(repeats) timeout ${max_time} ./${<}
     39%.run : %
     40        @ time ${REPEAT} $(repeats) timeout ${max_time} ./${<}
    4241        @ rm ${<}
    4342        @ 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

    re2e7330 rbc6f918  
    451451max_time = 600
    452452preempt = 1_000ul
    453 REPEAT = ${abs_top_srcdir}/tools/repeat
    454 TIME = /usr/bin/time -f "%E"
     453REPEAT = ${abs_top_srcdir}/tools/repeat -s
    455454BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -debug -O2 -DPREEMPTION_RATE=${preempt}
    456455TESTS = block create disjoint enter enter3 processor stack wait yield
     
    875874        ${AM_V_GEN}${CC} ${CFLAGS} ${<} -o ${@}
    876875
    877 %.run : % ${REPEAT}
    878         @ time ${REPEAT} -r out.log -i -s $(repeats) timeout ${max_time} ./${<}
     876%.run : %
     877        @ time ${REPEAT} $(repeats) timeout ${max_time} ./${<}
    879878        @ rm ${<}
    880879        @ 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/
    889880
    890881# Tell versions [3.59,3.63) of GNU make to not export all variables.
  • src/tests/preempt_longrun/block.c

    re2e7330 rbc6f918  
    1 ../concurrent/signal/block.c
     1../sched-int-block.c
  • src/tests/preempt_longrun/create.c

    re2e7330 rbc6f918  
    1414thread worker_t {};
    1515
    16 void main(worker_t & this) {}
     16void main(worker_t * this) {}
    1717
    1818int main(int argc, char* argv[]) {
  • src/tests/preempt_longrun/disjoint.c

    re2e7330 rbc6f918  
    1 ../concurrent/signal/disjoint.c
     1../sched-int-disjoint.c
  • src/tests/preempt_longrun/enter.c

    re2e7330 rbc6f918  
    1717mon_t mon;
    1818
    19 void foo( mon_t & mutex this ) {}
     19void foo( mon_t * mutex this ) {}
    2020
    2121thread worker_t {};
    2222
    23 void main( worker_t & this ) {
     23void main( worker_t * this ) {
    2424        for( unsigned long i = 0; i < N; i++ ) {
    25                 foo( mon );
     25                foo( &mon );
    2626        }
    2727}
  • src/tests/preempt_longrun/enter3.c

    re2e7330 rbc6f918  
    1717mon_t mon1, mon2, mon3;
    1818
    19 void foo( mon_t & mutex a, mon_t & mutex b, mon_t & mutex c ) {}
     19void foo( mon_t * mutex a, mon_t * mutex b, mon_t * mutex c ) {}
    2020
    2121thread worker_t {};
    2222
    23 void main( worker_t & this ) {
     23void main( worker_t * this ) {
    2424        for( unsigned long i = 0; i < N; i++ ) {
    25                 foo( mon1, mon2, mon3 );
     25                foo( &mon1, &mon2, &mon3 );
    2626        }
    2727}
  • src/tests/preempt_longrun/processor.c

    re2e7330 rbc6f918  
    1414thread worker_t {};
    1515
    16 void main(worker_t & this) {}
     16void main(worker_t * this) {}
    1717
    1818int main(int argc, char* argv[]) {
  • src/tests/preempt_longrun/stack.c

    re2e7330 rbc6f918  
    1414thread worker_t {};
    1515
    16 void main(worker_t & this) {
     16void main(worker_t * this) {
    1717        volatile long long p = 5_021_609ul;
    1818        volatile long long a = 326_417ul;
  • src/tests/preempt_longrun/wait.c

    re2e7330 rbc6f918  
    1 ../concurrent/signal/wait.c
     1../sched-int-wait.c
  • src/tests/preempt_longrun/yield.c

    re2e7330 rbc6f918  
    1414thread worker_t {};
    1515
    16 void main(worker_t & this) {
     16void main(worker_t * this) {
    1717        for(int i = 0; i < N; i++) {
    1818                yield();
Note: See TracChangeset for help on using the changeset viewer.