Changeset e2e7330


Ignore:
Timestamp:
Jan 31, 2018, 5:50:34 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
295e5071
Parents:
bc6f918 (diff), 281806b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:/u/cforall/software/cfa/cfa-cc

Files:
4 added
3 deleted
50 edited
5 moved

Legend:

Unmodified
Added
Removed
  • .gitignore

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

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

    rbc6f918 re2e7330  
    882882    address     = {\href{https://www.iso.org/standard/64031.html}{https://\-www.iso.org/\-standard/\-64031.html}},
    883883    year        = 2015
     884}
     885
     886@misc{Cforall,
     887    key         = {Cforall},
     888    title       = {C$\forall$ Features},
     889    howpublished= {\url{https://plg.uwaterloo.ca/~cforall/features}},
     890    note        = {Accessed: 2018-01-01},
    884891}
    885892
     
    36853692    contributer = {pabuhr@plg},
    36863693    author      = {James Gosling and Bill Joy and Guy Steele and Gilad Bracha and Alex Buckley},
    3687     title       = {{Java} Language Spec.},
     3694    title       = {{Java} Language Specification},
    36883695    publisher   = {Oracle},
    36893696    year        = 2015,
  • doc/papers/OOPSLA17/.gitignore

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

    rbc6f918 re2e7330  
    1 ## Define the appropriate configuration variables.
     1## Define the configuration variables.
    22
    3 TeXLIB = .:../LaTeXmacros:../LaTeXmacros/listings:../LaTeXmacros/enumitem:../bibliography/:
    4 LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error
     3Build = build
     4Figures = figures
     5Macros = ../../LaTeXmacros
     6TeXLIB = .:${Macros}:${Build}:../../bibliography:
     7LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build}
    58BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
     9
     10MAKEFLAGS = --no-print-directory --silent #
     11VPATH = ${Figures} evaluation
    612
    713## Define the text source files.
     
    3339
    3440clean :
    35         rm -f *.bbl *.aux *.dvi *.idx *.ilg *.ind *.brf *.out *.log *.toc *.blg *.pstex_t *.cf \
    36                 ${FIGURES} ${PICTURES} ${PROGRAMS} ${GRAPHS} ${basename ${DOCUMENT}}.ps ${DOCUMENT}
     41        @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build}
    3742
    3843# File Dependencies #
     
    4247
    4348${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
    44         dvips $< -o $@
     49        dvips ${Build}/$< -o $@
    4550
    46 #${DOCUMENT} : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \
    47 
    48 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ../bibliography/cfa.bib
    49         # Conditionally create an empty *.idx (index) file for inclusion until makeindex is run.
    50         if [ ! -r ${basename $@}.idx ] ; then touch ${basename $@}.idx ; fi
     51${basename ${DOCUMENT}}.dvi : Makefile ${Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ../../bibliography/pl.bib
    5152        # Must have *.aux file containing citations for bibtex
    5253        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
    53         -${BibTeX} ${basename $@}
    54         # Some citations reference others so run steps again to resolve these citations
     54        -${BibTeX} ${Build}/${basename $@}
     55        # Some citations reference others so run again to resolve these citations
    5556        ${LaTeX} ${basename $@}.tex
    56         -${BibTeX} ${basename $@}
    57         # Make index from *.aux entries and input index at end of document
    58         makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx
     57        -${BibTeX} ${Build}/${basename $@}
     58        # Run again to finish citations
    5959        ${LaTeX} ${basename $@}.tex
    60         # Run again to get index title into table of contents
    61         ${LaTeX} ${basename $@}.tex
    62 
    63 predefined :
    64         sed -f predefined.sed ${basename ${DOCUMENT}}.tex > ${basename $@}.cf
    6560
    6661## Define the default recipes.
    6762
    68 ${GRAPHS} : evaluation/timing.gp evaluation/timing.dat
    69         gnuplot evaluation/timing.gp
     63${Build}:
     64        mkdir -p ${Build}
     65
     66${GRAPHS} : timing.gp timing.dat
     67        gnuplot -e Build="'${Build}/'" evaluation/timing.gp
    7068
    7169%.tex : %.fig
    72         fig2dev -L eepic $< > $@
     70        fig2dev -L eepic $< > ${Build}/$@
    7371
    7472%.ps : %.fig
    75         fig2dev -L ps $< > $@
     73        fig2dev -L ps $< > ${Build}/$@
    7674
    7775%.pstex : %.fig
    78         fig2dev -L pstex $< > $@
    79         fig2dev -L pstex_t -p $@ $< > $@_t
     76        fig2dev -L pstex $< > ${Build}/$@
     77        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
    8078
    8179# Local Variables: #
  • doc/papers/OOPSLA17/evaluation/timing.gp

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

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

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

    rbc6f918 re2e7330  
    1 % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended
    2 
    3 % inline code �...� (copyright symbol) emacs: C-q M-)
    4 % red highlighting �...� (registered trademark symbol) emacs: C-q M-.
    5 % blue highlighting �...� (sharp s symbol) emacs: C-q M-_
    6 % green highlighting �...� (cent symbol) emacs: C-q M-"
    7 % LaTex escape �...� (section symbol) emacs: C-q M-'
    8 % keyword escape �...� (pilcrow symbol) emacs: C-q M-^
     1% inline code ©...© (copyright symbol) emacs: C-q M-)
     2% red highlighting ®...® (registered trademark symbol) emacs: C-q M-.
     3% blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_
     4% green highlighting ¢...¢ (cent symbol) emacs: C-q M-"
     5% LaTex escape §...§ (section symbol) emacs: C-q M-'
     6% keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^
    97% math escape $...$ (dollar symbol)
    108
     
    2018\usepackage{epic,eepic}
    2119\usepackage{upquote}                                            % switch curled `'" to straight
    22 \usepackage{dirtytalk}
    2320\usepackage{calc}
    2421\usepackage{xspace}
     
    4643\urlstyle{rm}
    4744
    48 \usepackage{tikz}
    49 \def\checkmark{\tikz\fill[scale=0.4](0,.35) -- (.25,0) -- (1,.7) -- (.25,.15) -- cycle;}
    50 
    5145\setlength{\topmargin}{-0.45in}                         % move running title into header
    5246\setlength{\headsep}{0.25in}
     
    7872
    7973\title{Concurrency in \CFA}
    80 \author{Thierry Delisle, Waterloo, Ontario, Canada, 2018}
     74\author{Thierry Delisle and Peter A. Buhr, Waterloo, Ontario, Canada}
    8175
    8276
     
    8579
    8680\begin{abstract}
    87 \CFA is a modern, non-object-oriented extension of the C programming language. This thesis serves as a definition and an implementation for the concurrency and parallelism \CFA offers. These features are created from scratch due to the lack of concurrency in ISO C. Lightweight threads are introduced into the language. In addition, monitors are introduced as a high-level tool for control-flow based synchronization and mutual-exclusion. The main contributions of this thesis are two-fold: it extends the existing semantics of monitors introduce by~\cite{Hoare74} to handle monitors in groups and also details the engineering effort needed to introduce these features as core language features. Indeed, these features are added with respect to expectations of C programmers, and integrate with the \CFA type-system and other language features.
     81\CFA is a modern, \emph{non-object-oriented} extension of the C programming language.
     82This 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.
    8883\end{abstract}
    8984
     
    9590\section{Introduction}
    9691% ======================================================================
    97 This thesis provides a minimal concurrency \textbf{api} that is simple, efficient and can be reused to build higher-level features. The simplest possible concurrency system is a thread and a lock but this low-level approach is hard to master. An easier approach for users is to support higher-level constructs as the basis of concurrency. Indeed, for highly productive concurrent programming, high-level approaches are much more popular~\cite{HPP:Study}. Examples are task based, message passing and implicit threading. The high-level approach and its minimal \textbf{api} are tested in a dialect of C, called \CFA. Furthermore, the proposed \textbf{api} doubles as an early definition of the \CFA language and library. This thesis also provides an implementation of the concurrency library for \CFA as well as all the required language features added to the source-to-source translator.
     92
     93This 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.
    9894
    9995There 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.
    10096
    101 In the context of this thesis, a \textbf{thread} is a fundamental unit of execution that runs a sequence of code, generally on a program stack. Having multiple simultaneous threads gives rise to concurrency and generally requires some kind of locking mechanism to ensure proper execution. Correspondingly, \textbf{concurrency} is defined as the concepts and challenges that occur when multiple independent (sharing memory, timing dependencies, etc.) concurrent threads are introduced. Accordingly, \textbf{locking} (and by extension locks) are defined as a mechanism that prevents the progress of certain threads in order to avoid problems due to concurrency. Finally, in this thesis \textbf{parallelism} is distinct from concurrency and is defined as running multiple threads simultaneously. More precisely, parallelism implies \emph{actual} simultaneous execution as opposed to concurrency which only requires \emph{apparent} simultaneous execution. As such, parallelism is only observable in the differences in performance or, more generally, differences in timing.
     97In 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.
    10298
    10399% ======================================================================
     
    113109
    114110% ======================================================================
    115 \section{References}
     111\subsection{References}
    116112
    117113Like \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:
     
    132128
    133129% ======================================================================
    134 \section{Overloading}
     130\subsection{Overloading}
    135131
    136132Another 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.
     
    153149
    154150% ======================================================================
    155 \section{Operators}
     151\subsection{Operators}
    156152Overloading 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.:
    157153\begin{cfacode}
     
    173169
    174170% ======================================================================
    175 \section{Constructors/Destructors}
     171\subsection{Constructors/Destructors}
    176172Object 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:
    177173\begin{cfacode}
     
    208204
    209205% ======================================================================
    210 \section{Parametric Polymorphism}
     206\subsection{Parametric Polymorphism}
    211207\label{s:ParametricPolymorphism}
    212208Routines 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:
     
    241237
    242238% ======================================================================
    243 \section{with Clause/Statement}
     239\subsection{with Clause/Statement}
    244240Since \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).
    245241\begin{cfacode}
     
    286282
    287283\section{\protect\CFA's Thread Building Blocks}
    288 One of the important features that are missing in C is threading\footnote{While the C11 standard defines a ``threads.h'' header, it is minimal and defined as optional. As such, library support for threading is far from widespread. At the time of writing the thesis, neither \texttt{gcc} nor \texttt{clang} support ``threads.h'' in their respective standard libraries.}. On modern architectures, a lack of threading is unacceptable~\cite{Sutter05, Sutter05b}, and therefore modern programming languages must have the proper tools to allow users to write efficient concurrent programs to take advantage of parallelism. As an extension of C, \CFA needs to express these concepts in a way that is as natural as possible to programmers familiar with imperative languages. And being a system-level language means programmers expect to choose precisely which features they need and which cost they are willing to pay.
     284One 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.
    289285
    290286\section{Coroutines: A Stepping Stone}\label{coroutine}
     
    664660\end{cfacode}
    665661
    666 In this example, threads of type \code{foo} start execution in the \code{void main(foo &)} routine, which prints \code{"Hello World!".} While this 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.
     662In 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.
    667663\begin{cfacode}
    668664typedef void (*voidFunc)(int);
     
    999995% ======================================================================
    1000996% ======================================================================
    1001 In addition to mutual exclusion, the monitors at the core of \CFA's concurrency can also be used to achieve synchronization. With monitors, this capability is generally achieved with internal or external scheduling as in~\cite{Hoare74}. With \textbf{scheduling} loosely defined as deciding which thread acquires the critical section next, \textbf{internal scheduling} means making the decision from inside the critical section (i.e., with access to the shared state), while \textbf{external scheduling} means making the decision when entering the critical section (i.e., without access to the shared state). Since internal scheduling within a single monitor is mostly a solved problem, this 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.
     997In 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.
    1002998
    1003999First, here is a simple example of internal scheduling:
     
    18001796A \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}.
    18011797
    1802 \textbf{cfacluster} have not been fully implemented in the context of this thesis. Currently \CFA only supports one \textbf{cfacluster}, the initial one.
     1798\textbf{cfacluster} have not been fully implemented in the context of this paper. Currently \CFA only supports one \textbf{cfacluster}, the initial one.
    18031799
    18041800\subsection{Future Work: Machine Setup}\label{machine}
    1805 While this was not done in the context of this thesis, another important aspect of clusters is affinity. While many common desktop and laptop PCs have homogeneous CPUs, other devices often have more heterogeneous setups. For example, a system using \textbf{numa} configurations may benefit from users being able to tie clusters and/or kernel threads to certain CPU cores. OS support for CPU affinity is now common~\cite{affinityLinux, affinityWindows, affinityFreebsd, affinityNetbsd, affinityMacosx}, which means it is both possible and desirable for \CFA to offer an abstraction mechanism for portable CPU affinity.
     1801While 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.
    18061802
    18071803\subsection{Paradigms}\label{cfaparadigms}
     
    18151811The 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.
    18161812
    1817 Note 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.
     1813Note 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.
    18181814
    18191815% ======================================================================
     
    26152611
    26162612\section{Conclusion}
    2617 This thesis has achieved a minimal concurrency \textbf{api} that is simple, efficient and usable as the basis for higher-level features. The approach presented is based on a lightweight thread-system for parallelism, which sits on top of clusters of processors. This M:N model is judged to be both more efficient and allow more flexibility for users. Furthermore, this document introduces monitors as the main concurrency tool for users. This 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.
     2613This 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.
    26182614
    26192615
     
    26252621
    26262622\subsection{Performance} \label{futur:perf}
    2627 This 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.
     2623This 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.
    26282624
    26292625\subsection{Flexible Scheduling} \label{futur:sched}
     
    27292725\section{Acknowledgements}
    27302726
    2731 I would like to thank my supervisor, Professor Peter Buhr, for his guidance through my degree as well as the editing of this document.
    2732 
    2733 I would like to thank Professors Martin Karsten and Gregor Richards, for reading my thesis and providing helpful feedback.
    2734 
    2735 Thanks to Aaron Moss, Rob Schluntz and Andrew Beach for their work on the \CFA project as well as all the discussions which have helped me concretize the ideas in this thesis.
    2736 
    2737 Finally, I acknowledge that this has been possible thanks to the financial help offered by the David R. Cheriton School of Computer Science and the corporate partnership with Huawei Ltd.
     2727Thanks 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.
     2728Partial funding was supplied by the Natural Sciences and Engineering Research Council of Canada and a corporate partnership with Huawei Ltd.
    27382729
    27392730
     
    27442735
    27452736\end{document}
     2737
     2738% Local Variables: %
     2739% tab-width: 4 %
     2740% fill-column: 120 %
     2741% compile-command: "make" %
     2742% End: %
  • doc/papers/general/.gitignore

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

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

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

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

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

    rbc6f918 re2e7330  
    1 ## Define the appropriate configuration variables.
     1## Define the configuration variables.
    22
    3 TeXLIB = .:../LaTeXmacros:../LaTeXmacros/listings:../LaTeXmacros/enumitem:../bibliography/:
    4 LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error
     3Build = build
     4Figures = figures
     5Macros = ../LaTeXmacros
     6TeXLIB = .:${Macros}:${Build}:../bibliography:
     7LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build}
    58BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
     9
     10MAKEFLAGS = --no-print-directory --silent #
     11VPATH = ${Figures}
    612
    713## Define the text source files.
     
    3137# Directives #
    3238
     39.PHONY : all clean                                      # not file names
     40
    3341all : ${DOCUMENT}
    3442
    3543clean :
    36         rm -f *.bbl *.aux *.dvi *.idx *.ilg *.ind *.brf *.out *.log *.toc *.blg *.pstex_t *.cf \
    37                 ${FIGURES} ${PICTURES} ${PROGRAMS} ${GRAPHS} ${basename ${DOCUMENT}}.ps ${DOCUMENT}
     44        @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build}
    3845
    3946# File Dependencies #
     
    4350
    4451${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
    45         dvips $< -o $@
     52        dvips ${Build}/$< -o $@
    4653
    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
     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
    4956        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    50         if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi
     57        if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi
    5158        # Must have *.aux file containing citations for bibtex
    5259        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
    53         -${BibTeX} ${basename $@}
    54         # Some citations reference others so run steps again to resolve these citations
     60        -${BibTeX} ${Build}/${basename $@}
     61        # Some citations reference others so run again to resolve these citations
    5562        ${LaTeX} ${basename $@}.tex
    56         -${BibTeX} ${basename $@}
     63        -${BibTeX} ${Build}/${basename $@}
    5764        # Make index from *.aux entries and input index at end of document
    58         makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx
     65        makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx
     66        # Run again to finish citations
    5967        ${LaTeX} ${basename $@}.tex
    6068        # Run again to get index title into table of contents
     
    6674## Define the default recipes.
    6775
     76${Build}:
     77        mkdir -p ${Build}
     78
    6879%.tex : %.fig
    69         fig2dev -L eepic $< > $@
     80        fig2dev -L eepic $< > ${Build}/$@
    7081
    7182%.ps : %.fig
    72         fig2dev -L ps $< > $@
     83        fig2dev -L ps $< > ${Build}/$@
    7384
    7485%.pstex : %.fig
    75         fig2dev -L pstex $< > $@
    76         fig2dev -L pstex_t -p $@ $< > $@_t
     86        fig2dev -L pstex $< > ${Build}/$@
     87        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
    7788
    7889# Local Variables: #
  • doc/refrat/refrat.tex

    rbc6f918 re2e7330  
    1111%% Created On       : Wed Apr  6 14:52:25 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Tue Aug 15 18:46:31 2017
    14 %% Update Count     : 106
     13%% Last Modified On : Wed Jan 31 17:30:23 2018
     14%% Update Count     : 108
    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 the companion document ``An Overview of \CFA''
    144 \cite{Ditchfield96:Overview}.
     143For a simple introduction to \CFA, see~\cite{Cforall}.
    145144
    146145\begin{rationale}
     
    596595\begin{rationale}
    597596Since each subsection describes the interpretations of an expression in terms of the interpretations of its subexpressions, this chapter can be taken as describing an overload resolution algorithm that uses one bottom-up pass over an expression tree.
    598 Such an algorithm was first described (for Ada) by Baker~\cite{Bak:overload}.
     597Such an algorithm was first described (for Ada) by Baker~\cite{Baker82}.
    599598It is extended here to handle polymorphic functions and arithmetic conversions.
    600599The 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.
     
    37753774
    37763775\bibliographystyle{plain}
    3777 \bibliography{cfa}
     3776\bibliography{pl}
    37783777
    37793778
  • doc/user/.gitignore

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

    rbc6f918 re2e7330  
    1 ## Define the appropriate configuration variables.
     1## Define the configuration variables.
    22
    3 TeXLIB = .:../LaTeXmacros:../bibliography/:
    4 LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error
     3Build = build
     4Figures = figures
     5Macros = ../LaTeXmacros
     6TeXLIB = .:${Macros}:${Build}:../bibliography:
     7LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build}
    58BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
     9
     10MAKEFLAGS = --no-print-directory --silent #
     11VPATH = ${Figures}
    612
    713## Define the text source files.
     
    3541# Directives #
    3642
     43.PHONY : all clean                                      # not file names
     44
    3745all : ${DOCUMENT}
    3846
    3947clean :
    40         rm -f *.bbl *.aux *.dvi *.idx *.ilg *.ind *.brf *.out *.log *.toc *.blg *.pstex_t *.cf \
    41                 ${FIGURES} ${PICTURES} ${PROGRAMS} ${GRAPHS} ${basename ${DOCUMENT}}.ps ${DOCUMENT}
     48        @rm -frv ${DOCUMENT} ${basename ${DOCUMENT}}.ps ${Build}
    4249
    4350# File Dependencies #
     
    4754
    4855${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
    49         dvips $< -o $@
     56        dvips ${Build}/$< -o $@
    5057
    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
     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
    5360        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    54         if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi
     61        if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi
    5562        # Must have *.aux file containing citations for bibtex
    5663        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
    57         -${BibTeX} ${basename $@}
    58         # Some citations reference others so run steps again to resolve these citations
     64        -${BibTeX} ${Build}/${basename $@}
     65        # Some citations reference others so run again to resolve these citations
    5966        ${LaTeX} ${basename $@}.tex
    60         -${BibTeX} ${basename $@}
     67        -${BibTeX} ${Build}/${basename $@}
    6168        # Make index from *.aux entries and input index at end of document
    62         makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx
     69        makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx
     70        # Run again to finish citations
    6371        ${LaTeX} ${basename $@}.tex
    6472        # Run again to get index title into table of contents
    6573        ${LaTeX} ${basename $@}.tex
    6674
    67 predefined :
    68         sed -f predefined.sed ${basename ${DOCUMENT}}.tex > ${basename $@}.cf
    69 
    7075## Define the default recipes.
    7176
     77${Build}:
     78        mkdir -p ${Build}
     79
    7280%.tex : %.fig
    73         fig2dev -L eepic $< > $@
     81        fig2dev -L eepic $< > ${Build}/$@
    7482
    7583%.ps : %.fig
    76         fig2dev -L ps $< > $@
     84        fig2dev -L ps $< > ${Build}/$@
    7785
    7886%.pstex : %.fig
    79         fig2dev -L pstex $< > $@
    80         fig2dev -L pstex_t -p $@ $< > $@_t
     87        fig2dev -L pstex $< > ${Build}/$@
     88        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
    8189
    8290# Local Variables: #
  • doc/user/user.tex

    rbc6f918 re2e7330  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Mon Nov 27 18:09:59 2017
    14 %% Update Count     : 3143
     13%% Last Modified On : Wed Jan 31 07:59:24 2018
     14%% Update Count     : 3146
    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}
    4342
    4443\usepackage[pagewise]{lineno}
     
    66616660
    66626661\bibliographystyle{plain}
    6663 \bibliography{cfa}
     6662\bibliography{pl}
    66646663
    66656664
  • src/benchmark/Makefile.am

    rbc6f918 re2e7330  
    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},'
    6165        @echo -e '\t"ctxswitch": {'
    6266        @echo -en '\t\t"coroutine":'
  • src/benchmark/Makefile.in

    rbc6f918 re2e7330  
    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},'
    475479        @echo -e '\t"ctxswitch": {'
    476480        @echo -en '\t\t"coroutine":'
  • src/driver/cfa.cc

    rbc6f918 re2e7330  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Oct 31 11:40:44 2017
    13 // Update Count     : 160
     12// Last Modified On : Tue Jan 30 15:46:15 2018
     13// Update Count     : 161
    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;
    279283
    280284        } // if
     
    353357                nargs += 1;
    354358                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
    355361                nargs += 1;
    356362                args[nargs] = ( *new string( string("-B") + Bprefix + "/" ) ).c_str();
  • src/libcfa/bits/containers.h

    rbc6f918 re2e7330  
    140140
    141141#ifdef __cforall
     142
    142143        forall(dtype T | is_node(T))
    143         static inline void ?{}( __queue(T) & this ) {
    144                 (this.head){ NULL };
    145                 (this.tail){ &this.head };
     144        static inline void ?{}( __queue(T) & this ) with( this ) {
     145                head{ NULL };
     146                tail{ &head };
    146147        }
    147148
    148149        forall(dtype T | is_node(T) | sized(T))
    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 );
     150        static inline void append( __queue(T) & this, T * val ) with( this ) {
     151                verify(tail != NULL);
     152                *tail = val;
     153                tail = &get_next( *val );
    153154        }
    154155
     
    167168
    168169        forall(dtype T | is_node(T) | sized(T))
    169         static inline T * remove( __queue(T) & this, T ** it ) {
     170        static inline T * remove( __queue(T) & this, T ** it ) with( this ) {
    170171                T * val = *it;
    171172                verify( val );
     
    173174                (*it) = get_next( *val );
    174175
    175                 if( this.tail == &get_next( *val ) ) {
    176                         this.tail = it;
     176                if( tail == &get_next( *val ) ) {
     177                        tail = it;
    177178                }
    178179
    179180                get_next( *val ) = NULL;
    180181
    181                 verify( (this.head == NULL) == (&this.head == this.tail) );
    182                 verify( *this.tail == NULL );
     182                verify( (head == NULL) == (&head == tail) );
     183                verify( *tail == NULL );
    183184                return val;
    184185        }
    185186#endif
     187
     188//-----------------------------------------------------------------------------
     189// Tools
     190//-----------------------------------------------------------------------------
     191#ifdef __cforall
     192
     193#endif
  • src/libcfa/bits/locks.h

    rbc6f918 re2e7330  
    5858
    5959#ifdef __cforall
     60        extern "C" {
     61                extern void disable_interrupts();
     62                extern void enable_interrupts_noPoll();
     63        }
     64
    6065        extern void yield( unsigned int );
    6166        extern thread_local struct thread_desc *    volatile this_thread;
     67        extern thread_local struct processor *      volatile this_processor;
    6268
    6369        static inline void ?{}( __spinlock_t & this ) {
     
    6874        static inline _Bool try_lock  ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
    6975                _Bool result = __lock_test_and_test_and_set( this.lock );
    70                 __cfaabi_dbg_debug_do(
    71                         if( result ) {
     76                if( result ) {
     77                        disable_interrupts();
     78                        __cfaabi_dbg_debug_do(
    7279                                this.prev_name = caller;
    7380                                this.prev_thrd = this_thread;
    74                         }
    75                 )
     81                        )
     82                }
    7683                return result;
    7784        }
     
    99106                        #endif
    100107                }
     108                disable_interrupts();
    101109                __cfaabi_dbg_debug_do(
    102110                        this.prev_name = caller;
     
    105113        }
    106114
    107         // Lock the spinlock, spin if already acquired
    108         static inline void lock_yield( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
    109                 for ( unsigned int i = 1;; i += 1 ) {
    110                         if ( __lock_test_and_test_and_set( this.lock ) ) break;
    111                         yield( i );
    112                 }
    113                 __cfaabi_dbg_debug_do(
    114                         this.prev_name = caller;
    115                         this.prev_thrd = this_thread;
    116                 )
    117         }
     115        // // Lock the spinlock, yield if already acquired
     116        // static inline void lock_yield( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
     117        //      for ( unsigned int i = 1;; i += 1 ) {
     118        //              if ( __lock_test_and_test_and_set( this.lock ) ) break;
     119        //              yield( i );
     120        //      }
     121        //      disable_interrupts();
     122        //      __cfaabi_dbg_debug_do(
     123        //              this.prev_name = caller;
     124        //              this.prev_thrd = this_thread;
     125        //      )
     126        // }
    118127
    119128        static inline void unlock( __spinlock_t & this ) {
     129                enable_interrupts_noPoll();
    120130                __lock_release( this.lock );
    121131        }
  • src/libcfa/concurrency/coroutine.c

    rbc6f918 re2e7330  
    118118} //ctxSwitchDirect
    119119
    120 void create_stack( coStack_t* this, unsigned int storageSize ) {
     120void create_stack( coStack_t* this, unsigned int storageSize ) with( *this ) {
    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)this->storage == 0 ) {
    127                 this->userStack = false;
    128                 this->size = libCeiling( storageSize, 16 );
     126        if ( (intptr_t)storage == 0 ) {
     127                userStack = false;
     128                size = libCeiling( storageSize, 16 );
    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( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) );
    133                 __cfaabi_dbg_no_debug_do( this->storage = malloc( cxtSize + this->size + 8 ) );
     132                __cfaabi_dbg_debug_do( storage = memalign( pageSize, cxtSize + size + pageSize ) );
     133                __cfaabi_dbg_no_debug_do( storage = malloc( cxtSize + size + 8 ) );
    134134
    135135                __cfaabi_dbg_debug_do(
    136                         if ( mprotect( this->storage, pageSize, PROT_NONE ) == -1 ) {
     136                        if ( mprotect( 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)this->storage == 0 ) {
    142                         abortf( "Attempt to allocate %d bytes of storage for coroutine or task execution-state but insufficient memory available.", this->size );
     141                if ( (intptr_t)storage == 0 ) {
     142                        abortf( "Attempt to allocate %d bytes of storage for coroutine or task execution-state but insufficient memory available.", size );
    143143                } // if
    144144
    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
     145                __cfaabi_dbg_debug_do( limit = (char *)storage + pageSize );
     146                __cfaabi_dbg_no_debug_do( limit = (char *)libCeiling( (unsigned long)storage, 16 ) ); // minimum alignment
    147147
    148148        } else {
    149                 assertf( ((size_t)this->storage & (libAlign() - 1)) != 0ul, "Stack storage %p for task/coroutine must be aligned on %d byte boundary.", this->storage, (int)libAlign() );
    150                 this->userStack = true;
    151                 this->size = storageSize - cxtSize;
     149                assertf( ((size_t)storage & (libAlign() - 1)) != 0ul, "Stack storage %p for task/coroutine must be aligned on %d byte boundary.", storage, (int)libAlign() );
     150                userStack = true;
     151                size = storageSize - cxtSize;
    152152
    153                 if ( this->size % 16 != 0u ) this->size -= 8;
     153                if ( size % 16 != 0u ) size -= 8;
    154154
    155                 this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ); // minimum alignment
     155                limit = (char *)libCeiling( (unsigned long)storage, 16 ); // minimum alignment
    156156        } // if
    157         assertf( this->size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", this->size, MinStackSize );
     157        assertf( size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", size, MinStackSize );
    158158
    159         this->base = (char *)this->limit + this->size;
    160         this->context = this->base;
    161         this->top = (char *)this->context + cxtSize;
     159        base = (char *)limit + size;
     160        context = base;
     161        top = (char *)context + cxtSize;
    162162}
    163163
  • src/libcfa/concurrency/invoke.h

    rbc6f918 re2e7330  
    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                )
    136142     };
    137143
  • src/libcfa/concurrency/kernel.c

    rbc6f918 re2e7330  
    8787}
    8888
    89 void ?{}( coStack_t & this, current_stack_info_t * info) {
    90         this.size = info->size;
    91         this.storage = info->storage;
    92         this.limit = info->limit;
    93         this.base = info->base;
    94         this.context = info->context;
    95         this.top = info->top;
    96         this.userStack = true;
    97 }
    98 
    99 void ?{}( coroutine_desc & this, current_stack_info_t * info) {
    100         (this.stack){ info };
    101         this.name = "Main Thread";
    102         this.errno_ = 0;
    103         this.state = Start;
    104         this.starter = NULL;
    105 }
    106 
    107 void ?{}( thread_desc & this, current_stack_info_t * info) {
    108         (this.self_cor){ info };
     89void ?{}( 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
     99void ?{}( 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
     107void ?{}( thread_desc & this, current_stack_info_t * info) with( this ) {
     108        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) {
    157         if( ! this.do_terminate ) {
     156void ^?{}(processor & this) with( this ){
     157        if( ! do_terminate ) {
    158158                __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this);
    159                 this.do_terminate = true;
    160                 P( this.terminated );
    161                 pthread_join( this.kernel_thread, NULL );
    162         }
    163 }
    164 
    165 void ?{}(cluster & this) {
    166         (this.ready_queue){};
    167         ( this.ready_queue_lock ){};
    168 
    169         this.preemption = default_preemption();
     159                do_terminate = true;
     160                P( terminated );
     161                pthread_join( kernel_thread, NULL );
     162        }
     163}
     164
     165void ?{}(cluster & this) with( this ) {
     166        ready_queue{};
     167        ready_queue_lock{};
     168
     169        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) {
    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] );
     242void 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] );
    256259                }
    257260        }
    258         else if( this->finish.action_code == Release_Multi_Schedule ) {
    259                 for(int i = 0; i < this->finish.lock_count; i++) {
    260                         unlock( *this->finish.locks[i] );
     261        else if( action_code == Release_Multi_Schedule ) {
     262                for(int i = 0; i < lock_count; i++) {
     263                        unlock( *locks[i] );
    261264                }
    262                 for(int i = 0; i < this->finish.thrd_count; i++) {
    263                         ScheduleThread( this->finish.thrds[i] );
     265                for(int i = 0; i < thrd_count; i++) {
     266                        ScheduleThread( thrds[i] );
    264267                }
    265268        }
    266269        else {
    267                 assert(this->finish.action_code == No_Action);
     270                assert(action_code == No_Action);
    268271        }
    269272}
     
    334337        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    335338
    336         lock(   this_processor->cltr->ready_queue_lock __cfaabi_dbg_ctx2 );
    337         append( this_processor->cltr->ready_queue, thrd );
    338         unlock( this_processor->cltr->ready_queue_lock );
    339 
    340         verify( disable_preempt_count > 0 );
    341 }
    342 
    343 thread_desc * nextThread(cluster * this) {
    344         verify( disable_preempt_count > 0 );
    345         lock( this->ready_queue_lock __cfaabi_dbg_ctx2 );
    346         thread_desc * head = pop_head( this->ready_queue );
    347         unlock( this->ready_queue_lock );
     339        with( *this_processor->cltr ) {
     340                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
     341                append( ready_queue, thrd );
     342                unlock( ready_queue_lock );
     343        }
     344
     345        verify( disable_preempt_count > 0 );
     346}
     347
     348thread_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 );
    348353        verify( disable_preempt_count > 0 );
    349354        return head;
     
    361366        disable_interrupts();
    362367        this_processor->finish.action_code = Release;
    363         this_processor->finish.lock = lock;
    364 
    365         verify( disable_preempt_count > 0 );
     368        this_processor->finish.lock        = lock;
     369
     370        verify( disable_preempt_count > 1 );
    366371        suspend();
    367372        verify( disable_preempt_count > 0 );
     
    371376
    372377void BlockInternal( thread_desc * thrd ) {
    373         assert(thrd);
    374378        disable_interrupts();
    375         assert( thrd->self_cor.state != Halted );
    376379        this_processor->finish.action_code = Schedule;
    377         this_processor->finish.thrd = thrd;
     380        this_processor->finish.thrd        = thrd;
    378381
    379382        verify( disable_preempt_count > 0 );
     
    388391        disable_interrupts();
    389392        this_processor->finish.action_code = Release_Schedule;
    390         this_processor->finish.lock = lock;
    391         this_processor->finish.thrd = thrd;
    392 
    393         verify( disable_preempt_count > 0 );
     393        this_processor->finish.lock        = lock;
     394        this_processor->finish.thrd        = thrd;
     395
     396        verify( disable_preempt_count > 1 );
    394397        suspend();
    395398        verify( disable_preempt_count > 0 );
     
    401404        disable_interrupts();
    402405        this_processor->finish.action_code = Release_Multi;
    403         this_processor->finish.locks = locks;
    404         this_processor->finish.lock_count = count;
     406        this_processor->finish.locks       = locks;
     407        this_processor->finish.lock_count  = count;
    405408
    406409        verify( disable_preempt_count > 0 );
     
    414417        disable_interrupts();
    415418        this_processor->finish.action_code = Release_Multi_Schedule;
    416         this_processor->finish.locks = locks;
    417         this_processor->finish.lock_count = lock_count;
    418         this_processor->finish.thrds = thrds;
    419         this_processor->finish.thrd_count = thrd_count;
     419        this_processor->finish.locks       = locks;
     420        this_processor->finish.lock_count  = lock_count;
     421        this_processor->finish.thrds       = thrds;
     422        this_processor->finish.thrd_count  = thrd_count;
    420423
    421424        verify( disable_preempt_count > 0 );
     
    429432        verify( disable_preempt_count > 0 );
    430433        this_processor->finish.action_code = thrd ? Release_Schedule : Release;
    431         this_processor->finish.lock = lock;
    432         this_processor->finish.thrd = thrd;
     434        this_processor->finish.lock        = lock;
     435        this_processor->finish.thrd        = thrd;
    433436
    434437        suspend();
     
    516519}
    517520
     521//=============================================================================================
     522// Unexpected Terminating logic
     523//=============================================================================================
     524
     525
    518526static __spinlock_t kernel_abort_lock;
    519527static __spinlock_t kernel_debug_lock;
     
    581589void ^?{}(semaphore & this) {}
    582590
    583 void P(semaphore & this) {
    584         lock( this.lock __cfaabi_dbg_ctx2 );
    585         this.count -= 1;
    586         if ( this.count < 0 ) {
     591void P(semaphore & this) with( this ){
     592        lock( lock __cfaabi_dbg_ctx2 );
     593        count -= 1;
     594        if ( count < 0 ) {
    587595                // queue current task
    588                 append( this.waiting, (thread_desc *)this_thread );
     596                append( waiting, (thread_desc *)this_thread );
    589597
    590598                // atomically release spin lock and block
    591                 BlockInternal( &this.lock );
     599                BlockInternal( &lock );
    592600        }
    593601        else {
    594             unlock( this.lock );
    595         }
    596 }
    597 
    598 void V(semaphore & this) {
     602            unlock( lock );
     603        }
     604}
     605
     606void V(semaphore & this) with( this ) {
    599607        thread_desc * thrd = NULL;
    600         lock( this.lock __cfaabi_dbg_ctx2 );
    601         this.count += 1;
    602         if ( this.count <= 0 ) {
     608        lock( lock __cfaabi_dbg_ctx2 );
     609        count += 1;
     610        if ( count <= 0 ) {
    603611                // remove task at head of waiting list
    604                 thrd = pop_head( this.waiting );
    605         }
    606 
    607         unlock( this.lock );
     612                thrd = pop_head( waiting );
     613        }
     614
     615        unlock( lock );
    608616
    609617        // make new owner
     
    611619}
    612620
     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)
    613654// Local Variables: //
    614655// mode: c //
  • src/libcfa/concurrency/kernel_private.h

    rbc6f918 re2e7330  
    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
    8792//-----------------------------------------------------------------------------
    8893// Utils
  • src/libcfa/concurrency/monitor.c

    rbc6f918 re2e7330  
    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 
    6155//-----------------------------------------------------------------------------
    6256// Useful defines
     
    9084        static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) {
    9185                // Lock the monitor spinlock
    92                 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
     86                lock( this->lock __cfaabi_dbg_ctx2 );
    9387                thread_desc * thrd = this_thread;
     88
     89                verify( disable_preempt_count > 0 );
    9490
    9591                __cfaabi_dbg_print_safe("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
     
    121117                        // Some one else has the monitor, wait in line for it
    122118                        append( this->entry_queue, thrd );
     119
     120                        verify( disable_preempt_count > 0 );
     121
    123122                        BlockInternal( &this->lock );
    124123
     
    138137        static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) {
    139138                // Lock the monitor spinlock
    140                 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
     139                lock( this->lock __cfaabi_dbg_ctx2 );
    141140                thread_desc * thrd = this_thread;
    142141
     
    201200        // Leave single monitor
    202201        void __leave_monitor_desc( monitor_desc * this ) {
    203                 // Lock the monitor spinlock, DO_LOCK to reduce contention
    204                 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
     202                // Lock the monitor spinlock
     203                lock( this->lock __cfaabi_dbg_ctx2 );
    205204
    206205                __cfaabi_dbg_print_safe("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner);
     
    248247
    249248                // Lock the monitor now
    250                 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
     249                lock( this->lock __cfaabi_dbg_ctx2 );
    251250
    252251                disable_interrupts();
     
    397396        append( this.blocked, &waiter );
    398397
     398        verify( disable_preempt_count == 0 );
     399
    399400        // Lock all monitors (aggregates the locks as well)
    400401        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"); }
    401405
    402406        // Find the next thread(s) to run
     
    473477        monitor_ctx( this.monitors, this.monitor_count );
    474478
     479        verify( disable_preempt_count == 0 );
     480
    475481        // Lock all monitors (aggregates the locks them as well)
    476482        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
    477487
    478488        // Create the node specific to this wait operation
     
    737747static inline void lock_all( __spinlock_t * locks [], __lock_size_t count ) {
    738748        for( __lock_size_t i = 0; i < count; i++ ) {
    739                 DO_LOCK( *locks[i] __cfaabi_dbg_ctx2 );
     749                lock( *locks[i] __cfaabi_dbg_ctx2 );
    740750        }
    741751}
     
    744754        for( __lock_size_t i = 0; i < count; i++ ) {
    745755                __spinlock_t * l = &source[i]->lock;
    746                 DO_LOCK( *l __cfaabi_dbg_ctx2 );
     756                lock( *l __cfaabi_dbg_ctx2 );
    747757                if(locks) locks[i] = l;
    748758        }
  • src/libcfa/concurrency/preemption.c

    rbc6f918 re2e7330  
    1919extern "C" {
    2020#include <errno.h>
    21 #include <execinfo.h>
    22 #define __USE_GNU
    23 #include <signal.h>
    24 #undef __USE_GNU
    2521#include <stdio.h>
    2622#include <string.h>
     
    2925#undef ftype
    3026
    31 #ifdef __USE_STREAM__
    32 #include "fstream"
    33 #endif
     27#include "bits/signal.h"
    3428
    3529//TODO move to defaults
     
    4034        return __CFA_DEFAULT_PREEMPTION__;
    4135}
    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
    4636
    4737// FwdDeclarations : timeout handlers
     
    5343void sigHandler_segv     ( __CFA_SIGPARMS__ );
    5444void sigHandler_abort    ( __CFA_SIGPARMS__ );
    55 
    56 // FwdDeclarations : sigaction wrapper
    57 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
    5845
    5946// FwdDeclarations : alarm thread main
     
    7360static pthread_t alarm_thread;                        // pthread handle to alarm thread
    7461
    75 void ?{}(event_kernel_t & this) {
    76         (this.alarms){};
    77         (this.lock){};
     62void ?{}(event_kernel_t & this) with( this ) {
     63        alarms{};
     64        lock{};
    7865}
    7966
     
    162149        // If counter reaches 0, execute any pending CtxSwitch
    163150        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    164                 processor * proc  = this_processor;      // Cache the processor now since interrupts can start happening after the atomic add
     151                processor   * proc = this_processor;      // Cache the processor now since interrupts can start happening after the atomic add
    165152                thread_desc * thrd = this_thread;         // Cache the thread now since interrupts can start happening after the atomic add
    166153
     
    182169        void enable_interrupts_noPoll() {
    183170                __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    184                 verify( prev != 0u );                     // If this triggers someone is enabled already enabled interrupts
     171                verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
    185172        }
    186173}
     
    246233        // Setup proper signal handlers
    247234        __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
    250235
    251236        signal_block( SIGALRM );
     
    308293        if( !preemption_ready() ) { return; }
    309294
    310         // __cfaabi_dbg_print_buffer_decl(" KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
     295        __cfaabi_dbg_print_buffer_decl(" KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
    311296
    312297        preemption_in_progress = true;                      // Sync flag : prevent recursive calls to the signal handler
     
    380365}
    381366
    382 // Sigaction wrapper : register an signal handler
    383 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) {
    384         struct sigaction act;
    385 
    386         act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;
    387         act.sa_flags = flags;
    388 
    389         if ( sigaction( sig, &act, NULL ) == -1 ) {
    390                 __cfaabi_dbg_print_buffer_decl(
    391                         " __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",
    392                         sig, handler, flags, errno, strerror( errno )
    393                 );
    394                 _exit( EXIT_FAILURE );
    395         }
    396 }
    397 
    398 // Sigaction wrapper : restore default handler
    399 static void __kernel_sigdefault( int sig ) {
    400         struct sigaction act;
    401 
    402         act.sa_handler = SIG_DFL;
    403         act.sa_flags = 0;
    404         sigemptyset( &act.sa_mask );
    405 
    406         if ( sigaction( sig, &act, NULL ) == -1 ) {
    407                 __cfaabi_dbg_print_buffer_decl(
    408                         " __kernel_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n",
    409                         sig, errno, strerror( errno )
    410                 );
    411                 _exit( EXIT_FAILURE );
    412         }
    413 }
    414 
    415 //=============================================================================================
    416 // Terminating Signals 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 
    511367// Local Variables: //
    512368// mode: c //
  • src/libcfa/concurrency/thread.c

    rbc6f918 re2e7330  
    3131// Thread ctors and dtors
    3232
    33 void ?{}(thread_desc& this) {
    34         (this.self_cor){};
    35         this.self_cor.name = "Anonymous Coroutine";
    36         this.self_mon.owner = &this;
    37         this.self_mon.recursion = 1;
    38         this.self_mon_p = &this.self_mon;
    39         this.next = NULL;
     33void ?{}(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        )
    4045
    41         (this.monitors){ &this.self_mon_p, 1, (fptr_t)0 };
     46        monitors{ &self_mon_p, 1, (fptr_t)0 };
    4247}
    4348
    44 void ^?{}(thread_desc& this) {
    45         ^(this.self_cor){};
     49void ^?{}(thread_desc& this) with( this ) {
     50        ^self_cor{};
    4651}
    4752
    4853forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } )
    49 void ?{}( scoped(T)& this ) {
    50         (this.handle){};
    51         __thrd_start(this.handle);
     54void ?{}( scoped(T)& this ) with( this ) {
     55        handle{};
     56        __thrd_start(handle);
    5257}
    5358
    5459forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T&, P); } )
    55 void ?{}( scoped(T)& this, P params ) {
    56         (this.handle){ params };
    57         __thrd_start(this.handle);
     60void ?{}( scoped(T)& this, P params ) with( this ) {
     61        handle{ params };
     62        __thrd_start(handle);
    5863}
    5964
    6065forall( dtype T | sized(T) | is_thread(T) )
    61 void ^?{}( scoped(T)& this ) {
    62         ^(this.handle){};
     66void ^?{}( scoped(T)& this ) with( this ) {
     67        ^handle{};
    6368}
    6469
     
    6873void __thrd_start( T& this ) {
    6974        coroutine_desc* thrd_c = get_coroutine(this);
    70         thread_desc* thrd_h = get_thread   (this);
     75        thread_desc   * thrd_h = get_thread   (this);
    7176        thrd_c->last = this_coroutine;
    7277
  • src/libcfa/interpose.c

    rbc6f918 re2e7330  
    2222#include <dlfcn.h>
    2323#include <unistd.h>
     24#define __USE_GNU
     25#include <signal.h>
     26#undef __USE_GNU
     27#include <execinfo.h>
    2428}
    2529
    2630#include "bits/debug.h"
    2731#include "bits/defs.h"
     32#include "bits/signal.h"
    2833#include "startup.h"
    2934
    30 void interpose_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
     35void __cfaabi_interpose_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
    3136
    3237typedef void (*generic_fptr_t)(void);
     
    8489#define INIT_REALRTN( x, ver ) assign_ptr( (void**)&libc_##x, #x, ver)
    8590
    86 void interpose_startup() {
     91void sigHandler_segv ( __CFA_SIGPARMS__ );
     92void sigHandler_abort( __CFA_SIGPARMS__ );
     93
     94void __cfaabi_interpose_startup() {
    8795        const char *version = NULL;
    8896
    8997        INIT_REALRTN( abort, version );
    9098        INIT_REALRTN( exit, version );
    91 }
     99
     100        __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO );      // Failure handler
     101        __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO );      // Failure handler
     102        __kernel_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO );      // Failure handler
     103}
     104
     105//=============================================================================================
     106// Terminating Signals logic
     107//=============================================================================================
    92108
    93109extern "C" {
     
    137153                libc_abort();
    138154        }
     155}
     156
     157// skip first 6 stack frames by default
     158static 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
     210void 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
     215void sigHandler_abort( __CFA_SIGPARMS__ ) {
     216        __kernel_backtrace();
     217
     218        // reset default signal handler
     219        __kernel_sigdefault( SIGABRT );
     220
     221        raise( SIGABRT );
    139222}
    140223
  • src/libcfa/interpose.h

    rbc6f918 re2e7330  
    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

    rbc6f918 re2e7330  
    3939// ------------------------------------------------------------
    4040
    41 _Bool                   ?++( _Bool & ),                         ?++( volatile _Bool & );
    42 _Bool                   ?--( _Bool & ),                         ?--( volatile _Bool & );
    4341signed short            ?++( signed short & ),                  ?++( volatile signed short & );
    4442signed short            ?--( signed short & ),                  ?--( volatile signed short & );
     
    9492// ------------------------------------------------------------
    9593
    96 _Bool                   ++?( _Bool & ),                         --?( _Bool & );
    9794signed short    ++?( signed short & ),                  --?( signed short & );
    9895signed int              ++?( signed int & ),                    --?( signed int & );
     
    125122forall( ftype FT ) FT &          *?( FT * );
    126123
    127 _Bool                   +?( _Bool ),                    -?( _Bool ),                    ~?( _Bool );
     124_Bool                   +?( _Bool ),                    -?( _Bool );
    128125signed int              +?( signed int ),               -?( signed int ),               ~?( signed int );
    129126unsigned int            +?( unsigned int ),             -?( unsigned int ),             ~?( unsigned int );
     
    157154// ------------------------------------------------------------
    158155
    159 _Bool                   ?*?( _Bool, _Bool ),                                    ?/?( _Bool, _Bool ),                            ?%?( _Bool, _Bool );
    160156signed int              ?*?( signed int, signed int ),                          ?/?( signed int, signed int ),                  ?%?( signed int, signed int );
    161157unsigned int            ?*?( unsigned int, unsigned int ),                      ?/?( unsigned int, unsigned int ),              ?%?( unsigned int, unsigned int );
     
    215211// ------------------------------------------------------------
    216212
    217 _Bool                   ?<<?( _Bool, _Bool ),                                   ?>>?( _Bool, _Bool );
    218213signed int              ?<<?( signed int, signed int ),                         ?>>?( signed int, signed int );
    219214unsigned int            ?<<?( unsigned int, unsigned int ),                     ?>>?( unsigned int, unsigned int );
     
    467462
    468463
    469 _Bool                   ?*=?( _Bool &, _Bool ),                                 ?*=?( volatile _Bool &, _Bool );
    470464char                    ?*=?( char &, char ),                                   ?*=?( volatile char &, char );
    471465char signed             ?*=?( char signed &, char signed ),                     ?*=?( volatile char signed &, char signed );
     
    534528unsigned long long int  ?-=?( unsigned long long int &, unsigned long long int ), ?-=?( volatile unsigned long long int &, unsigned long long int );
    535529
    536 _Bool                   ?<<=?( _Bool &, _Bool ),                                ?<<=?( volatile _Bool &, _Bool );
    537530char                    ?<<=?( char &, char ),                                  ?<<=?( volatile char &, char );
    538531char signed             ?<<=?( char signed &, char signed ),                    ?<<=?( volatile char signed &, char signed );
     
    547540unsigned long long int  ?<<=?( unsigned long long int &, unsigned long long int ), ?<<=?( volatile unsigned long long int &, unsigned long long int );
    548541
    549 _Bool                   ?>>=?( _Bool &, _Bool ),                                ?>>=?( volatile _Bool &, _Bool );
    550542char                    ?>>=?( char &, char ),                                  ?>>=?( volatile char &, char );
    551543char signed             ?>>=?( char signed &, char signed ),                    ?>>=?( volatile char signed &, char signed );
  • src/tests/Makefile.am

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

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

    rbc6f918 re2e7330  
    99// Created On       : Wed Dec  6 12:15:52 2017
    1010// Last Modified By : Peter A. Buhr
    11 // Last Modified On : Mon Jan 29 08:41:37 2018
    12 // Update Count     : 155
     11// Last Modified On : Tue Jan 30 15:58:58 2018
     12// Update Count     : 162
    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 ?
    103                 if ( argv[1][0] == '-' && argv[1][1] == 't' ) { // timing ?
     102                if ( strcmp( argv[1], "-t" ) == 0 ) {                   // timing ?
    104103                        &unsortedfile = (ifstream *)0;                          // no input
    105104                        choose ( argc ) {
  • src/tests/functions.c

    rbc6f918 re2e7330  
    1010// Created On       : Wed Aug 17 08:39:58 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Nov 27 18:08:54 2017
    13 // Update Count     : 11
     12// Last Modified On : Wed Jan 17 22:44:12 2018
     13// Update Count     : 12
    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

    rbc6f918 re2e7330  
    1010// Created On       : Wed Aug 17 08:36:34 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 17 08:37:06 2016
    13 // Update Count     : 1
     12// Last Modified On : Wed Jan 17 22:39:13 2018
     13// Update Count     : 2
    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

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

    rbc6f918 re2e7330  
    1919preempt=1_000ul
    2020
    21 REPEAT = ${abs_top_srcdir}/tools/repeat -s
     21REPEAT = ${abs_top_srcdir}/tools/repeat
     22TIME = /usr/bin/time -f "%E"
    2223
    2324BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -debug -O2 -DPREEMPTION_RATE=${preempt}
     
    3738        ${AM_V_GEN}${CC} ${CFLAGS} ${<} -o ${@}
    3839
    39 %.run : %
    40         @ time ${REPEAT} $(repeats) timeout ${max_time} ./${<}
     40%.run : % ${REPEAT}
     41        @ time ${REPEAT} -r out.log -i -s $(repeats) timeout ${max_time} ./${<}
    4142        @ rm ${<}
    4243        @ echo -e "${<}: SUCCESS\n"
     44
     45%.time : % ${REPEAT}
     46        @ ${REPEAT} -i -s -- $(repeats) $(TIME) -a -o times.log ./${<}
     47        @ rm ${<}
     48        @ echo -e "${<}: SUCCESS\n"
     49
     50${REPEAT}:
     51        @+make -C ${abs_top_srcdir}/tools/
  • src/tests/preempt_longrun/Makefile.in

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

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

    rbc6f918 re2e7330  
    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

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

    rbc6f918 re2e7330  
    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

    rbc6f918 re2e7330  
    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

    rbc6f918 re2e7330  
    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

    rbc6f918 re2e7330  
    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

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

    rbc6f918 re2e7330  
    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.